LCOV - code coverage report
Current view: top level - gcc - gimplify.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.5 % 10733 10144
Test Date: 2026-06-20 15:32:29 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      5770808 : next_cond_uid ()
      94              : {
      95      5770808 :   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      2880744 : reset_cond_uid ()
     104              : {
     105      2880744 :   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      1205202 : tree_associate_condition_with_expr (tree stmt, unsigned uid)
     115              : {
     116      1205202 :   if (!condition_coverage_flag)
     117              :     return;
     118              : 
     119          527 :   if (!cond_uids)
     120           65 :     cond_uids = new hash_map <tree, unsigned> ();
     121              : 
     122          527 :   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              :   GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
     189              :                            | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
     190              :                            | GOVD_LOCAL)
     191              : };
     192              : 
     193              : 
     194              : enum omp_region_type
     195              : {
     196              :   ORT_WORKSHARE = 0x00,
     197              :   ORT_TASKGROUP = 0x01,
     198              :   ORT_DISPATCH  = 0x02,
     199              :   ORT_SIMD      = 0x04,
     200              : 
     201              :   ORT_PARALLEL  = 0x08,
     202              :   ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
     203              : 
     204              :   ORT_TASK      = 0x10,
     205              :   ORT_UNTIED_TASK = ORT_TASK | 1,
     206              :   ORT_TASKLOOP  = ORT_TASK | 2,
     207              :   ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
     208              : 
     209              :   ORT_TEAMS     = 0x20,
     210              :   ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
     211              :   ORT_HOST_TEAMS = ORT_TEAMS | 2,
     212              :   ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
     213              : 
     214              :   /* Data region.  */
     215              :   ORT_TARGET_DATA = 0x40,
     216              : 
     217              :   /* Data region with offloading.  */
     218              :   ORT_TARGET    = 0x80,
     219              :   ORT_COMBINED_TARGET = ORT_TARGET | 1,
     220              :   ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
     221              : 
     222              :   /* OpenACC variants.  */
     223              :   ORT_ACC       = 0x100,  /* A generic OpenACC region.  */
     224              :   ORT_ACC_DATA  = ORT_ACC | ORT_TARGET_DATA, /* Data construct.  */
     225              :   ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET,  /* Parallel construct */
     226              :   ORT_ACC_KERNELS  = ORT_ACC | ORT_TARGET | 2,  /* Kernels construct.  */
     227              :   ORT_ACC_SERIAL   = ORT_ACC | ORT_TARGET | 4,  /* Serial construct.  */
     228              :   ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2,  /* Host data.  */
     229              : 
     230              :   /* Dummy OpenMP region, used to disable expansion of
     231              :      DECL_VALUE_EXPRs in taskloop pre body.  */
     232              :   ORT_NONE      = 0x200
     233              : };
     234              : 
     235              : /* Gimplify hashtable helper.  */
     236              : 
     237              : struct gimplify_hasher : free_ptr_hash <elt_t>
     238              : {
     239              :   static inline hashval_t hash (const elt_t *);
     240              :   static inline bool equal (const elt_t *, const elt_t *);
     241              : };
     242              : 
     243              : struct gimplify_ctx
     244              : {
     245              :   struct gimplify_ctx *prev_context;
     246              : 
     247              :   vec<gbind *> bind_expr_stack;
     248              :   tree temps;
     249              :   gimple_seq conditional_cleanups;
     250              :   tree exit_label;
     251              :   tree return_temp;
     252              : 
     253              :   vec<tree> case_labels;
     254              :   hash_set<tree> *live_switch_vars;
     255              :   /* The formal temporary table.  Should this be persistent?  */
     256              :   hash_table<gimplify_hasher> *temp_htab;
     257              : 
     258              :   int conditions;
     259              :   unsigned into_ssa : 1;
     260              :   unsigned allow_rhs_cond_expr : 1;
     261              :   unsigned in_cleanup_point_expr : 1;
     262              :   unsigned keep_stack : 1;
     263              :   unsigned save_stack : 1;
     264              :   unsigned in_switch_expr : 1;
     265              :   unsigned in_handler_expr : 1;
     266              : };
     267              : 
     268              : enum gimplify_defaultmap_kind
     269              : {
     270              :   GDMK_SCALAR,
     271              :   GDMK_SCALAR_TARGET, /* w/ Fortran's target attr, implicit mapping, only.  */
     272              :   GDMK_AGGREGATE,
     273              :   GDMK_ALLOCATABLE,
     274              :   GDMK_POINTER
     275              : };
     276              : 
     277              : struct gimplify_omp_ctx
     278              : {
     279              :   struct gimplify_omp_ctx *outer_context;
     280              :   splay_tree variables;
     281              :   hash_map<omp_name_type<tree>, tree> *implicit_mappers;
     282              :   hash_set<tree> *privatized_types;
     283              :   tree clauses;
     284              :   /* Iteration variables in an OMP_FOR.  */
     285              :   vec<tree> loop_iter_var;
     286              :   location_t location;
     287              :   enum omp_clause_default_kind default_kind;
     288              :   enum omp_region_type region_type;
     289              :   enum tree_code code;
     290              :   bool combined_loop;
     291              :   bool distribute;
     292              :   bool target_firstprivatize_array_bases;
     293              :   bool add_safelen1;
     294              :   bool order_concurrent;
     295              :   bool has_depend;
     296              :   bool in_for_exprs;
     297              :   bool in_call_args;
     298              :   int defaultmap[5];
     299              : };
     300              : 
     301              : static struct gimplify_ctx *gimplify_ctxp;
     302              : static struct gimplify_omp_ctx *gimplify_omp_ctxp;
     303              : static bool in_omp_construct;
     304              : 
     305              : /* Forward declaration.  */
     306              : static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
     307              : static hash_map<tree, tree> *oacc_declare_returns;
     308              : static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
     309              :                                            bool (*) (tree), fallback_t, bool);
     310              : static void prepare_gimple_addressable (tree *, gimple_seq *);
     311              : 
     312              : /* Shorter alias name for the above function for use in gimplify.cc
     313              :    only.  */
     314              : 
     315              : static inline void
     316     92150048 : gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
     317              : {
     318     92150048 :   gimple_seq_add_stmt_without_update (seq_p, gs);
     319      6617887 : }
     320              : 
     321              : /* Append sequence SRC to the end of sequence *DST_P.  If *DST_P is
     322              :    NULL, a new sequence is allocated.   This function is
     323              :    similar to gimple_seq_add_seq, but does not scan the operands.
     324              :    During gimplification, we need to manipulate statement sequences
     325              :    before the def/use vectors have been constructed.  */
     326              : 
     327              : static void
     328      9151082 : gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
     329              : {
     330      9151082 :   gimple_stmt_iterator si;
     331              : 
     332      9151082 :   if (src == NULL)
     333      4023500 :     return;
     334              : 
     335      5127582 :   si = gsi_last (*dst_p);
     336      5127582 :   gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
     337              : }
     338              : 
     339              : 
     340              : /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
     341              :    and popping gimplify contexts.  */
     342              : 
     343              : static struct gimplify_ctx *ctx_pool = NULL;
     344              : 
     345              : /* Return a gimplify context struct from the pool.  */
     346              : 
     347              : static inline struct gimplify_ctx *
     348      8843408 : ctx_alloc (void)
     349              : {
     350      8843408 :   struct gimplify_ctx * c = ctx_pool;
     351              : 
     352      8843408 :   if (c)
     353      8572269 :     ctx_pool = c->prev_context;
     354              :   else
     355       271139 :     c = XNEW (struct gimplify_ctx);
     356              : 
     357      8843408 :   memset (c, '\0', sizeof (*c));
     358      8843408 :   return c;
     359              : }
     360              : 
     361              : /* Put gimplify context C back into the pool.  */
     362              : 
     363              : static inline void
     364      8843404 : ctx_free (struct gimplify_ctx *c)
     365              : {
     366      8843404 :   c->prev_context = ctx_pool;
     367      8843404 :   ctx_pool = c;
     368              : }
     369              : 
     370              : /* Free allocated ctx stack memory.  */
     371              : 
     372              : void
     373       238613 : free_gimplify_stack (void)
     374              : {
     375       238613 :   struct gimplify_ctx *c;
     376              : 
     377       477488 :   while ((c = ctx_pool))
     378              :     {
     379       238875 :       ctx_pool = c->prev_context;
     380       238875 :       free (c);
     381              :     }
     382       238613 : }
     383              : 
     384              : 
     385              : /* Set up a context for the gimplifier.  */
     386              : 
     387              : void
     388      8843408 : push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
     389              : {
     390      8843408 :   struct gimplify_ctx *c = ctx_alloc ();
     391              : 
     392      8843408 :   c->prev_context = gimplify_ctxp;
     393      8843408 :   gimplify_ctxp = c;
     394      8843408 :   gimplify_ctxp->into_ssa = in_ssa;
     395      8843408 :   gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
     396      8843408 : }
     397              : 
     398              : /* Tear down a context for the gimplifier.  If BODY is non-null, then
     399              :    put the temporaries into the outer BIND_EXPR.  Otherwise, put them
     400              :    in the local_decls.
     401              : 
     402              :    BODY is not a sequence, but the first tuple in a sequence.  */
     403              : 
     404              : void
     405      8843404 : pop_gimplify_context (gimple *body)
     406              : {
     407      8843404 :   struct gimplify_ctx *c = gimplify_ctxp;
     408              : 
     409      8843404 :   gcc_assert (c
     410              :               && (!c->bind_expr_stack.exists ()
     411              :                   || c->bind_expr_stack.is_empty ()));
     412      8843404 :   c->bind_expr_stack.release ();
     413      8843404 :   gimplify_ctxp = c->prev_context;
     414              : 
     415      8843404 :   if (body)
     416      3005240 :     declare_vars (c->temps, body, false);
     417              :   else
     418      5838164 :     record_vars (c->temps);
     419              : 
     420      8843404 :   delete c->temp_htab;
     421      8843404 :   c->temp_htab = NULL;
     422      8843404 :   ctx_free (c);
     423      8843404 : }
     424              : 
     425              : /* Push a GIMPLE_BIND tuple onto the stack of bindings.  */
     426              : 
     427              : static void
     428      5930032 : gimple_push_bind_expr (gbind *bind_stmt)
     429              : {
     430      5930032 :   gimplify_ctxp->bind_expr_stack.reserve (8);
     431      5930032 :   gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
     432      5930032 : }
     433              : 
     434              : /* Pop the first element off the stack of bindings.  */
     435              : 
     436              : static void
     437      5930032 : gimple_pop_bind_expr (void)
     438              : {
     439            0 :   gimplify_ctxp->bind_expr_stack.pop ();
     440         2207 : }
     441              : 
     442              : /* Return the first element of the stack of bindings.  */
     443              : 
     444              : gbind *
     445            0 : gimple_current_bind_expr (void)
     446              : {
     447            0 :   return gimplify_ctxp->bind_expr_stack.last ();
     448              : }
     449              : 
     450              : /* Return the stack of bindings created during gimplification.  */
     451              : 
     452              : vec<gbind *>
     453          359 : gimple_bind_expr_stack (void)
     454              : {
     455          359 :   return gimplify_ctxp->bind_expr_stack;
     456              : }
     457              : 
     458              : /* Return true iff there is a COND_EXPR between us and the innermost
     459              :    CLEANUP_POINT_EXPR.  This info is used by gimple_push_cleanup.  */
     460              : 
     461              : static bool
     462      2786448 : gimple_conditional_context (void)
     463              : {
     464      2786448 :   return gimplify_ctxp->conditions > 0;
     465              : }
     466              : 
     467              : /* Note that we've entered a COND_EXPR.  */
     468              : 
     469              : static void
     470      5771243 : gimple_push_condition (void)
     471              : {
     472              : #ifdef ENABLE_GIMPLE_CHECKING
     473      5771243 :   if (gimplify_ctxp->conditions == 0)
     474      3801866 :     gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
     475              : #endif
     476      5771243 :   ++(gimplify_ctxp->conditions);
     477      5771243 : }
     478              : 
     479              : /* Note that we've left a COND_EXPR.  If we're back at unconditional scope
     480              :    now, add any conditional cleanups we've seen to the prequeue.  */
     481              : 
     482              : static void
     483      5771243 : gimple_pop_condition (gimple_seq *pre_p)
     484              : {
     485      5771243 :   int conds = --(gimplify_ctxp->conditions);
     486              : 
     487      5771243 :   gcc_assert (conds >= 0);
     488      5771243 :   if (conds == 0)
     489              :     {
     490      3801866 :       gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
     491      3801866 :       gimplify_ctxp->conditional_cleanups = NULL;
     492              :     }
     493      5771243 : }
     494              : 
     495              : /* A stable comparison routine for use with splay trees and DECLs.  */
     496              : 
     497              : static int
     498     18331412 : splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
     499              : {
     500     18331412 :   tree a = (tree) xa;
     501     18331412 :   tree b = (tree) xb;
     502              : 
     503     18331412 :   return DECL_UID (a) - DECL_UID (b);
     504              : }
     505              : 
     506              : /* Create a new omp construct that deals with variable remapping.  */
     507              : 
     508              : static struct gimplify_omp_ctx *
     509       140298 : new_omp_context (enum omp_region_type region_type)
     510              : {
     511       140298 :   struct gimplify_omp_ctx *c;
     512              : 
     513       140298 :   c = XCNEW (struct gimplify_omp_ctx);
     514       140298 :   c->outer_context = gimplify_omp_ctxp;
     515       140298 :   c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
     516       140298 :   c->implicit_mappers = new hash_map<omp_name_type<tree>, tree>;
     517       140298 :   c->privatized_types = new hash_set<tree>;
     518       140298 :   c->location = input_location;
     519       140298 :   c->region_type = region_type;
     520       140298 :   if ((region_type & ORT_TASK) == 0)
     521       134250 :     c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
     522              :   else
     523         6048 :     c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
     524       140298 :   c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
     525       140298 :   c->defaultmap[GDMK_SCALAR_TARGET] = GOVD_MAP;
     526       140298 :   c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
     527       140298 :   c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
     528       140298 :   c->defaultmap[GDMK_POINTER] = GOVD_MAP;
     529              : 
     530       140298 :   return c;
     531              : }
     532              : 
     533              : /* Destroy an omp construct that deals with variable remapping.  */
     534              : 
     535              : static void
     536       139739 : delete_omp_context (struct gimplify_omp_ctx *c)
     537              : {
     538       139739 :   splay_tree_delete (c->variables);
     539       279478 :   delete c->privatized_types;
     540       279478 :   delete c->implicit_mappers;
     541       139739 :   c->loop_iter_var.release ();
     542       139739 :   XDELETE (c);
     543       139739 : }
     544              : 
     545              : static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
     546              : static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
     547              : 
     548              : /* Both gimplify the statement T and append it to *SEQ_P.  This function
     549              :    behaves exactly as gimplify_stmt, but you don't have to pass T as a
     550              :    reference.  */
     551              : 
     552              : void
     553     37899253 : gimplify_and_add (tree t, gimple_seq *seq_p)
     554              : {
     555     37899253 :   gimplify_stmt (&t, seq_p);
     556     37899253 : }
     557              : 
     558              : /* Gimplify statement T into sequence *SEQ_P, and return the first
     559              :    tuple in the sequence of generated tuples for this statement.
     560              :    Return NULL if gimplifying T produced no tuples.  */
     561              : 
     562              : static gimple *
     563       105352 : gimplify_and_return_first (tree t, gimple_seq *seq_p)
     564              : {
     565       105352 :   gimple_stmt_iterator last = gsi_last (*seq_p);
     566              : 
     567       105352 :   gimplify_and_add (t, seq_p);
     568              : 
     569       105352 :   if (!gsi_end_p (last))
     570              :     {
     571         4881 :       gsi_next (&last);
     572         4881 :       return gsi_stmt (last);
     573              :     }
     574              :   else
     575       100471 :     return gimple_seq_first_stmt (*seq_p);
     576              : }
     577              : 
     578              : /* Returns true iff T is a valid RHS for an assignment to an un-renamed
     579              :    LHS, or for a call argument.  */
     580              : 
     581              : static bool
     582       237406 : is_gimple_mem_rhs (tree t)
     583              : {
     584              :   /* If we're dealing with a renamable type, either source or dest must be
     585              :      a renamed variable.  */
     586       237406 :   if (is_gimple_reg_type (TREE_TYPE (t)))
     587       234041 :     return is_gimple_val (t);
     588              :   else
     589         3365 :     return is_gimple_val (t) || is_gimple_lvalue (t);
     590              : }
     591              : 
     592              : /* Return true if T is a CALL_EXPR or an expression that can be
     593              :    assigned to a temporary.  Note that this predicate should only be
     594              :    used during gimplification.  See the rationale for this in
     595              :    gimplify_modify_expr.  */
     596              : 
     597              : static bool
     598     97371074 : is_gimple_reg_rhs_or_call (tree t)
     599              : {
     600     71517597 :   return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
     601     97371074 :           || TREE_CODE (t) == CALL_EXPR);
     602              : }
     603              : 
     604              : /* Return true if T is a valid memory RHS or a CALL_EXPR.  Note that
     605              :    this predicate should only be used during gimplification.  See the
     606              :    rationale for this in gimplify_modify_expr.  */
     607              : 
     608              : static bool
     609     14236971 : is_gimple_mem_rhs_or_call (tree t)
     610              : {
     611              :   /* If we're dealing with a renamable type, either source or dest must be
     612              :      a renamed variable.  */
     613     14236971 :   if (is_gimple_reg_type (TREE_TYPE (t)))
     614     10904355 :     return is_gimple_val (t);
     615              :   else
     616      3332616 :     return (is_gimple_val (t)
     617      1669884 :             || is_gimple_lvalue (t)
     618      1154040 :             || (TREE_CODE (t) == CONSTRUCTOR && CONSTRUCTOR_NELTS (t) == 0)
     619      4486266 :             || TREE_CODE (t) == CALL_EXPR);
     620              : }
     621              : 
     622              : /* Create a temporary with a name derived from VAL.  Subroutine of
     623              :    lookup_tmp_var; nobody else should call this function.  */
     624              : 
     625              : static inline tree
     626      2145871 : create_tmp_from_val (tree val)
     627              : {
     628              :   /* Drop all qualifiers and address-space information from the value type.  */
     629      2145871 :   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
     630      2145871 :   tree var = create_tmp_var (type, get_name (val));
     631      2145871 :   return var;
     632              : }
     633              : 
     634              : /* Create a temporary to hold the value of VAL.  If IS_FORMAL, try to reuse
     635              :    an existing expression temporary.  If NOT_GIMPLE_REG, mark it as such.  */
     636              : 
     637              : static tree
     638      2381586 : lookup_tmp_var (tree val, bool is_formal, bool not_gimple_reg)
     639              : {
     640      2381586 :   tree ret;
     641              : 
     642              :   /* We cannot mark a formal temporary with DECL_NOT_GIMPLE_REG_P.  */
     643      2381586 :   gcc_assert (!is_formal || !not_gimple_reg);
     644              : 
     645              :   /* If not optimizing, never really reuse a temporary.  local-alloc
     646              :      won't allocate any variable that is used in more than one basic
     647              :      block, which means it will go into memory, causing much extra
     648              :      work in reload and final and poorer code generation, outweighing
     649              :      the extra memory allocation here.  */
     650      2381586 :   if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
     651              :     {
     652      1089184 :       ret = create_tmp_from_val (val);
     653      1089184 :       DECL_NOT_GIMPLE_REG_P (ret) = not_gimple_reg;
     654              :     }
     655              :   else
     656              :     {
     657      1292402 :       elt_t elt, *elt_p;
     658      1292402 :       elt_t **slot;
     659              : 
     660      1292402 :       elt.val = val;
     661      1292402 :       if (!gimplify_ctxp->temp_htab)
     662       395610 :         gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
     663      1292402 :       slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
     664      1292402 :       if (*slot == NULL)
     665              :         {
     666      1056687 :           elt_p = XNEW (elt_t);
     667      1056687 :           elt_p->val = val;
     668      1056687 :           elt_p->temp = ret = create_tmp_from_val (val);
     669      1056687 :           *slot = elt_p;
     670              :         }
     671              :       else
     672              :         {
     673       235715 :           elt_p = *slot;
     674       235715 :           ret = elt_p->temp;
     675              :         }
     676              :     }
     677              : 
     678      2381586 :   return ret;
     679              : }
     680              : 
     681              : /* Helper for get_formal_tmp_var and get_initialized_tmp_var.  */
     682              : 
     683              : static tree
     684     26387748 : internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
     685              :                       bool is_formal, bool allow_ssa, bool not_gimple_reg)
     686              : {
     687     26387748 :   tree t, mod;
     688              : 
     689              :   /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
     690              :      can create an INIT_EXPR and convert it into a GIMPLE_CALL below.  */
     691     26387748 :   gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
     692              :                  fb_rvalue);
     693              : 
     694     26387748 :   if (allow_ssa
     695     26119930 :       && gimplify_ctxp->into_ssa
     696     51062137 :       && is_gimple_reg_type (TREE_TYPE (val)))
     697              :     {
     698     24006163 :       t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
     699     24006163 :       if (! gimple_in_ssa_p (cfun))
     700              :         {
     701     20679097 :           const char *name = get_name (val);
     702     20679097 :           if (name)
     703      6773144 :             SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
     704              :         }
     705              :     }
     706              :   else
     707      2381585 :     t = lookup_tmp_var (val, is_formal, not_gimple_reg);
     708              : 
     709     26387748 :   mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
     710              : 
     711     26387748 :   SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
     712              : 
     713              :   /* gimplify_modify_expr might want to reduce this further.  */
     714     26387748 :   gimplify_and_add (mod, pre_p);
     715     26387748 :   ggc_free (mod);
     716              : 
     717              :   /* If we failed to gimplify VAL then we can end up with the temporary
     718              :      SSA name not having a definition.  In this case return a decl.  */
     719     26387748 :   if (TREE_CODE (t) == SSA_NAME && ! SSA_NAME_DEF_STMT (t))
     720            1 :     return lookup_tmp_var (val, is_formal, not_gimple_reg);
     721              : 
     722              :   return t;
     723              : }
     724              : 
     725              : /* Return a formal temporary variable initialized with VAL.  PRE_P is as
     726              :    in gimplify_expr.  Only use this function if:
     727              : 
     728              :    1) The value of the unfactored expression represented by VAL will not
     729              :       change between the initialization and use of the temporary, and
     730              :    2) The temporary will not be otherwise modified.
     731              : 
     732              :    For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
     733              :    and #2 means it is inappropriate for && temps.
     734              : 
     735              :    For other cases, use get_initialized_tmp_var instead.  */
     736              : 
     737              : tree
     738     25892033 : get_formal_tmp_var (tree val, gimple_seq *pre_p)
     739              : {
     740     25892033 :   return internal_get_tmp_var (val, pre_p, NULL, true, true, false);
     741              : }
     742              : 
     743              : /* Return a temporary variable initialized with VAL.  PRE_P and POST_P
     744              :    are as in gimplify_expr.  */
     745              : 
     746              : tree
     747       483694 : get_initialized_tmp_var (tree val, gimple_seq *pre_p,
     748              :                          gimple_seq *post_p /* = NULL */,
     749              :                          bool allow_ssa /* = true */)
     750              : {
     751       483694 :   return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa, false);
     752              : }
     753              : 
     754              : /* Declare all the variables in VARS in SCOPE.  If DEBUG_INFO is true,
     755              :    generate debug info for them; otherwise don't.  */
     756              : 
     757              : void
     758      3013264 : declare_vars (tree vars, gimple *gs, bool debug_info)
     759              : {
     760      3013264 :   tree last = vars;
     761      3013264 :   if (last)
     762              :     {
     763      1885599 :       tree temps, block;
     764              : 
     765      1885599 :       gbind *scope = as_a <gbind *> (gs);
     766              : 
     767      1885599 :       temps = nreverse (last);
     768              : 
     769      1885599 :       block = gimple_bind_block (scope);
     770      1885599 :       gcc_assert (!block || TREE_CODE (block) == BLOCK);
     771      1885599 :       if (!block || !debug_info)
     772              :         {
     773      1881867 :           DECL_CHAIN (last) = gimple_bind_vars (scope);
     774      1881867 :           gimple_bind_set_vars (scope, temps);
     775              :         }
     776              :       else
     777              :         {
     778              :           /* We need to attach the nodes both to the BIND_EXPR and to its
     779              :              associated BLOCK for debugging purposes.  The key point here
     780              :              is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
     781              :              is a subchain of the BIND_EXPR_VARS of the BIND_EXPR.  */
     782         3732 :           if (BLOCK_VARS (block))
     783         3539 :             BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
     784              :           else
     785              :             {
     786          193 :               gimple_bind_set_vars (scope,
     787              :                                     chainon (gimple_bind_vars (scope), temps));
     788          193 :               BLOCK_VARS (block) = temps;
     789              :             }
     790              :         }
     791              :     }
     792      3013264 : }
     793              : 
     794              : /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
     795              :    for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly.  Abort if
     796              :    no such upper bound can be obtained.  */
     797              : 
     798              : static void
     799            0 : force_constant_size (tree var)
     800              : {
     801              :   /* The only attempt we make is by querying the maximum size of objects
     802              :      of the variable's type.  */
     803              : 
     804            0 :   HOST_WIDE_INT max_size;
     805              : 
     806            0 :   gcc_assert (VAR_P (var));
     807              : 
     808            0 :   max_size = max_int_size_in_bytes (TREE_TYPE (var));
     809              : 
     810            0 :   gcc_assert (max_size >= 0);
     811              : 
     812            0 :   DECL_SIZE_UNIT (var)
     813            0 :     = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
     814            0 :   DECL_SIZE (var)
     815            0 :     = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
     816            0 : }
     817              : 
     818              : /* Push the temporary variable TMP into the current binding.  */
     819              : 
     820              : void
     821        24028 : gimple_add_tmp_var_fn (struct function *fn, tree tmp)
     822              : {
     823        24028 :   gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
     824              : 
     825              :   /* Later processing assumes that the object size is constant, which might
     826              :      not be true at this point.  Force the use of a constant upper bound in
     827              :      this case.  */
     828        24028 :   if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
     829            0 :     force_constant_size (tmp);
     830              : 
     831        24028 :   DECL_CONTEXT (tmp) = fn->decl;
     832        24028 :   DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
     833              : 
     834        24028 :   record_vars_into (tmp, fn->decl);
     835        24028 : }
     836              : 
     837              : /* Push the temporary variable TMP into the current binding.  */
     838              : 
     839              : void
     840     16281386 : gimple_add_tmp_var (tree tmp)
     841              : {
     842     16281386 :   gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
     843              : 
     844              :   /* Later processing assumes that the object size is constant, which might
     845              :      not be true at this point.  Force the use of a constant upper bound in
     846              :      this case.  */
     847     16281386 :   if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
     848            0 :     force_constant_size (tmp);
     849              : 
     850     16281386 :   DECL_CONTEXT (tmp) = current_function_decl;
     851     16281386 :   DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
     852              : 
     853     16281386 :   if (gimplify_ctxp)
     854              :     {
     855      5576886 :       DECL_CHAIN (tmp) = gimplify_ctxp->temps;
     856      5576886 :       gimplify_ctxp->temps = tmp;
     857              : 
     858              :       /* Mark temporaries local within the nearest enclosing parallel.  */
     859      5576886 :       if (gimplify_omp_ctxp)
     860              :         {
     861              :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
     862       553323 :           int flag = GOVD_LOCAL | GOVD_SEEN;
     863              :           while (ctx
     864       553323 :                  && (ctx->region_type == ORT_WORKSHARE
     865              :                      || ctx->region_type == ORT_TASKGROUP
     866       405784 :                      || ctx->region_type == ORT_SIMD
     867       355593 :                      || ctx->region_type == ORT_ACC))
     868              :             {
     869       204588 :               if (ctx->region_type == ORT_SIMD
     870        50191 :                   && TREE_ADDRESSABLE (tmp)
     871           95 :                   && !TREE_STATIC (tmp))
     872              :                 {
     873           95 :                   if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
     874            0 :                     ctx->add_safelen1 = true;
     875           95 :                   else if (ctx->in_for_exprs)
     876              :                     flag = GOVD_PRIVATE;
     877              :                   else
     878              :                     flag = GOVD_PRIVATE | GOVD_SEEN;
     879              :                   break;
     880              :                 }
     881       204493 :               ctx = ctx->outer_context;
     882              :             }
     883       348735 :           if (ctx)
     884       321649 :             omp_add_variable (ctx, tmp, flag);
     885              :         }
     886              :     }
     887     10704500 :   else if (cfun)
     888     10704500 :     record_vars (tmp);
     889              :   else
     890              :     {
     891            0 :       gimple_seq body_seq;
     892              : 
     893              :       /* This case is for nested functions.  We need to expose the locals
     894              :          they create.  */
     895            0 :       body_seq = gimple_body (current_function_decl);
     896            0 :       declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
     897              :     }
     898     16281386 : }
     899              : 
     900              : /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
     901              :    any nested functions.  */
     902              : 
     903              : static void
     904      2907361 : unshare_body (tree fndecl)
     905              : {
     906      2907361 :   struct cgraph_node *cgn = cgraph_node::get (fndecl);
     907              :   /* If the language requires deep unsharing, we need a pointer set to make
     908              :      sure we don't repeatedly unshare subtrees of unshareable nodes.  */
     909      2907361 :   hash_set<tree> *visited
     910      2907361 :     = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
     911              : 
     912      2907361 :   copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
     913      2907361 :   copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
     914      2907361 :   copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
     915              : 
     916      2911537 :   delete visited;
     917              : 
     918      2907361 :   if (cgn)
     919      5858554 :     for (cgn = first_nested_function (cgn); cgn;
     920        26113 :          cgn = next_nested_function (cgn))
     921        26113 :       unshare_body (cgn->decl);
     922      2907361 : }
     923              : 
     924              : /* Callback for walk_tree to unmark the visited trees rooted at *TP.
     925              :    Subtrees are walked until the first unvisited node is encountered.  */
     926              : 
     927              : static tree
     928    278287029 : unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
     929              : {
     930    278287029 :   tree t = *tp;
     931              : 
     932              :   /* If this node has been visited, unmark it and keep looking.  */
     933    278287029 :   if (TREE_VISITED (t))
     934    194895506 :     TREE_VISITED (t) = 0;
     935              : 
     936              :   /* Otherwise, don't look any deeper.  */
     937              :   else
     938     83391523 :     *walk_subtrees = 0;
     939              : 
     940    278287029 :   return NULL_TREE;
     941              : }
     942              : 
     943              : /* Unmark the visited trees rooted at *TP.  */
     944              : 
     945              : static inline void
     946      8722083 : unmark_visited (tree *tp)
     947              : {
     948      8722083 :   walk_tree (tp, unmark_visited_r, NULL, NULL);
     949      8722083 : }
     950              : 
     951              : /* Likewise, but mark all trees as not visited.  */
     952              : 
     953              : static void
     954      2907361 : unvisit_body (tree fndecl)
     955              : {
     956      2907361 :   struct cgraph_node *cgn = cgraph_node::get (fndecl);
     957              : 
     958      2907361 :   unmark_visited (&DECL_SAVED_TREE (fndecl));
     959      2907361 :   unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
     960      2907361 :   unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
     961              : 
     962      2907361 :   if (cgn)
     963      2929277 :     for (cgn = first_nested_function (cgn);
     964      2929277 :          cgn; cgn = next_nested_function (cgn))
     965        26113 :       unvisit_body (cgn->decl);
     966      2907361 : }
     967              : 
     968              : /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
     969              :    one, OR_ELSE otherwise.  The location of a STATEMENT_LISTs
     970              :    comprising at least one DEBUG_BEGIN_STMT followed by exactly one
     971              :    EXPR is the location of the EXPR.  */
     972              : 
     973              : static location_t
     974      1170066 : rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
     975              : {
     976      1170066 :   if (!expr)
     977              :     return or_else;
     978              : 
     979      1170066 :   if (EXPR_HAS_LOCATION (expr))
     980       817487 :     return EXPR_LOCATION (expr);
     981              : 
     982       352579 :   if (TREE_CODE (expr) != STATEMENT_LIST)
     983              :     return or_else;
     984              : 
     985            0 :   tree_stmt_iterator i = tsi_start (expr);
     986              : 
     987            0 :   bool found = false;
     988            0 :   while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
     989              :     {
     990            0 :       found = true;
     991            0 :       tsi_next (&i);
     992              :     }
     993              : 
     994       352579 :   if (!found || !tsi_one_before_end_p (i))
     995              :     return or_else;
     996              : 
     997            0 :   return rexpr_location (tsi_stmt (i), or_else);
     998              : }
     999              : 
    1000              : /* Return TRUE iff EXPR (maybe recursively) has a location; see
    1001              :    rexpr_location for the potential recursion.  */
    1002              : 
    1003              : static inline bool
    1004       508861 : rexpr_has_location (tree expr)
    1005              : {
    1006       305783 :   return rexpr_location (expr) != UNKNOWN_LOCATION;
    1007              : }
    1008              : 
    1009              : 
    1010              : /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
    1011              :    contain statements and have a value.  Assign its value to a temporary
    1012              :    and give it void_type_node.  Return the temporary, or NULL_TREE if
    1013              :    WRAPPER was already void.  */
    1014              : 
    1015              : tree
    1016     20030948 : voidify_wrapper_expr (tree wrapper, tree temp)
    1017              : {
    1018     20030948 :   tree type = TREE_TYPE (wrapper);
    1019     20030948 :   if (type && !VOID_TYPE_P (type))
    1020              :     {
    1021              :       tree *p;
    1022              : 
    1023              :       /* Set p to point to the body of the wrapper.  Loop until we find
    1024              :          something that isn't a wrapper.  */
    1025       766407 :       for (p = &wrapper; p && *p; )
    1026              :         {
    1027       766407 :           switch (TREE_CODE (*p))
    1028              :             {
    1029         3144 :             case BIND_EXPR:
    1030         3144 :               TREE_SIDE_EFFECTS (*p) = 1;
    1031         3144 :               TREE_TYPE (*p) = void_type_node;
    1032              :               /* For a BIND_EXPR, the body is operand 1.  */
    1033         3144 :               p = &BIND_EXPR_BODY (*p);
    1034         3144 :               break;
    1035              : 
    1036       353747 :             case CLEANUP_POINT_EXPR:
    1037       353747 :             case TRY_FINALLY_EXPR:
    1038       353747 :             case TRY_CATCH_EXPR:
    1039       353747 :               TREE_SIDE_EFFECTS (*p) = 1;
    1040       353747 :               TREE_TYPE (*p) = void_type_node;
    1041       353747 :               p = &TREE_OPERAND (*p, 0);
    1042       353747 :               break;
    1043              : 
    1044        17903 :             case STATEMENT_LIST:
    1045        17903 :               {
    1046        17903 :                 tree_stmt_iterator i = tsi_last (*p);
    1047        17903 :                 TREE_SIDE_EFFECTS (*p) = 1;
    1048        17903 :                 TREE_TYPE (*p) = void_type_node;
    1049        17903 :                 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
    1050              :               }
    1051        17903 :               break;
    1052              : 
    1053              :             case COMPOUND_EXPR:
    1054              :               /* Advance to the last statement.  Set all container types to
    1055              :                  void.  */
    1056        63512 :               for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
    1057              :                 {
    1058        31759 :                   TREE_SIDE_EFFECTS (*p) = 1;
    1059        31759 :                   TREE_TYPE (*p) = void_type_node;
    1060              :                 }
    1061              :               break;
    1062              : 
    1063           76 :             case TRANSACTION_EXPR:
    1064           76 :               TREE_SIDE_EFFECTS (*p) = 1;
    1065           76 :               TREE_TYPE (*p) = void_type_node;
    1066           76 :               p = &TRANSACTION_EXPR_BODY (*p);
    1067           76 :               break;
    1068              : 
    1069       359784 :             default:
    1070              :               /* Assume that any tree upon which voidify_wrapper_expr is
    1071              :                  directly called is a wrapper, and that its body is op0.  */
    1072       359784 :               if (p == &wrapper)
    1073              :                 {
    1074           33 :                   TREE_SIDE_EFFECTS (*p) = 1;
    1075           33 :                   TREE_TYPE (*p) = void_type_node;
    1076           33 :                   p = &TREE_OPERAND (*p, 0);
    1077           33 :                   break;
    1078              :                 }
    1079       359751 :               goto out;
    1080              :             }
    1081              :         }
    1082              : 
    1083            0 :     out:
    1084       359751 :       if (p == NULL || IS_EMPTY_STMT (*p))
    1085              :         temp = NULL_TREE;
    1086       359751 :       else if (temp)
    1087              :         {
    1088              :           /* The wrapper is on the RHS of an assignment that we're pushing
    1089              :              down.  */
    1090         1933 :           gcc_assert (TREE_CODE (temp) == INIT_EXPR
    1091              :                       || TREE_CODE (temp) == MODIFY_EXPR);
    1092         1933 :           TREE_OPERAND (temp, 1) = *p;
    1093         1933 :           *p = temp;
    1094              :         }
    1095              :       else
    1096              :         {
    1097       357818 :           temp = create_tmp_var (type, "retval");
    1098       357818 :           *p = build2 (INIT_EXPR, type, temp, *p);
    1099              :         }
    1100              : 
    1101       359751 :       return temp;
    1102              :     }
    1103              : 
    1104              :   return NULL_TREE;
    1105              : }
    1106              : 
    1107              : /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
    1108              :    a temporary through which they communicate.  */
    1109              : 
    1110              : static void
    1111         7870 : build_stack_save_restore (gcall **save, gcall **restore)
    1112              : {
    1113         7870 :   tree tmp_var;
    1114              : 
    1115        15740 :   *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
    1116         7870 :   tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
    1117         7870 :   gimple_call_set_lhs (*save, tmp_var);
    1118              : 
    1119         7870 :   *restore
    1120         7870 :     = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
    1121              :                          1, tmp_var);
    1122         7870 : }
    1123              : 
    1124              : /* Generate IFN_ASAN_MARK call that poisons shadow memory of the DECL
    1125              :    variable.  */
    1126              : 
    1127              : static tree
    1128          478 : build_asan_poison_call_expr (tree decl)
    1129              : {
    1130              :   /* Do not poison variables that have size equal to zero.  */
    1131          478 :   tree unit_size = DECL_SIZE_UNIT (decl);
    1132          478 :   if (zerop (unit_size))
    1133              :     return NULL_TREE;
    1134              : 
    1135          478 :   tree base = build_fold_addr_expr (decl);
    1136              : 
    1137          478 :   return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
    1138              :                                        void_type_node, 3,
    1139              :                                        build_int_cst (integer_type_node,
    1140              :                                                       ASAN_MARK_POISON),
    1141              :                                        base, unit_size);
    1142              : }
    1143              : 
    1144              : /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
    1145              :    on POISON flag, shadow memory of a DECL variable.  The call will be
    1146              :    put on location identified by IT iterator, where BEFORE flag drives
    1147              :    position where the stmt will be put.  */
    1148              : 
    1149              : static void
    1150         5065 : asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
    1151              :                       bool before)
    1152              : {
    1153         5065 :   tree unit_size = DECL_SIZE_UNIT (decl);
    1154         5065 :   tree base = build_fold_addr_expr (decl);
    1155              : 
    1156              :   /* Do not poison variables that have size equal to zero.  */
    1157         5065 :   if (zerop (unit_size))
    1158         5065 :     return;
    1159              : 
    1160              :   /* It's necessary to have all stack variables aligned to ASAN granularity
    1161              :      bytes.  */
    1162         5051 :   gcc_assert (!hwassist_sanitize_p () || hwassist_sanitize_stack_p ());
    1163         5051 :   unsigned shadow_granularity
    1164         5051 :     = (hwassist_sanitize_p ()
    1165         5051 :        ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY);
    1166         5051 :   if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
    1167         4849 :     SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
    1168              : 
    1169         5051 :   HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
    1170              : 
    1171         5051 :   gimple *g
    1172         5051 :     = gimple_build_call_internal (IFN_ASAN_MARK, 3,
    1173         5051 :                                   build_int_cst (integer_type_node, flags),
    1174              :                                   base, unit_size);
    1175              : 
    1176         5051 :   if (before)
    1177         2648 :     gsi_insert_before (it, g, GSI_NEW_STMT);
    1178              :   else
    1179         2403 :     gsi_insert_after (it, g, GSI_NEW_STMT);
    1180              : }
    1181              : 
    1182              : /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
    1183              :    either poisons or unpoisons a DECL.  Created statement is appended
    1184              :    to SEQ_P gimple sequence.  */
    1185              : 
    1186              : static void
    1187         4587 : asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
    1188              : {
    1189         4587 :   gimple_stmt_iterator it = gsi_last (*seq_p);
    1190         4587 :   bool before = false;
    1191              : 
    1192         4587 :   if (gsi_end_p (it))
    1193         2433 :     before = true;
    1194              : 
    1195         4587 :   asan_poison_variable (decl, poison, &it, before);
    1196         4587 : }
    1197              : 
    1198              : /* Sort pair of VAR_DECLs A and B by DECL_UID.  */
    1199              : 
    1200              : static int
    1201          135 : sort_by_decl_uid (const void *a, const void *b)
    1202              : {
    1203          135 :   const tree *t1 = (const tree *)a;
    1204          135 :   const tree *t2 = (const tree *)b;
    1205              : 
    1206          135 :   int uid1 = DECL_UID (*t1);
    1207          135 :   int uid2 = DECL_UID (*t2);
    1208              : 
    1209          135 :   if (uid1 < uid2)
    1210              :     return -1;
    1211           57 :   else if (uid1 > uid2)
    1212              :     return 1;
    1213              :   else
    1214            0 :     return 0;
    1215              : }
    1216              : 
    1217              : /* Generate IFN_ASAN_MARK internal call for all VARIABLES
    1218              :    depending on POISON flag.  Created statement is appended
    1219              :    to SEQ_P gimple sequence.  */
    1220              : 
    1221              : static void
    1222      1034761 : asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
    1223              : {
    1224      1034761 :   unsigned c = variables->elements ();
    1225      1034761 :   if (c == 0)
    1226      1034487 :     return;
    1227              : 
    1228          274 :   auto_vec<tree> sorted_variables (c);
    1229              : 
    1230          274 :   for (hash_set<tree>::iterator it = variables->begin ();
    1231          864 :        it != variables->end (); ++it)
    1232          295 :     sorted_variables.safe_push (*it);
    1233              : 
    1234          274 :   sorted_variables.qsort (sort_by_decl_uid);
    1235              : 
    1236              :   unsigned i;
    1237              :   tree var;
    1238          843 :   FOR_EACH_VEC_ELT (sorted_variables, i, var)
    1239              :     {
    1240          295 :       asan_poison_variable (var, poison, seq_p);
    1241              : 
    1242              :       /* Add use_after_scope_memory attribute for the variable in order
    1243              :          to prevent re-written into SSA.  */
    1244          295 :       if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
    1245          295 :                              DECL_ATTRIBUTES (var)))
    1246           97 :         DECL_ATTRIBUTES (var)
    1247          194 :           = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
    1248              :                        integer_one_node,
    1249           97 :                        DECL_ATTRIBUTES (var));
    1250              :     }
    1251          274 : }
    1252              : 
    1253              : /* Gimplify a BIND_EXPR.  Just voidify and recurse.  */
    1254              : 
    1255              : static enum gimplify_status
    1256      5927825 : gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
    1257              : {
    1258      5927825 :   tree bind_expr = *expr_p;
    1259      5927825 :   bool old_keep_stack = gimplify_ctxp->keep_stack;
    1260      5927825 :   bool old_save_stack = gimplify_ctxp->save_stack;
    1261      5927825 :   tree t;
    1262      5927825 :   gbind *bind_stmt;
    1263      5927825 :   gimple_seq body, cleanup;
    1264      5927825 :   gcall *stack_save;
    1265      5927825 :   location_t start_locus = 0, end_locus = 0;
    1266      5927825 :   tree ret_clauses = NULL;
    1267              : 
    1268      5927825 :   tree temp = voidify_wrapper_expr (bind_expr, NULL);
    1269              : 
    1270              :   /* Mark variables seen in this bind expr.  */
    1271     12738720 :   for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
    1272              :     {
    1273      6810895 :       if (VAR_P (t))
    1274              :         {
    1275      6169366 :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
    1276      6169366 :           tree attr;
    1277              : 
    1278      6169366 :           if (flag_openmp
    1279       258255 :               && !is_global_var (t)
    1280       249341 :               && !TREE_STATIC (t)
    1281       249341 :               && DECL_CONTEXT (t) == current_function_decl
    1282       249341 :               && TREE_USED (t)
    1283      6417086 :               && (attr = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t)))
    1284              :                  != NULL_TREE)
    1285              :             {
    1286           76 :               gcc_assert (!DECL_HAS_VALUE_EXPR_P (t));
    1287           76 :               tree alloc = TREE_PURPOSE (TREE_VALUE (attr));
    1288           76 :               tree align = TREE_VALUE (TREE_VALUE (attr));
    1289              :               /* Allocate directives that appear in a target region must specify
    1290              :                  an allocator clause unless a requires directive with the
    1291              :                  dynamic_allocators clause is present in the same compilation
    1292              :                  unit.  */
    1293           76 :               bool missing_dyn_alloc = false;
    1294           76 :               if (alloc == NULL_TREE
    1295           48 :                   && ((omp_requires_mask & OMP_REQUIRES_DYNAMIC_ALLOCATORS)
    1296              :                       == 0))
    1297              :                 {
    1298              :                   /* This comes too early for omp_discover_declare_target...,
    1299              :                      but should at least catch the most common cases.  */
    1300           42 :                   missing_dyn_alloc
    1301           42 :                     = cgraph_node::get (current_function_decl)->offloadable;
    1302           42 :                   for (struct gimplify_omp_ctx *ctx2 = ctx;
    1303           48 :                        ctx2 && !missing_dyn_alloc; ctx2 = ctx2->outer_context)
    1304            6 :                     if (ctx2->code == OMP_TARGET)
    1305            2 :                       missing_dyn_alloc = true;
    1306              :                 }
    1307           42 :               if (missing_dyn_alloc)
    1308            4 :                 error_at (DECL_SOURCE_LOCATION (t),
    1309              :                           "%<allocate%> directive for %qD inside a target "
    1310              :                           "region must specify an %<allocator%> clause", t);
    1311              :               /* Skip for omp_default_mem_alloc (= 1),
    1312              :                  unless align is present.  For C/C++, there should be always a
    1313              :                  statement list following if TREE_USED, except for, e.g., using
    1314              :                  this decl in a static_assert; in that case, only a single
    1315              :                  DECL_EXPR remains, which can be skipped here.  */
    1316           72 :               else if (!errorcount
    1317           57 :                        && (align != NULL_TREE
    1318           57 :                            || alloc == NULL_TREE
    1319           12 :                            || !integer_onep (alloc))
    1320          127 :                        && (lang_GNU_Fortran ()
    1321           27 :                            || (TREE_CODE (BIND_EXPR_BODY (bind_expr))
    1322              :                                != DECL_EXPR)))
    1323              :                 {
    1324              :                   /* Fortran might already use a pointer type internally;
    1325              :                      use that pointer except for type(C_ptr) and type(C_funptr);
    1326              :                      note that normal proc pointers are rejected.  */
    1327           55 :                   tree type = TREE_TYPE (t);
    1328           55 :                   tree tmp, v;
    1329           55 :                   if (lang_GNU_Fortran ()
    1330           28 :                       && POINTER_TYPE_P (type)
    1331            8 :                       && TREE_TYPE (type) != void_type_node
    1332           61 :                       && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
    1333              :                     {
    1334            6 :                       type = TREE_TYPE (type);
    1335            6 :                       v = t;
    1336              :                     }
    1337              :                   else
    1338              :                     {
    1339           49 :                       tmp = build_pointer_type (type);
    1340           49 :                       v = create_tmp_var (tmp, get_name (t));
    1341           49 :                       DECL_IGNORED_P (v) = 0;
    1342           49 :                       DECL_ATTRIBUTES (v)
    1343           49 :                         = tree_cons (get_identifier ("omp allocate var"),
    1344              :                                      build_tree_list (NULL_TREE, t),
    1345              :                                      remove_attribute ("omp allocate",
    1346           49 :                                                        DECL_ATTRIBUTES (t)));
    1347           49 :                       tmp = build_fold_indirect_ref (v);
    1348           49 :                       TREE_THIS_NOTRAP (tmp) = 1;
    1349           49 :                       SET_DECL_VALUE_EXPR (t, tmp);
    1350           49 :                       DECL_HAS_VALUE_EXPR_P (t) = 1;
    1351              :                     }
    1352           55 :                   tree sz = TYPE_SIZE_UNIT (type);
    1353              :                   /* The size to use in Fortran might not match TYPE_SIZE_UNIT;
    1354              :                      hence, for some decls, a size variable is saved in the
    1355              :                      attributes; use it, if available.  */
    1356           55 :                   if (TREE_CHAIN (TREE_VALUE (attr))
    1357           28 :                       && TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)))
    1358           61 :                       && TREE_PURPOSE (
    1359              :                            TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)))))
    1360              :                     {
    1361            6 :                       sz = TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)));
    1362            6 :                       sz = TREE_PURPOSE (sz);
    1363              :                     }
    1364           55 :                   if (alloc == NULL_TREE)
    1365           36 :                     alloc = build_zero_cst (ptr_type_node);
    1366           55 :                   if (align == NULL_TREE)
    1367           44 :                     align = build_int_cst (size_type_node, DECL_ALIGN_UNIT (t));
    1368              :                   else
    1369           11 :                     align = build_int_cst (size_type_node,
    1370           11 :                                            MAX (tree_to_uhwi (align),
    1371              :                                                 DECL_ALIGN_UNIT (t)));
    1372           55 :                   location_t loc = DECL_SOURCE_LOCATION (t);
    1373           55 :                   tmp = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
    1374           55 :                   tmp = build_call_expr_loc (loc, tmp, 3, align, sz, alloc);
    1375           55 :                   tmp = fold_build2_loc (loc, MODIFY_EXPR, TREE_TYPE (v), v,
    1376           55 :                                          fold_convert (TREE_TYPE (v), tmp));
    1377           55 :                   gcc_assert (BIND_EXPR_BODY (bind_expr) != NULL_TREE);
    1378              :                   /* Ensure that either TREE_CHAIN (TREE_VALUE (attr) is set
    1379              :                      and GOMP_FREE added here or that DECL_HAS_VALUE_EXPR_P (t)
    1380              :                      is set, using in a condition much further below.  */
    1381           61 :                   gcc_assert (DECL_HAS_VALUE_EXPR_P (t)
    1382              :                               || TREE_CHAIN (TREE_VALUE (attr)));
    1383           55 :                   if (TREE_CHAIN (TREE_VALUE (attr)))
    1384              :                     {
    1385              :                       /* Fortran is special as it does not have properly nest
    1386              :                          declarations in blocks.  And as there is no
    1387              :                          initializer, there is also no expression to look for.
    1388              :                          Hence, the FE makes the statement list of the
    1389              :                          try-finally block available. We can put the GOMP_alloc
    1390              :                          at the top, unless an allocator or size expression
    1391              :                          requires to put it afterward; note that the size is
    1392              :                          always later in generated code; for strings, no
    1393              :                          size expr but still an expr might be available.
    1394              :                          As LTO does not handle a statement list, 'sl' has
    1395              :                          to be removed; done so by removing the attribute.  */
    1396           28 :                       DECL_ATTRIBUTES (t)
    1397           28 :                         = remove_attribute ("omp allocate",
    1398           28 :                                             DECL_ATTRIBUTES (t));
    1399           28 :                       tree sl = TREE_PURPOSE (TREE_CHAIN (TREE_VALUE (attr)));
    1400           28 :                       tree_stmt_iterator e = tsi_start (sl);
    1401           28 :                       tree needle = NULL_TREE;
    1402           28 :                       if (TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr))))
    1403              :                         {
    1404            6 :                           needle = TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)));
    1405            6 :                           needle = (TREE_VALUE (needle) ? TREE_VALUE (needle)
    1406              :                                                         : sz);
    1407              :                         }
    1408           22 :                       else if (TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr))))
    1409              :                         needle = sz;
    1410           22 :                       else if (DECL_P (alloc) && DECL_ARTIFICIAL (alloc))
    1411              :                         needle = alloc;
    1412              : 
    1413           10 :                       if (needle != NULL_TREE)
    1414              :                         {
    1415           49 :                           while (!tsi_end_p (e))
    1416              :                             {
    1417           49 :                               if (*e == needle
    1418           49 :                                   || (TREE_CODE (*e) == MODIFY_EXPR
    1419           49 :                                       && TREE_OPERAND (*e, 0) == needle))
    1420              :                                 break;
    1421           39 :                               ++e;
    1422              :                             }
    1423           10 :                           gcc_assert (!tsi_end_p (e));
    1424              :                         }
    1425           28 :                       tsi_link_after (&e, tmp, TSI_SAME_STMT);
    1426              : 
    1427              :                       /* As the cleanup is in BIND_EXPR_BODY, GOMP_free is added
    1428              :                          here; for C/C++ it will be added in the 'cleanup'
    1429              :                          section after gimplification. But Fortran already has
    1430              :                          a try-finally block.  */
    1431           28 :                       sl = TREE_VALUE (TREE_CHAIN (TREE_VALUE (attr)));
    1432           28 :                       e = tsi_last (sl);
    1433           28 :                       tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
    1434           28 :                       tmp = build_call_expr_loc (EXPR_LOCATION (*e), tmp, 2, v,
    1435              :                                                  build_zero_cst (ptr_type_node));
    1436           28 :                       tsi_link_after (&e, tmp, TSI_SAME_STMT);
    1437           28 :                       tmp = build_clobber (TREE_TYPE (v), CLOBBER_STORAGE_END);
    1438           28 :                       tmp = fold_build2_loc (loc, MODIFY_EXPR, TREE_TYPE (v), v,
    1439           28 :                                              fold_convert (TREE_TYPE (v), tmp));
    1440           28 :                       ++e;
    1441           28 :                       tsi_link_after (&e, tmp, TSI_SAME_STMT);
    1442              :                     }
    1443              :                   else
    1444              :                     {
    1445           27 :                       gcc_assert (TREE_CODE (BIND_EXPR_BODY (bind_expr))
    1446              :                                   == STATEMENT_LIST);
    1447           27 :                       tree_stmt_iterator e;
    1448           27 :                       e = tsi_start (BIND_EXPR_BODY (bind_expr));
    1449          117 :                       while (!tsi_end_p (e))
    1450              :                         {
    1451           90 :                           if ((TREE_CODE (*e) == DECL_EXPR
    1452           60 :                                && TREE_OPERAND (*e, 0) == t)
    1453          123 :                               || (TREE_CODE (*e) == CLEANUP_POINT_EXPR
    1454            0 :                                   && (TREE_CODE (TREE_OPERAND (*e, 0))
    1455              :                                       == DECL_EXPR)
    1456            0 :                                   && (TREE_OPERAND (TREE_OPERAND (*e, 0), 0)
    1457              :                                       == t)))
    1458              :                             break;
    1459           63 :                           ++e;
    1460              :                         }
    1461           27 :                       gcc_assert (!tsi_end_p (e));
    1462           27 :                       tsi_link_before (&e, tmp, TSI_SAME_STMT);
    1463              :                    }
    1464              :                 }
    1465              :             }
    1466              : 
    1467              :           /* Mark variable as local.  */
    1468      6169366 :           if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
    1469              :             {
    1470       100748 :               if (! DECL_SEEN_IN_BIND_EXPR_P (t)
    1471       100748 :                   || splay_tree_lookup (ctx->variables,
    1472              :                                         (splay_tree_key) t) == NULL)
    1473              :                 {
    1474       100748 :                   int flag = GOVD_LOCAL;
    1475       100748 :                   if (ctx->region_type == ORT_SIMD
    1476         4374 :                       && TREE_ADDRESSABLE (t)
    1477           81 :                       && !TREE_STATIC (t))
    1478              :                     {
    1479           69 :                       if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
    1480            2 :                         ctx->add_safelen1 = true;
    1481              :                       else
    1482              :                         flag = GOVD_PRIVATE;
    1483              :                     }
    1484       100748 :                   omp_add_variable (ctx, t, flag | GOVD_SEEN);
    1485              :                 }
    1486              :               /* Static locals inside of target construct or offloaded
    1487              :                  routines need to be "omp declare target".  */
    1488       100748 :               if (TREE_STATIC (t))
    1489         1380 :                 for (; ctx; ctx = ctx->outer_context)
    1490         1201 :                   if ((ctx->region_type & ORT_TARGET) != 0)
    1491              :                     {
    1492          964 :                       if (!lookup_attribute ("omp declare target",
    1493          964 :                                              DECL_ATTRIBUTES (t)))
    1494              :                         {
    1495          952 :                           tree id = get_identifier ("omp declare target");
    1496          952 :                           DECL_ATTRIBUTES (t)
    1497          952 :                             = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
    1498          952 :                           varpool_node *node = varpool_node::get (t);
    1499          952 :                           if (node)
    1500              :                             {
    1501           33 :                               node->offloadable = 1;
    1502           33 :                               if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
    1503              :                                 {
    1504              :                                   g->have_offload = true;
    1505              :                                   if (!in_lto_p)
    1506              :                                     vec_safe_push (offload_vars, t);
    1507              :                                 }
    1508              :                             }
    1509              :                         }
    1510              :                       break;
    1511              :                     }
    1512              :             }
    1513              : 
    1514      6169366 :           DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
    1515              : 
    1516      6169366 :           if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
    1517         1088 :             cfun->has_local_explicit_reg_vars = true;
    1518              :         }
    1519              :     }
    1520              : 
    1521     11855650 :   bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
    1522      5927825 :                                  BIND_EXPR_BLOCK (bind_expr));
    1523      5927825 :   gimple_push_bind_expr (bind_stmt);
    1524              : 
    1525      5927825 :   gimplify_ctxp->keep_stack = false;
    1526      5927825 :   gimplify_ctxp->save_stack = false;
    1527              : 
    1528              :   /* Gimplify the body into the GIMPLE_BIND tuple's body.  */
    1529      5927825 :   body = NULL;
    1530      5927825 :   gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
    1531      5927825 :   gimple_bind_set_body (bind_stmt, body);
    1532              : 
    1533              :   /* Source location wise, the cleanup code (stack_restore and clobbers)
    1534              :      belongs to the end of the block, so propagate what we have.  The
    1535              :      stack_save operation belongs to the beginning of block, which we can
    1536              :      infer from the bind_expr directly if the block has no explicit
    1537              :      assignment.  */
    1538      5927825 :   if (BIND_EXPR_BLOCK (bind_expr))
    1539              :     {
    1540      5796410 :       end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
    1541      5796410 :       start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
    1542              :     }
    1543      5796410 :   if (start_locus == 0)
    1544      5927825 :     start_locus = EXPR_LOCATION (bind_expr);
    1545              : 
    1546      5927825 :   cleanup = NULL;
    1547      5927825 :   stack_save = NULL;
    1548              : 
    1549              :   /* Add clobbers for all variables that go out of scope.  */
    1550     12738720 :   for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
    1551              :     {
    1552      6810895 :       if (VAR_P (t)
    1553      6169366 :           && !is_global_var (t)
    1554     12762527 :           && DECL_CONTEXT (t) == current_function_decl)
    1555              :         {
    1556      5951632 :           if (flag_openmp
    1557       249326 :               && DECL_HAS_VALUE_EXPR_P (t)
    1558         1087 :               && TREE_USED (t)
    1559      5952700 :               && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t)))
    1560              :             {
    1561              :               /* For Fortran, TREE_CHAIN (TREE_VALUE (attr)) is set, which
    1562              :                  causes that the GOMP_free call is already added above;
    1563              :                  and "omp allocate" is removed from DECL_ATTRIBUTES.  */
    1564           27 :               tree v = TREE_OPERAND (DECL_VALUE_EXPR (t), 0);
    1565           27 :               tree tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
    1566           27 :               tmp = build_call_expr_loc (end_locus, tmp, 2, v,
    1567              :                                          build_zero_cst (ptr_type_node));
    1568           27 :               gimplify_and_add (tmp, &cleanup);
    1569           27 :               gimple *clobber_stmt;
    1570           27 :               tmp = build_clobber (TREE_TYPE (v), CLOBBER_STORAGE_END);
    1571           27 :               clobber_stmt = gimple_build_assign (v, tmp);
    1572           27 :               gimple_set_location (clobber_stmt, end_locus);
    1573           27 :               gimplify_seq_add_stmt (&cleanup, clobber_stmt);
    1574              :             }
    1575      5951632 :           if (!DECL_HARD_REGISTER (t)
    1576      5950544 :               && !TREE_THIS_VOLATILE (t)
    1577      5911549 :               && !DECL_HAS_VALUE_EXPR_P (t)
    1578              :               /* Only care for variables that have to be in memory.  Others
    1579              :                  will be rewritten into SSA names, hence moved to the
    1580              :                  top-level.  */
    1581      5808109 :               && !is_gimple_reg (t)
    1582      7189832 :               && flag_stack_reuse != SR_NONE)
    1583              :             {
    1584      1234753 :               tree clobber = build_clobber (TREE_TYPE (t), CLOBBER_STORAGE_END);
    1585      1234753 :               gimple *clobber_stmt;
    1586      1234753 :               clobber_stmt = gimple_build_assign (t, clobber);
    1587      1234753 :               gimple_set_location (clobber_stmt, end_locus);
    1588      1234753 :               gimplify_seq_add_stmt (&cleanup, clobber_stmt);
    1589              :             }
    1590              : 
    1591      5951632 :           if (flag_openacc && oacc_declare_returns != NULL)
    1592              :             {
    1593          207 :               tree key = t;
    1594          207 :               if (DECL_HAS_VALUE_EXPR_P (key))
    1595              :                 {
    1596            8 :                   key = DECL_VALUE_EXPR (key);
    1597            8 :                   if (INDIRECT_REF_P (key))
    1598            8 :                     key = TREE_OPERAND (key, 0);
    1599              :                 }
    1600          207 :               tree *c = oacc_declare_returns->get (key);
    1601          207 :               if (c != NULL)
    1602              :                 {
    1603          116 :                   if (ret_clauses)
    1604           64 :                     OMP_CLAUSE_CHAIN (*c) = ret_clauses;
    1605              : 
    1606          116 :                   ret_clauses = unshare_expr (*c);
    1607              : 
    1608          116 :                   oacc_declare_returns->remove (key);
    1609              : 
    1610          116 :                   if (oacc_declare_returns->is_empty ())
    1611              :                     {
    1612           40 :                       delete oacc_declare_returns;
    1613           40 :                       oacc_declare_returns = NULL;
    1614              :                     }
    1615              :                 }
    1616              :             }
    1617              :         }
    1618              : 
    1619      6810895 :       if (asan_poisoned_variables != NULL
    1620      6810895 :           && asan_poisoned_variables->contains (t))
    1621              :         {
    1622         2146 :           asan_poisoned_variables->remove (t);
    1623         2146 :           asan_poison_variable (t, true, &cleanup);
    1624              :         }
    1625              : 
    1626      6810895 :       if (gimplify_ctxp->live_switch_vars != NULL
    1627      6810895 :           && gimplify_ctxp->live_switch_vars->contains (t))
    1628           55 :         gimplify_ctxp->live_switch_vars->remove (t);
    1629              :     }
    1630              : 
    1631              :   /* If the code both contains VLAs and calls alloca, then we cannot reclaim
    1632              :      the stack space allocated to the VLAs.  */
    1633      5927825 :   if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
    1634              :     {
    1635         7870 :       gcall *stack_restore;
    1636              : 
    1637              :       /* Save stack on entry and restore it on exit.  Add a try_finally
    1638              :          block to achieve this.  */
    1639         7870 :       build_stack_save_restore (&stack_save, &stack_restore);
    1640              : 
    1641         7870 :       gimple_set_location (stack_save, start_locus);
    1642         7870 :       gimple_set_location (stack_restore, end_locus);
    1643              : 
    1644         7870 :       gimplify_seq_add_stmt (&cleanup, stack_restore);
    1645              :     }
    1646              : 
    1647      5927825 :   if (ret_clauses)
    1648              :     {
    1649           52 :       gomp_target *stmt;
    1650           52 :       gimple_stmt_iterator si = gsi_start (cleanup);
    1651              : 
    1652           52 :       stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
    1653              :                                       ret_clauses);
    1654           52 :       gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
    1655              :     }
    1656              : 
    1657      5927825 :   if (cleanup)
    1658              :     {
    1659       762931 :       gtry *gs;
    1660       762931 :       gimple_seq new_body;
    1661              : 
    1662       762931 :       new_body = NULL;
    1663       762931 :       gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
    1664              :                              GIMPLE_TRY_FINALLY);
    1665              : 
    1666       762931 :       if (stack_save)
    1667         7870 :         gimplify_seq_add_stmt (&new_body, stack_save);
    1668       762931 :       gimplify_seq_add_stmt (&new_body, gs);
    1669       762931 :       gimple_bind_set_body (bind_stmt, new_body);
    1670              :     }
    1671              : 
    1672              :   /* keep_stack propagates all the way up to the outermost BIND_EXPR.  */
    1673      5927825 :   if (!gimplify_ctxp->keep_stack)
    1674      5912504 :     gimplify_ctxp->keep_stack = old_keep_stack;
    1675      5927825 :   gimplify_ctxp->save_stack = old_save_stack;
    1676              : 
    1677      5927825 :   gimple_pop_bind_expr ();
    1678              : 
    1679      5927825 :   gimplify_seq_add_stmt (pre_p, bind_stmt);
    1680              : 
    1681      5927825 :   if (temp)
    1682              :     {
    1683         1709 :       *expr_p = temp;
    1684         1709 :       return GS_OK;
    1685              :     }
    1686              : 
    1687      5926116 :   *expr_p = NULL_TREE;
    1688      5926116 :   return GS_ALL_DONE;
    1689              : }
    1690              : 
    1691              : /* Maybe add early return predict statement to PRE_P sequence.  */
    1692              : 
    1693              : static void
    1694      2201599 : maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
    1695              : {
    1696              :   /* If we are not in a conditional context, add PREDICT statement.  */
    1697      2201599 :   if (gimple_conditional_context ())
    1698              :     {
    1699       440612 :       gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
    1700              :                                               NOT_TAKEN);
    1701       440612 :       gimplify_seq_add_stmt (pre_p, predict);
    1702              :     }
    1703      2201599 : }
    1704              : 
    1705              : /* Gimplify a RETURN_EXPR.  If the expression to be returned is not a
    1706              :    GIMPLE value, it is assigned to a new temporary and the statement is
    1707              :    re-written to return the temporary.
    1708              : 
    1709              :    PRE_P points to the sequence where side effects that must happen before
    1710              :    STMT should be stored.  */
    1711              : 
    1712              : static enum gimplify_status
    1713      2201605 : gimplify_return_expr (tree stmt, gimple_seq *pre_p)
    1714              : {
    1715      2201605 :   greturn *ret;
    1716      2201605 :   tree ret_expr = TREE_OPERAND (stmt, 0);
    1717      2201605 :   tree result_decl, result;
    1718              : 
    1719      2201605 :   if (ret_expr == error_mark_node)
    1720              :     return GS_ERROR;
    1721              : 
    1722      2201599 :   if (!ret_expr
    1723      2114743 :       || TREE_CODE (ret_expr) == RESULT_DECL)
    1724              :     {
    1725       100582 :       maybe_add_early_return_predict_stmt (pre_p);
    1726       100582 :       greturn *ret = gimple_build_return (ret_expr);
    1727       100582 :       copy_warning (ret, stmt);
    1728       100582 :       gimplify_seq_add_stmt (pre_p, ret);
    1729       100582 :       return GS_ALL_DONE;
    1730              :     }
    1731              : 
    1732      2101017 :   if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
    1733              :     result_decl = NULL_TREE;
    1734      2100691 :   else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
    1735              :     {
    1736              :       /* Used in C++ for handling EH cleanup of the return value if a local
    1737              :          cleanup throws.  Assume the front-end knows what it's doing.  */
    1738         4807 :       result_decl = DECL_RESULT (current_function_decl);
    1739              :       /* But crash if we end up trying to modify ret_expr below.  */
    1740         4807 :       ret_expr = NULL_TREE;
    1741              :     }
    1742              :   else
    1743              :     {
    1744      2095884 :       result_decl = TREE_OPERAND (ret_expr, 0);
    1745              : 
    1746              :       /* See through a return by reference.  */
    1747      2095884 :       if (INDIRECT_REF_P (result_decl))
    1748        42340 :         result_decl = TREE_OPERAND (result_decl, 0);
    1749              : 
    1750      2095884 :       gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
    1751              :                    || TREE_CODE (ret_expr) == INIT_EXPR)
    1752              :                   && TREE_CODE (result_decl) == RESULT_DECL);
    1753              :     }
    1754              : 
    1755              :   /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
    1756              :      Recall that aggregate_value_p is FALSE for any aggregate type that is
    1757              :      returned in registers.  If we're returning values in registers, then
    1758              :      we don't want to extend the lifetime of the RESULT_DECL, particularly
    1759              :      across another call.  In addition, for those aggregates for which
    1760              :      hard_function_value generates a PARALLEL, we'll die during normal
    1761              :      expansion of structure assignments; there's special code in expand_return
    1762              :      to handle this case that does not exist in expand_expr.  */
    1763         4807 :   if (!result_decl)
    1764              :     result = NULL_TREE;
    1765      2100691 :   else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
    1766              :     {
    1767       178288 :       if (!poly_int_tree_p (DECL_SIZE (result_decl)))
    1768              :         {
    1769           48 :           if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
    1770            0 :             gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
    1771              :           /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
    1772              :              should be effectively allocated by the caller, i.e. all calls to
    1773              :              this function must be subject to the Return Slot Optimization.  */
    1774           48 :           gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
    1775           48 :           gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
    1776              :         }
    1777              :       result = result_decl;
    1778              :     }
    1779      1922403 :   else if (gimplify_ctxp->return_temp)
    1780              :     result = gimplify_ctxp->return_temp;
    1781              :   else
    1782              :     {
    1783      1433697 :       result = create_tmp_reg (TREE_TYPE (result_decl));
    1784              : 
    1785              :       /* ??? With complex control flow (usually involving abnormal edges),
    1786              :          we can wind up warning about an uninitialized value for this.  Due
    1787              :          to how this variable is constructed and initialized, this is never
    1788              :          true.  Give up and never warn.  */
    1789      1433697 :       suppress_warning (result, OPT_Wuninitialized);
    1790              : 
    1791      1433697 :       gimplify_ctxp->return_temp = result;
    1792              :     }
    1793              : 
    1794              :   /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
    1795              :      Then gimplify the whole thing.  */
    1796      2101017 :   if (result != result_decl)
    1797      1922403 :     TREE_OPERAND (ret_expr, 0) = result;
    1798              : 
    1799      2101017 :   gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
    1800              : 
    1801      2101017 :   maybe_add_early_return_predict_stmt (pre_p);
    1802      2101017 :   ret = gimple_build_return (result);
    1803      2101017 :   copy_warning (ret, stmt);
    1804      2101017 :   gimplify_seq_add_stmt (pre_p, ret);
    1805              : 
    1806      2101017 :   return GS_ALL_DONE;
    1807              : }
    1808              : 
    1809              : /* Gimplify a variable-length array DECL.  */
    1810              : 
    1811              : static void
    1812         8970 : gimplify_vla_decl (tree decl, gimple_seq *seq_p)
    1813              : {
    1814              :   /* This is a variable-sized decl.  Simplify its size and mark it
    1815              :      for deferred expansion.  */
    1816         8970 :   tree t, addr, ptr_type;
    1817              : 
    1818         8970 :   gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
    1819         8970 :   gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
    1820              : 
    1821              :   /* Don't mess with a DECL_VALUE_EXPR set by the front-end.  */
    1822         8970 :   if (DECL_HAS_VALUE_EXPR_P (decl))
    1823              :     return;
    1824              : 
    1825              :   /* All occurrences of this decl in final gimplified code will be
    1826              :      replaced by indirection.  Setting DECL_VALUE_EXPR does two
    1827              :      things: First, it lets the rest of the gimplifier know what
    1828              :      replacement to use.  Second, it lets the debug info know
    1829              :      where to find the value.  */
    1830         8965 :   ptr_type = build_pointer_type (TREE_TYPE (decl));
    1831         8965 :   addr = create_tmp_var (ptr_type, get_name (decl));
    1832         8965 :   DECL_IGNORED_P (addr) = 0;
    1833         8965 :   t = build_fold_indirect_ref (addr);
    1834         8965 :   TREE_THIS_NOTRAP (t) = 1;
    1835         8965 :   SET_DECL_VALUE_EXPR (decl, t);
    1836         8965 :   DECL_HAS_VALUE_EXPR_P (decl) = 1;
    1837              : 
    1838         8965 :   t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
    1839         8965 :                               max_int_size_in_bytes (TREE_TYPE (decl)));
    1840              :   /* The call has been built for a variable-sized object.  */
    1841         8965 :   CALL_ALLOCA_FOR_VAR_P (t) = 1;
    1842         8965 :   t = fold_convert (ptr_type, t);
    1843         8965 :   t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
    1844              : 
    1845         8965 :   gimplify_and_add (t, seq_p);
    1846              : 
    1847              :   /* Record the dynamic allocation associated with DECL if requested.  */
    1848         8965 :   if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
    1849            0 :     record_dynamic_alloc (decl);
    1850              : }
    1851              : 
    1852              : /* A helper function to be called via walk_tree.  Mark all labels under *TP
    1853              :    as being forced.  To be called for DECL_INITIAL of static variables.  */
    1854              : 
    1855              : static tree
    1856       857051 : force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
    1857              : {
    1858       857051 :   if (TYPE_P (*tp))
    1859            0 :     *walk_subtrees = 0;
    1860       857051 :   if (TREE_CODE (*tp) == LABEL_DECL)
    1861              :     {
    1862          926 :       FORCED_LABEL (*tp) = 1;
    1863          926 :       cfun->has_forced_label_in_static = 1;
    1864              :     }
    1865              : 
    1866       857051 :   return NULL_TREE;
    1867              : }
    1868              : 
    1869              : /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
    1870              :    Build a call to internal const function DEFERRED_INIT:
    1871              :    1st argument: SIZE of the DECL;
    1872              :    2nd argument: INIT_TYPE;
    1873              :    3rd argument: NAME of the DECL;
    1874              : 
    1875              :    as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL).  */
    1876              : 
    1877              : static void
    1878       122819 : gimple_add_init_for_auto_var (tree decl,
    1879              :                               enum auto_init_type init_type,
    1880              :                               gimple_seq *seq_p)
    1881              : {
    1882       122819 :   gcc_assert (auto_var_p (decl));
    1883       122819 :   gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
    1884              : 
    1885       122819 :   const location_t loc = DECL_SOURCE_LOCATION (decl);
    1886       122819 :   tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
    1887       122819 :   tree init_type_node = build_int_cst (integer_type_node, (int) init_type);
    1888       122819 :   tree decl_name;
    1889              : 
    1890       122819 :   if (DECL_NAME (decl))
    1891        69231 :     decl_name = build_string_literal (DECL_NAME (decl));
    1892              :   else
    1893              :     {
    1894        53588 :       char decl_name_anonymous[3 + (HOST_BITS_PER_INT + 2) / 3];
    1895        53588 :       sprintf (decl_name_anonymous, "D.%u", DECL_UID (decl));
    1896        53588 :       decl_name = build_string_literal (decl_name_anonymous);
    1897              :     }
    1898              : 
    1899       122819 :   tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT,
    1900       122819 :                                             TREE_TYPE (decl), 3,
    1901              :                                             decl_size, init_type_node,
    1902              :                                             decl_name);
    1903              : 
    1904       122819 :   gimplify_assign (decl, call, seq_p);
    1905       122819 : }
    1906              : 
    1907              : /* Generate padding initialization for automatic variable DECL.
    1908              :    C guarantees that brace-init with fewer initializers than members
    1909              :    aggregate will initialize the rest of the aggregate as-if it were
    1910              :    static initialization.  In turn static initialization guarantees
    1911              :    that padding is initialized to zero. So, we always initialize paddings
    1912              :    to zeroes regardless INIT_TYPE.
    1913              :    To do the padding initialization, we insert a call to
    1914              :    __builtin_clear_padding (&decl, 0, for_auto_init = true).
    1915              :    Note, we add an additional dummy argument for __builtin_clear_padding,
    1916              :    'for_auto_init' to distinguish whether this call is for automatic
    1917              :    variable initialization or not.
    1918              :    */
    1919              : static void
    1920          115 : gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
    1921              :                                       gimple_seq *seq_p)
    1922              : {
    1923          115 :   tree addr_of_decl = NULL_TREE;
    1924          115 :   tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING);
    1925              : 
    1926          115 :   if (is_vla)
    1927              :     {
    1928              :       /* The temporary address variable for this vla should be
    1929              :          created in gimplify_vla_decl.  */
    1930            0 :       gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
    1931            0 :       gcc_assert (INDIRECT_REF_P (DECL_VALUE_EXPR (decl)));
    1932            0 :       addr_of_decl = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
    1933              :     }
    1934              :   else
    1935              :     {
    1936          115 :       mark_addressable (decl);
    1937          115 :       addr_of_decl = build_fold_addr_expr (decl);
    1938              :     }
    1939              : 
    1940          115 :   gimple *call = gimple_build_call (fn, 2, addr_of_decl,
    1941          115 :                                     build_one_cst (TREE_TYPE (addr_of_decl)));
    1942          115 :   gimplify_seq_add_stmt (seq_p, call);
    1943          115 : }
    1944              : 
    1945              : /* Return true if the DECL need to be automatically initialized by the
    1946              :    compiler.  */
    1947              : static bool
    1948      4200813 : var_needs_auto_init_p (tree decl)
    1949              : {
    1950      4200813 :   if (auto_var_p (decl)
    1951      4105808 :       && (TREE_CODE (decl) != VAR_DECL || !DECL_HARD_REGISTER (decl))
    1952      4105100 :       && flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    1953       247727 :       && !lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))
    1954       247719 :       && !lookup_attribute ("indeterminate", DECL_ATTRIBUTES (decl))
    1955       247710 :       && !OPAQUE_TYPE_P (TREE_TYPE (decl))
    1956      4448523 :       && !is_empty_type (TREE_TYPE (decl)))
    1957              :     return true;
    1958              :   return false;
    1959              : }
    1960              : 
    1961              : /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
    1962              :    and initialization explicit.  */
    1963              : 
    1964              : static enum gimplify_status
    1965      6523205 : gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
    1966              : {
    1967      6523205 :   tree stmt = *stmt_p;
    1968      6523205 :   tree decl = DECL_EXPR_DECL (stmt);
    1969              : 
    1970      6523205 :   *stmt_p = NULL_TREE;
    1971              : 
    1972      6523205 :   if (TREE_TYPE (decl) == error_mark_node)
    1973              :     return GS_ERROR;
    1974              : 
    1975      6523127 :   if ((TREE_CODE (decl) == TYPE_DECL
    1976      6479907 :        || VAR_P (decl))
    1977     12999958 :       && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
    1978              :     {
    1979       696590 :       gimplify_type_sizes (TREE_TYPE (decl), seq_p);
    1980       696590 :       if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
    1981        21422 :         gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
    1982              :     }
    1983              : 
    1984              :   /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
    1985              :      in case its size expressions contain problematic nodes like CALL_EXPR.  */
    1986      6523127 :   if (TREE_CODE (decl) == TYPE_DECL
    1987        43220 :       && DECL_ORIGINAL_TYPE (decl)
    1988      6528448 :       && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
    1989              :     {
    1990            0 :       gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
    1991            0 :       if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
    1992            0 :         gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
    1993              :     }
    1994              : 
    1995      6523127 :   if (VAR_P (decl) && !DECL_EXTERNAL (decl))
    1996              :     {
    1997      6476831 :       tree init = DECL_INITIAL (decl);
    1998      6476831 :       bool is_vla = false;
    1999              :       /* Check whether a decl has FE created VALUE_EXPR here BEFORE
    2000              :          gimplify_vla_decl creates VALUE_EXPR for a vla decl.
    2001              :          If the decl has VALUE_EXPR that was created by FE (usually
    2002              :          C++FE), it's a proxy variable, and FE already initialized
    2003              :          the VALUE_EXPR of it, we should not initialize it anymore.  */
    2004      6476831 :       bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl);
    2005              : 
    2006      6476831 :       poly_uint64 size;
    2007      6476831 :       if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
    2008      6476831 :           || (!TREE_STATIC (decl)
    2009      6352454 :               && flag_stack_check == GENERIC_STACK_CHECK
    2010          234 :               && maybe_gt (size,
    2011              :                            (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
    2012              :         {
    2013         8843 :           gimplify_vla_decl (decl, seq_p);
    2014         8843 :           is_vla = true;
    2015              :         }
    2016              : 
    2017      6476831 :       if (asan_poisoned_variables
    2018         5162 :           && !is_vla
    2019         4976 :           && TREE_ADDRESSABLE (decl)
    2020         2441 :           && !TREE_STATIC (decl)
    2021         2231 :           && !DECL_HAS_VALUE_EXPR_P (decl)
    2022         2154 :           && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
    2023         2154 :           && dbg_cnt (asan_use_after_scope)
    2024         2154 :           && !gimplify_omp_ctxp
    2025              :           /* GNAT introduces temporaries to hold return values of calls in
    2026              :              initializers of variables defined in other units, so the
    2027              :              declaration of the variable is discarded completely.  We do not
    2028              :              want to issue poison calls for such dropped variables.  */
    2029      6478977 :           && (DECL_SEEN_IN_BIND_EXPR_P (decl)
    2030            0 :               || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
    2031              :         {
    2032         2146 :           asan_poisoned_variables->add (decl);
    2033         2146 :           asan_poison_variable (decl, false, seq_p);
    2034         2146 :           if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
    2035           55 :             gimplify_ctxp->live_switch_vars->add (decl);
    2036              :         }
    2037              : 
    2038              :       /* Some front ends do not explicitly declare all anonymous
    2039              :          artificial variables.  We compensate here by declaring the
    2040              :          variables, though it would be better if the front ends would
    2041              :          explicitly declare them.  */
    2042      6476831 :       if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
    2043      6476831 :           && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
    2044        15960 :         gimple_add_tmp_var (decl);
    2045              : 
    2046      6476831 :       if (init && init != error_mark_node)
    2047              :         {
    2048      3688754 :           if (!TREE_STATIC (decl))
    2049              :             {
    2050      3659111 :               DECL_INITIAL (decl) = NULL_TREE;
    2051      3659111 :               init = build2 (INIT_EXPR, void_type_node, decl, init);
    2052      3659111 :               gimplify_and_add (init, seq_p);
    2053      3659111 :               ggc_free (init);
    2054              :               /* Clear TREE_READONLY if we really have an initialization.  */
    2055      3659111 :               if (!DECL_INITIAL (decl)
    2056      3659111 :                   && !omp_privatize_by_reference (decl))
    2057      3640962 :                 TREE_READONLY (decl) = 0;
    2058              :             }
    2059              :           else
    2060              :             /* We must still examine initializers for static variables
    2061              :                as they may contain a label address.  */
    2062        29643 :             walk_tree (&init, force_labels_r, NULL, NULL);
    2063              :         }
    2064              :       /* When there is no explicit initializer, if the user requested,
    2065              :          We should insert an artificial initializer for this automatic
    2066              :          variable.  */
    2067      2788077 :       else if (var_needs_auto_init_p (decl)
    2068      2788077 :                && !decl_had_value_expr_p)
    2069              :         {
    2070        74948 :           gimple_add_init_for_auto_var (decl,
    2071              :                                         flag_auto_var_init,
    2072              :                                         seq_p);
    2073              :           /* The expanding of a call to the above .DEFERRED_INIT will apply
    2074              :              block initialization to the whole space covered by this variable.
    2075              :              As a result, all the paddings will be initialized to zeroes
    2076              :              for zero initialization and 0xFE byte-repeatable patterns for
    2077              :              pattern initialization.
    2078              :              In order to make the paddings as zeroes for pattern init, We
    2079              :              should add a call to __builtin_clear_padding to clear the
    2080              :              paddings to zero in compatible with CLANG.
    2081              :              We cannot insert this call if the variable is a gimple register
    2082              :              since __builtin_clear_padding will take the address of the
    2083              :              variable.  As a result, if a long double/_Complex long double
    2084              :              variable will spilled into stack later, its padding is 0XFE.  */
    2085        74948 :           if (flag_auto_var_init == AUTO_INIT_PATTERN
    2086          183 :               && !is_gimple_reg (decl)
    2087        75045 :               && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)))
    2088           74 :             gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
    2089              :         }
    2090              :     }
    2091              : 
    2092              :   return GS_ALL_DONE;
    2093              : }
    2094              : 
    2095              : /* Gimplify a LOOP_EXPR.  Normally this just involves gimplifying the body
    2096              :    and replacing the LOOP_EXPR with goto, but if the loop contains an
    2097              :    EXIT_EXPR, we need to append a label for it to jump to.  */
    2098              : 
    2099              : static enum gimplify_status
    2100       203308 : gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
    2101              : {
    2102       203308 :   tree saved_label = gimplify_ctxp->exit_label;
    2103       203308 :   tree start_label = create_artificial_label (UNKNOWN_LOCATION);
    2104              : 
    2105       203308 :   gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
    2106              : 
    2107       203308 :   gimplify_ctxp->exit_label = NULL_TREE;
    2108              : 
    2109       203308 :   gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
    2110              : 
    2111       203308 :   gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
    2112              : 
    2113       203308 :   if (gimplify_ctxp->exit_label)
    2114         6132 :     gimplify_seq_add_stmt (pre_p,
    2115         3066 :                            gimple_build_label (gimplify_ctxp->exit_label));
    2116              : 
    2117       203308 :   gimplify_ctxp->exit_label = saved_label;
    2118              : 
    2119       203308 :   *expr_p = NULL;
    2120       203308 :   return GS_ALL_DONE;
    2121              : }
    2122              : 
    2123              : /* Gimplify a statement list onto a sequence.  These may be created either
    2124              :    by an enlightened front-end, or by shortcut_cond_expr.  */
    2125              : 
    2126              : static enum gimplify_status
    2127      8453338 : gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
    2128              : {
    2129      8453338 :   tree temp = voidify_wrapper_expr (*expr_p, NULL);
    2130              : 
    2131      8453338 :   tree_stmt_iterator i = tsi_start (*expr_p);
    2132              : 
    2133     54597535 :   while (!tsi_end_p (i))
    2134              :     {
    2135     37690859 :       gimplify_stmt (tsi_stmt_ptr (i), pre_p);
    2136     37690859 :       tsi_delink (&i);
    2137              :     }
    2138              : 
    2139      8453338 :   if (temp)
    2140              :     {
    2141        14759 :       *expr_p = temp;
    2142        14759 :       return GS_OK;
    2143              :     }
    2144              : 
    2145              :   return GS_ALL_DONE;
    2146              : }
    2147              : 
    2148              : 
    2149              : /* Emit warning for the unreachable statement STMT if needed.
    2150              :    Return the gimple itself when the warning is emitted, otherwise
    2151              :    return NULL.  */
    2152              : static gimple *
    2153          181 : emit_warn_switch_unreachable (gimple *stmt)
    2154              : {
    2155          181 :   if (gimple_code (stmt) == GIMPLE_GOTO
    2156           50 :       && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
    2157          231 :       && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
    2158              :   /* Don't warn for compiler-generated gotos.  These occur
    2159              :      in Duff's devices, for example.  */
    2160              :     return NULL;
    2161              :   else
    2162          131 :     warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
    2163              :                 "statement will never be executed");
    2164          131 :   return stmt;
    2165              : }
    2166              : 
    2167              : /* Callback for walk_gimple_seq.  */
    2168              : 
    2169              : static tree
    2170        48451 : warn_switch_unreachable_and_auto_init_r (gimple_stmt_iterator *gsi_p,
    2171              :                                          bool *handled_ops_p,
    2172              :                                          struct walk_stmt_info *wi)
    2173              : {
    2174        48451 :   gimple *stmt = gsi_stmt (*gsi_p);
    2175        48451 :   bool unreachable_issued = wi->info != NULL;
    2176              : 
    2177        48451 :   *handled_ops_p = true;
    2178        48451 :   switch (gimple_code (stmt))
    2179              :     {
    2180          155 :     case GIMPLE_TRY:
    2181              :       /* A compiler-generated cleanup or a user-written try block.
    2182              :          If it's empty, don't dive into it--that would result in
    2183              :          worse location info.  */
    2184          155 :       if (gimple_try_eval (stmt) == NULL)
    2185              :         {
    2186            3 :           if (warn_switch_unreachable && !unreachable_issued)
    2187            3 :             wi->info = emit_warn_switch_unreachable (stmt);
    2188              : 
    2189              :           /* Stop when auto var init warning is not on.  */
    2190            3 :           if (!warn_trivial_auto_var_init)
    2191            3 :             return integer_zero_node;
    2192              :         }
    2193              :       /* Fall through.  */
    2194         1796 :     case GIMPLE_BIND:
    2195         1796 :     case GIMPLE_CATCH:
    2196         1796 :     case GIMPLE_EH_FILTER:
    2197         1796 :     case GIMPLE_TRANSACTION:
    2198              :       /* Walk the sub-statements.  */
    2199         1796 :       *handled_ops_p = false;
    2200         1796 :       break;
    2201              : 
    2202              :     case GIMPLE_DEBUG:
    2203              :       /* Ignore these.  We may generate them before declarations that
    2204              :          are never executed.  If there's something to warn about,
    2205              :          there will be non-debug stmts too, and we'll catch those.  */
    2206              :       break;
    2207              : 
    2208           60 :     case GIMPLE_ASSIGN:
    2209              :       /* See comment below in the GIMPLE_CALL case.  */
    2210           60 :       if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2211           20 :           && gimple_assign_single_p (stmt)
    2212           79 :           && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
    2213              :         {
    2214            6 :           gimple *g = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
    2215            6 :           if (gimple_call_internal_p (g, IFN_DEFERRED_INIT))
    2216              :             break;
    2217              :         }
    2218           54 :       goto do_default;
    2219              : 
    2220        45450 :     case GIMPLE_LABEL:
    2221              :       /* Stop till the first Label.  */
    2222        45450 :       return integer_zero_node;
    2223           62 :     case GIMPLE_CALL:
    2224           62 :       if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
    2225              :         {
    2226            8 :           *handled_ops_p = false;
    2227            8 :           break;
    2228              :         }
    2229              :       /* Don't warn for compiler-generated initializations for
    2230              :          -ftrivial-auto-var-init for -Wswitch-unreachable.  Though
    2231              :          do warn for -Wtrivial-auto-var-init.
    2232              :          There are 3 cases:
    2233              :          case 1: a call to .DEFERRED_INIT;
    2234              :          case 2: a call to __builtin_clear_padding with the 2nd argument is
    2235              :                  present and non-zero;
    2236              :          case 3: a gimple assign store right after the call to .DEFERRED_INIT
    2237              :                  that has the LHS of .DEFERRED_INIT as the RHS as following:
    2238              :                   _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
    2239              :                   i1 = _1.
    2240              :          case 3 is handled above in the GIMPLE_ASSIGN case.  */
    2241           54 :       if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2242           54 :           && gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
    2243              :         {
    2244           33 :           if (warn_trivial_auto_var_init)
    2245              :             {
    2246              :               /* Get the variable name from the 3rd argument of call.  */
    2247           12 :               tree var_name = gimple_call_arg (stmt, 2);
    2248           12 :               var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
    2249           12 :               const char *var_name_str = TREE_STRING_POINTER (var_name);
    2250              : 
    2251           12 :               warning_at (gimple_location (stmt), OPT_Wtrivial_auto_var_init,
    2252              :                           "%qs cannot be initialized with "
    2253              :                           "%<-ftrivial-auto-var_init%>", var_name_str);
    2254              :             }
    2255              :           break;
    2256              :        }
    2257           21 :       if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2258            7 :           && gimple_call_builtin_p (stmt, BUILT_IN_CLEAR_PADDING)
    2259           24 :           && (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1)))
    2260              :         break;
    2261              :       /* Fall through.  */
    2262          178 :     default:
    2263          178 :     do_default:
    2264              :       /* check the first "real" statement (not a decl/lexical scope/...), issue
    2265              :          warning if needed.  */
    2266          178 :       if (warn_switch_unreachable && !unreachable_issued)
    2267          178 :         wi->info = emit_warn_switch_unreachable (stmt);
    2268              :       /* Stop when auto var init warning is not on.  */
    2269          178 :       if (!warn_trivial_auto_var_init)
    2270          178 :         return integer_zero_node;
    2271              :       break;
    2272              :     }
    2273              :   return NULL_TREE;
    2274              : }
    2275              : 
    2276              : 
    2277              : /* Possibly warn about unreachable statements between switch's controlling
    2278              :    expression and the first case.  Also warn about -ftrivial-auto-var-init
    2279              :    cannot initialize the auto variable under such situation.
    2280              :    SEQ is the body of a switch expression.  */
    2281              : 
    2282              : static void
    2283        49515 : maybe_warn_switch_unreachable_and_auto_init (gimple_seq seq)
    2284              : {
    2285           60 :   if ((!warn_switch_unreachable && !warn_trivial_auto_var_init)
    2286              :       /* This warning doesn't play well with Fortran when optimizations
    2287              :          are on.  */
    2288        49455 :       || lang_GNU_Fortran ()
    2289        95320 :       || seq == NULL)
    2290         3881 :     return;
    2291              : 
    2292        45634 :   struct walk_stmt_info wi;
    2293              : 
    2294        45634 :   memset (&wi, 0, sizeof (wi));
    2295        45634 :   walk_gimple_seq (seq, warn_switch_unreachable_and_auto_init_r, NULL, &wi);
    2296              : }
    2297              : 
    2298              : 
    2299              : /* A label entry that pairs label and a location.  */
    2300              : struct label_entry
    2301              : {
    2302              :   tree label;
    2303              :   location_t loc;
    2304              : };
    2305              : 
    2306              : /* Find LABEL in vector of label entries VEC.  */
    2307              : 
    2308              : static struct label_entry *
    2309        12198 : find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
    2310              : {
    2311        12198 :   unsigned int i;
    2312        12198 :   struct label_entry *l;
    2313              : 
    2314        23346 :   FOR_EACH_VEC_ELT (*vec, i, l)
    2315        19988 :     if (l->label == label)
    2316              :       return l;
    2317              :   return NULL;
    2318              : }
    2319              : 
    2320              : /* Return true if LABEL, a LABEL_DECL, represents a case label
    2321              :    in a vector of labels CASES.  */
    2322              : 
    2323              : static bool
    2324        16405 : case_label_p (const vec<tree> *cases, tree label)
    2325              : {
    2326        16405 :   unsigned int i;
    2327        16405 :   tree l;
    2328              : 
    2329       164574 :   FOR_EACH_VEC_ELT (*cases, i, l)
    2330       164240 :     if (CASE_LABEL (l) == label)
    2331              :       return true;
    2332              :   return false;
    2333              : }
    2334              : 
    2335              : /* Find the last nondebug statement in a scope STMT.  */
    2336              : 
    2337              : static gimple *
    2338         2265 : last_stmt_in_scope (gimple *stmt)
    2339              : {
    2340         4200 :   if (!stmt)
    2341              :     return NULL;
    2342              : 
    2343         6838 :   auto last_stmt_in_seq = [] (gimple_seq s) 
    2344              :     {
    2345         2649 :       gimple_seq_node n;
    2346         2649 :       for (n = gimple_seq_last (s);
    2347         2654 :            n && (is_gimple_debug (n)
    2348         2641 :                  || (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2349          110 :                      && gimple_call_internal_p (n, IFN_DEFERRED_INIT)));
    2350            5 :         n = n->prev)
    2351            7 :       if (n == s)
    2352              :         return (gimple *) NULL;
    2353              :       return (gimple *) n;
    2354              :     };
    2355              : 
    2356         4189 :   switch (gimple_code (stmt))
    2357              :     {
    2358         1387 :     case GIMPLE_BIND:
    2359         1387 :       {
    2360         1387 :         gbind *bind = as_a <gbind *> (stmt);
    2361         1387 :         stmt = last_stmt_in_seq (gimple_bind_body (bind));
    2362         1387 :         return last_stmt_in_scope (stmt);
    2363              :       }
    2364              : 
    2365          714 :     case GIMPLE_TRY:
    2366          714 :       {
    2367          714 :         gtry *try_stmt = as_a <gtry *> (stmt);
    2368          714 :         stmt = last_stmt_in_seq (gimple_try_eval (try_stmt));
    2369          714 :         gimple *last_eval = last_stmt_in_scope (stmt);
    2370          714 :         if (gimple_stmt_may_fallthru (last_eval)
    2371          567 :             && (last_eval == NULL
    2372          564 :                 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
    2373         1274 :             && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
    2374              :           {
    2375          548 :             stmt = last_stmt_in_seq (gimple_try_cleanup (try_stmt));
    2376          548 :             return last_stmt_in_scope (stmt);
    2377              :           }
    2378              :         else
    2379              :           return last_eval;
    2380              :       }
    2381              : 
    2382            0 :     case GIMPLE_DEBUG:
    2383            0 :       gcc_unreachable ();
    2384              : 
    2385              :     default:
    2386              :       return stmt;
    2387              :     }
    2388              : }
    2389              : 
    2390              : /* Collect labels that may fall through into LABELS and return the statement
    2391              :    preceding another case label, or a user-defined label.  Store a location
    2392              :    useful to give warnings at *PREVLOC (usually the location of the returned
    2393              :    statement or of its surrounding scope).  */
    2394              : 
    2395              : static gimple *
    2396        20996 : collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
    2397              :                             auto_vec <struct label_entry> *labels,
    2398              :                             location_t *prevloc)
    2399              : {
    2400        20996 :   gimple *prev = NULL;
    2401              : 
    2402        20996 :   *prevloc = UNKNOWN_LOCATION;
    2403       101593 :   do
    2404              :     {
    2405       101593 :       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
    2406              :         {
    2407              :           /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
    2408              :              which starts on a GIMPLE_SWITCH and ends with a break label.
    2409              :              Handle that as a single statement that can fall through.  */
    2410         1448 :           gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
    2411         1448 :           gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
    2412         1448 :           gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
    2413         1442 :           if (last
    2414         1442 :               && gimple_code (first) == GIMPLE_SWITCH
    2415         1544 :               && gimple_code (last) == GIMPLE_LABEL)
    2416              :             {
    2417          102 :               tree label = gimple_label_label (as_a <glabel *> (last));
    2418          102 :               if (SWITCH_BREAK_LABEL_P (label))
    2419              :                 {
    2420          102 :                   prev = bind;
    2421          102 :                   gsi_next (gsi_p);
    2422          102 :                   continue;
    2423              :                 }
    2424              :             }
    2425              :         }
    2426       101491 :       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
    2427       101491 :           || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
    2428              :         {
    2429              :           /* Nested scope.  Only look at the last statement of
    2430              :              the innermost scope.  */
    2431         1551 :           location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
    2432         1551 :           gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
    2433         1551 :           if (last)
    2434              :             {
    2435         1543 :               prev = last;
    2436              :               /* It might be a label without a location.  Use the
    2437              :                  location of the scope then.  */
    2438         1543 :               if (!gimple_has_location (prev))
    2439          671 :                 *prevloc = bind_loc;
    2440              :             }
    2441         1551 :           gsi_next (gsi_p);
    2442         1551 :           continue;
    2443         1551 :         }
    2444              : 
    2445              :       /* Ifs are tricky.  */
    2446        99940 :       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
    2447              :         {
    2448         7176 :           gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
    2449         7176 :           tree false_lab = gimple_cond_false_label (cond_stmt);
    2450         7176 :           location_t if_loc = gimple_location (cond_stmt);
    2451              : 
    2452              :           /* If we have e.g.
    2453              :                if (i > 1) goto <D.2259>; else goto D;
    2454              :              we can't do much with the else-branch.  */
    2455         7176 :           if (!DECL_ARTIFICIAL (false_lab))
    2456              :             break;
    2457              : 
    2458              :           /* Go on until the false label, then one step back.  */
    2459        54654 :           for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
    2460              :             {
    2461        54654 :               gimple *stmt = gsi_stmt (*gsi_p);
    2462        54654 :               if (gimple_code (stmt) == GIMPLE_LABEL
    2463        54654 :                   && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
    2464              :                 break;
    2465              :             }
    2466              : 
    2467              :           /* Not found?  Oops.  */
    2468         7176 :           if (gsi_end_p (*gsi_p))
    2469              :             break;
    2470              : 
    2471              :           /* A dead label can't fall through.  */
    2472         7176 :           if (!UNUSED_LABEL_P (false_lab))
    2473              :             {
    2474         7129 :               struct label_entry l = { false_lab, if_loc };
    2475         7129 :               labels->safe_push (l);
    2476              :             }
    2477              : 
    2478              :           /* Go to the last statement of the then branch.  */
    2479         7176 :           gsi_prev (gsi_p);
    2480              : 
    2481              :           /* if (i != 0) goto <D.1759>; else goto <D.1760>;
    2482              :              <D.1759>:
    2483              :              <stmt>;
    2484              :              goto <D.1761>;
    2485              :              <D.1760>:
    2486              :            */
    2487         7176 :           if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
    2488         7176 :               && !gimple_has_location (gsi_stmt (*gsi_p)))
    2489              :             {
    2490              :               /* Look at the statement before, it might be
    2491              :                  attribute fallthrough, in which case don't warn.  */
    2492         1570 :               gsi_prev (gsi_p);
    2493         1570 :               bool fallthru_before_dest
    2494         1570 :                 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
    2495         1570 :               gsi_next (gsi_p);
    2496         1570 :               tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
    2497         1570 :               if (!fallthru_before_dest)
    2498              :                 {
    2499         1513 :                   struct label_entry l = { goto_dest, if_loc };
    2500         1513 :                   labels->safe_push (l);
    2501              :                 }
    2502              :             }
    2503              :           /* This case is about
    2504              :               if (1 != 0) goto <D.2022>; else goto <D.2023>;
    2505              :               <D.2022>:
    2506              :               n = n + 1; // #1
    2507              :               <D.2023>:  // #2
    2508              :               <D.1988>:  // #3
    2509              :              where #2 is UNUSED_LABEL_P and we want to warn about #1 falling
    2510              :              through to #3.  So set PREV to #1.  */
    2511         5606 :           else if (UNUSED_LABEL_P (false_lab))
    2512           47 :             prev = gsi_stmt (*gsi_p);
    2513              : 
    2514              :           /* And move back.  */
    2515         7176 :           gsi_next (gsi_p);
    2516              :         }
    2517              : 
    2518        99940 :       tree lab;
    2519              :       /* Remember the last statement.  Skip labels that are of no interest
    2520              :          to us.  */
    2521        99940 :       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
    2522              :         {
    2523        11980 :           tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
    2524        11980 :           if (find_label_entry (labels, label))
    2525        75114 :             prev = gsi_stmt (*gsi_p);
    2526              :         }
    2527        87960 :       else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
    2528              :         ;
    2529        87960 :       else if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2530        87960 :                && gimple_call_internal_p (gsi_stmt (*gsi_p),
    2531              :                                           IFN_DEFERRED_INIT))
    2532              :         ;
    2533        87960 :       else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
    2534              :         ;
    2535        86736 :       else if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2536         2136 :                && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
    2537          316 :                && (lab = gimple_goto_dest (gsi_stmt (*gsi_p)))
    2538          316 :                && TREE_CODE (lab) == LABEL_DECL
    2539        87051 :                && VACUOUS_INIT_LABEL_P (lab))
    2540              :         ;
    2541        86736 :       else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
    2542        75114 :         prev = gsi_stmt (*gsi_p);
    2543        99940 :       gsi_next (gsi_p);
    2544              :     }
    2545       101593 :   while (!gsi_end_p (*gsi_p)
    2546              :          /* Stop if we find a case or a user-defined label.  */
    2547       203186 :          && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
    2548        21729 :              || !gimple_has_location (gsi_stmt (*gsi_p))));
    2549              : 
    2550        20996 :   if (prev && gimple_has_location (prev))
    2551        20551 :     *prevloc = gimple_location (prev);
    2552        20996 :   return prev;
    2553              : }
    2554              : 
    2555              : /* Return true if the switch fallthrough warning should occur.  LABEL is
    2556              :    the label statement that we're falling through to.  */
    2557              : 
    2558              : static bool
    2559        16918 : should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
    2560              : {
    2561        16918 :   gimple_stmt_iterator gsi = *gsi_p;
    2562              : 
    2563              :   /* Don't warn if the label is marked with a "falls through" comment.  */
    2564        16918 :   if (FALLTHROUGH_LABEL_P (label))
    2565              :     return false;
    2566              : 
    2567              :   /* Don't warn for non-case labels followed by a statement:
    2568              :        case 0:
    2569              :          foo ();
    2570              :        label:
    2571              :          bar ();
    2572              :      as these are likely intentional.  */
    2573        16146 :   if (!case_label_p (&gimplify_ctxp->case_labels, label))
    2574              :     {
    2575              :       tree l;
    2576          334 :       while (!gsi_end_p (gsi)
    2577          334 :              && ((gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
    2578          259 :                   && (l
    2579          259 :                       = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
    2580          259 :                   && !case_label_p (&gimplify_ctxp->case_labels, l))
    2581          153 :                  || (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2582           31 :                      && gimple_call_internal_p (gsi_stmt (gsi),
    2583              :                                                 IFN_DEFERRED_INIT))))
    2584          173 :         gsi_next_nondebug (&gsi);
    2585          161 :       if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
    2586              :         return false;
    2587              :     }
    2588              : 
    2589              :   /* Don't warn for terminated branches, i.e. when the subsequent case labels
    2590              :      immediately breaks.  */
    2591        16071 :   gsi = *gsi_p;
    2592              : 
    2593              :   /* Skip all immediately following labels.  */
    2594        35694 :   while (!gsi_end_p (gsi)
    2595        35694 :          && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
    2596        16214 :              || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT
    2597        16005 :              || (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2598          734 :                  && gimple_call_internal_p (gsi_stmt (gsi),
    2599              :                                             IFN_DEFERRED_INIT))))
    2600        19623 :     gsi_next_nondebug (&gsi);
    2601              : 
    2602              :   /* { ... something; default:; } */
    2603        16071 :   if (gsi_end_p (gsi)
    2604              :       /* { ... something; default: break; } or
    2605              :          { ... something; default: goto L; } */
    2606        16005 :       || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
    2607              :       /* { ... something; default: return; } */
    2608        30977 :       || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
    2609              :     return false;
    2610              : 
    2611              :   return true;
    2612              : }
    2613              : 
    2614              : /* Callback for walk_gimple_seq.  */
    2615              : 
    2616              : static tree
    2617        21956 : warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
    2618              :                              struct walk_stmt_info *)
    2619              : {
    2620        21956 :   gimple *stmt = gsi_stmt (*gsi_p);
    2621              : 
    2622        21956 :   *handled_ops_p = true;
    2623        21956 :   switch (gimple_code (stmt))
    2624              :     {
    2625          267 :     case GIMPLE_TRY:
    2626          267 :     case GIMPLE_BIND:
    2627          267 :     case GIMPLE_CATCH:
    2628          267 :     case GIMPLE_EH_FILTER:
    2629          267 :     case GIMPLE_TRANSACTION:
    2630              :       /* Walk the sub-statements.  */
    2631          267 :       *handled_ops_p = false;
    2632          267 :       break;
    2633              : 
    2634              :     /* Find a sequence of form:
    2635              : 
    2636              :        GIMPLE_LABEL
    2637              :        [...]
    2638              :        <may fallthru stmt>
    2639              :        GIMPLE_LABEL
    2640              : 
    2641              :        and possibly warn.  */
    2642              :     case GIMPLE_LABEL:
    2643              :       {
    2644              :         /* Found a label.  Skip all immediately following labels.  */
    2645        49227 :         while (!gsi_end_p (*gsi_p)
    2646        49227 :                && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
    2647        27997 :           gsi_next_nondebug (gsi_p);
    2648              : 
    2649              :         /* There might be no more statements.  */
    2650        21230 :         if (gsi_end_p (*gsi_p))
    2651         4305 :           return integer_zero_node;
    2652              : 
    2653              :         /* Vector of labels that fall through.  */
    2654        20996 :         auto_vec <struct label_entry> labels;
    2655        20996 :         location_t prevloc;
    2656        20996 :         gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
    2657              : 
    2658              :         /* There might be no more statements.  */
    2659        20996 :         if (gsi_end_p (*gsi_p))
    2660         4071 :           return integer_zero_node;
    2661              : 
    2662        16925 :         gimple *next = gsi_stmt (*gsi_p);
    2663        16925 :         tree label;
    2664              :         /* If what follows is a label, then we may have a fallthrough.  */
    2665        16925 :         if (gimple_code (next) == GIMPLE_LABEL
    2666        16925 :             && gimple_has_location (next)
    2667        16925 :             && (label = gimple_label_label (as_a <glabel *> (next)))
    2668        33850 :             && prev != NULL)
    2669              :           {
    2670        16918 :             struct label_entry *l;
    2671        16918 :             bool warned_p = false;
    2672        16918 :             auto_diagnostic_group d;
    2673        16918 :             if (!should_warn_for_implicit_fallthrough (gsi_p, label))
    2674              :               /* Quiet.  */;
    2675        14879 :             else if (gimple_code (prev) == GIMPLE_LABEL
    2676          218 :                      && (label = gimple_label_label (as_a <glabel *> (prev)))
    2677        15097 :                      && (l = find_label_entry (&labels, label)))
    2678          198 :               warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
    2679              :                                      "this statement may fall through");
    2680        14681 :             else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
    2681              :                      /* Try to be clever and don't warn when the statement
    2682              :                         can't actually fall through.  */
    2683        14145 :                      && gimple_stmt_may_fallthru (prev)
    2684        14982 :                      && prevloc != UNKNOWN_LOCATION)
    2685          301 :               warned_p = warning_at (prevloc,
    2686          301 :                                      OPT_Wimplicit_fallthrough_,
    2687              :                                      "this statement may fall through");
    2688          499 :             if (warned_p)
    2689          499 :               inform (gimple_location (next), "here");
    2690              : 
    2691              :             /* Mark this label as processed so as to prevent multiple
    2692              :                warnings in nested switches.  */
    2693        16918 :             FALLTHROUGH_LABEL_P (label) = true;
    2694              : 
    2695              :             /* So that next warn_implicit_fallthrough_r will start looking for
    2696              :                a new sequence starting with this label.  */
    2697        16918 :             gsi_prev (gsi_p);
    2698        16918 :           }
    2699         4071 :       }
    2700        16925 :       break;
    2701              :    default:
    2702              :       break;
    2703              :     }
    2704              :   return NULL_TREE;
    2705              : }
    2706              : 
    2707              : /* Warn when a switch case falls through.  */
    2708              : 
    2709              : static void
    2710        49515 : maybe_warn_implicit_fallthrough (gimple_seq seq)
    2711              : {
    2712        49515 :   if (!warn_implicit_fallthrough)
    2713        45351 :     return;
    2714              : 
    2715              :   /* This warning is meant for C/C++/ObjC/ObjC++ only.  */
    2716         4164 :   if (!(lang_GNU_C ()
    2717         1228 :         || lang_GNU_CXX ()
    2718            0 :         || lang_GNU_OBJC ()))
    2719              :     return;
    2720              : 
    2721         4164 :   struct walk_stmt_info wi;
    2722         4164 :   memset (&wi, 0, sizeof (wi));
    2723         4164 :   walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
    2724              : }
    2725              : 
    2726              : /* Callback for walk_gimple_seq.  */
    2727              : 
    2728              : static tree
    2729      3210636 : expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
    2730              :                       struct walk_stmt_info *wi)
    2731              : {
    2732      3210636 :   gimple *stmt = gsi_stmt (*gsi_p);
    2733              : 
    2734      3210636 :   *handled_ops_p = true;
    2735      3210636 :   switch (gimple_code (stmt))
    2736              :     {
    2737       146890 :     case GIMPLE_TRY:
    2738       146890 :     case GIMPLE_BIND:
    2739       146890 :     case GIMPLE_CATCH:
    2740       146890 :     case GIMPLE_EH_FILTER:
    2741       146890 :     case GIMPLE_TRANSACTION:
    2742              :       /* Walk the sub-statements.  */
    2743       146890 :       *handled_ops_p = false;
    2744       146890 :       break;
    2745       246718 :     case GIMPLE_CALL:
    2746       246718 :       static_cast<location_t *>(wi->info)[0] = UNKNOWN_LOCATION;
    2747       246718 :       if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
    2748              :         {
    2749         2563 :           location_t loc = gimple_location (stmt);
    2750         2563 :           gsi_remove (gsi_p, true);
    2751         2563 :           wi->removed_stmt = true;
    2752              : 
    2753              :           /* nothrow flag is added by genericize_c_loop to mark fallthrough
    2754              :              statement at the end of some loop's body.  Those should be
    2755              :              always diagnosed, either because they indeed don't precede
    2756              :              a case label or default label, or because the next statement
    2757              :              is not within the same iteration statement.  */
    2758         2563 :           if ((stmt->subcode & GF_CALL_NOTHROW) != 0)
    2759              :             {
    2760           12 :               pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
    2761              :                                "a case label or default label");
    2762           12 :               break;
    2763              :             }
    2764              : 
    2765         2551 :           if (gsi_end_p (*gsi_p))
    2766              :             {
    2767           32 :               static_cast<location_t *>(wi->info)[0] = BUILTINS_LOCATION;
    2768           32 :               static_cast<location_t *>(wi->info)[1] = loc;
    2769           32 :               break;
    2770              :             }
    2771              : 
    2772         2519 :           bool found = false;
    2773              : 
    2774         2519 :           gimple_stmt_iterator gsi2 = *gsi_p;
    2775         2519 :           stmt = gsi_stmt (gsi2);
    2776         2519 :           tree lab;
    2777         2519 :           if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2778          934 :               && gimple_code (stmt) == GIMPLE_GOTO
    2779           20 :               && (lab = gimple_goto_dest (stmt))
    2780           20 :               && TREE_CODE (lab) == LABEL_DECL
    2781         2539 :               && VACUOUS_INIT_LABEL_P (lab))
    2782              :             {
    2783              :               /* Handle for C++ artificial -ftrivial-auto-var-init=
    2784              :                  sequences.  Those look like:
    2785              :                  goto lab1;
    2786              :                  lab2:;
    2787              :                  v1 = .DEFERRED_INIT (...);
    2788              :                  v2 = .DEFERRED_INIT (...);
    2789              :                  lab3:;
    2790              :                  v3 = .DEFERRED_INIT (...);
    2791              :                  lab1:;
    2792              :                  In this case, a case/default label can be either in between
    2793              :                  the GIMPLE_GOTO and the corresponding GIMPLE_LABEL, if jumps
    2794              :                  from the switch condition to the case/default label cross
    2795              :                  vacuous initialization of some variables, or after the
    2796              :                  corresponding GIMPLE_LABEL, if those jumps don't cross
    2797              :                  any such initialization but there is an adjacent named label
    2798              :                  which crosses such initialization.  So, for the purpose of
    2799              :                  this function, just ignore the goto but until reaching the
    2800              :                  corresponding GIMPLE_LABEL allow also .DEFERRED_INIT
    2801              :                  calls.  */
    2802            5 :               gsi_next (&gsi2);
    2803              :             }
    2804         2514 :           else if (gimple_code (stmt) == GIMPLE_GOTO
    2805         2514 :                    && !gimple_has_location (stmt))
    2806              :             {
    2807              :               /* Go on until the artificial label.  */
    2808           57 :               tree goto_dest = gimple_goto_dest (stmt);
    2809          414 :               for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
    2810              :                 {
    2811          357 :                   if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
    2812          357 :                       && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
    2813              :                            == goto_dest)
    2814              :                     break;
    2815              :                 }
    2816              : 
    2817              :               /* Not found?  Stop.  */
    2818           57 :               if (gsi_end_p (gsi2))
    2819              :                 break;
    2820              : 
    2821              :               /* Look one past it.  */
    2822           57 :               gsi_next (&gsi2);
    2823              :             }
    2824              : 
    2825              :           /* We're looking for a case label or default label here.  */
    2826         2617 :           while (!gsi_end_p (gsi2))
    2827              :             {
    2828         2617 :               stmt = gsi_stmt (gsi2);
    2829         2617 :               if (gimple_code (stmt) == GIMPLE_LABEL)
    2830              :                 {
    2831         2574 :                   tree label = gimple_label_label (as_a <glabel *> (stmt));
    2832         2574 :                   if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
    2833              :                     {
    2834              :                       found = true;
    2835              :                       break;
    2836              :                     }
    2837              :                 }
    2838           43 :               else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
    2839              :                 ;
    2840           43 :               else if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2841           43 :                        && gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
    2842              :                 ;
    2843           43 :               else if (!is_gimple_debug (stmt))
    2844              :                 /* Anything else is not expected.  */
    2845              :                 break;
    2846           98 :               gsi_next (&gsi2);
    2847              :             }
    2848         2519 :           if (!found)
    2849           23 :             pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
    2850              :                      "a case label or default label");
    2851              :         }
    2852              :       break;
    2853      2817028 :     default:
    2854      2817028 :       static_cast<location_t *>(wi->info)[0] = UNKNOWN_LOCATION;
    2855      2817028 :       break;
    2856              :     }
    2857      3210636 :   return NULL_TREE;
    2858              : }
    2859              : 
    2860              : /* Expand all FALLTHROUGH () calls in SEQ.  */
    2861              : 
    2862              : static void
    2863        47829 : expand_FALLTHROUGH (gimple_seq *seq_p)
    2864              : {
    2865        47829 :   auto_urlify_attributes sentinel;
    2866              : 
    2867        47829 :   struct walk_stmt_info wi;
    2868        47829 :   location_t loc[2];
    2869        47829 :   memset (&wi, 0, sizeof (wi));
    2870        47829 :   loc[0] = UNKNOWN_LOCATION;
    2871        47829 :   loc[1] = UNKNOWN_LOCATION;
    2872        47829 :   wi.info = (void *) &loc[0];
    2873        47829 :   walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
    2874        47829 :   if (loc[0] != UNKNOWN_LOCATION)
    2875              :     /* We've found [[fallthrough]]; at the end of a switch, which the C++
    2876              :        standard says is ill-formed; see [dcl.attr.fallthrough].  */
    2877            8 :     pedwarn (loc[1], 0, "attribute %<fallthrough%> not preceding "
    2878              :              "a case label or default label");
    2879        47829 : }
    2880              : 
    2881              : 
    2882              : /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
    2883              :    branch to.  */
    2884              : 
    2885              : static enum gimplify_status
    2886        49515 : gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
    2887              : {
    2888        49515 :   tree switch_expr = *expr_p;
    2889        49515 :   gimple_seq switch_body_seq = NULL;
    2890        49515 :   enum gimplify_status ret;
    2891        49515 :   tree index_type = TREE_TYPE (switch_expr);
    2892        49515 :   if (index_type == NULL_TREE)
    2893        11396 :     index_type = TREE_TYPE (SWITCH_COND (switch_expr));
    2894              : 
    2895        49515 :   ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
    2896              :                        fb_rvalue);
    2897        49515 :   if (ret == GS_ERROR || ret == GS_UNHANDLED)
    2898              :     return ret;
    2899              : 
    2900        49515 :   if (SWITCH_BODY (switch_expr))
    2901              :     {
    2902        49515 :       vec<tree> labels;
    2903        49515 :       vec<tree> saved_labels;
    2904        49515 :       hash_set<tree> *saved_live_switch_vars = NULL;
    2905        49515 :       tree default_case = NULL_TREE;
    2906        49515 :       gswitch *switch_stmt;
    2907              : 
    2908              :       /* Save old labels, get new ones from body, then restore the old
    2909              :          labels.  Save all the things from the switch body to append after.  */
    2910        49515 :       saved_labels = gimplify_ctxp->case_labels;
    2911        49515 :       gimplify_ctxp->case_labels.create (8);
    2912              : 
    2913              :       /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR.  */
    2914        49515 :       saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
    2915        49515 :       tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
    2916        49515 :       if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
    2917        49231 :         gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
    2918              :       else
    2919          284 :         gimplify_ctxp->live_switch_vars = NULL;
    2920              : 
    2921        49515 :       bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
    2922        49515 :       gimplify_ctxp->in_switch_expr = true;
    2923              : 
    2924        49515 :       gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
    2925              : 
    2926        49515 :       gimplify_ctxp->in_switch_expr = old_in_switch_expr;
    2927        49515 :       maybe_warn_switch_unreachable_and_auto_init (switch_body_seq);
    2928        49515 :       maybe_warn_implicit_fallthrough (switch_body_seq);
    2929              :       /* Only do this for the outermost GIMPLE_SWITCH.  */
    2930        49515 :       if (!gimplify_ctxp->in_switch_expr)
    2931        47829 :         expand_FALLTHROUGH (&switch_body_seq);
    2932              : 
    2933        49515 :       labels = gimplify_ctxp->case_labels;
    2934        49515 :       gimplify_ctxp->case_labels = saved_labels;
    2935              : 
    2936        49515 :       if (gimplify_ctxp->live_switch_vars)
    2937              :         {
    2938        49231 :           gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
    2939        49231 :           delete gimplify_ctxp->live_switch_vars;
    2940              :         }
    2941        49515 :       gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
    2942              : 
    2943        49515 :       preprocess_case_label_vec_for_gimple (labels, index_type,
    2944              :                                             &default_case);
    2945              : 
    2946        49515 :       bool add_bind = false;
    2947        49515 :       if (!default_case)
    2948              :         {
    2949        14790 :           glabel *new_default;
    2950              : 
    2951        14790 :           default_case
    2952        14790 :             = build_case_label (NULL_TREE, NULL_TREE,
    2953              :                                 create_artificial_label (UNKNOWN_LOCATION));
    2954        14790 :           if (old_in_switch_expr)
    2955              :             {
    2956         1083 :               SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
    2957         1083 :               add_bind = true;
    2958              :             }
    2959        14790 :           new_default = gimple_build_label (CASE_LABEL (default_case));
    2960        14790 :           gimplify_seq_add_stmt (&switch_body_seq, new_default);
    2961              :         }
    2962        34725 :       else if (old_in_switch_expr)
    2963              :         {
    2964          603 :           gimple *last = gimple_seq_last_stmt (switch_body_seq);
    2965          603 :           if (last && gimple_code (last) == GIMPLE_LABEL)
    2966              :             {
    2967          338 :               tree label = gimple_label_label (as_a <glabel *> (last));
    2968          338 :               if (SWITCH_BREAK_LABEL_P (label))
    2969        49515 :                 add_bind = true;
    2970              :             }
    2971              :         }
    2972              : 
    2973        49515 :       switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
    2974              :                                          default_case, labels);
    2975        49515 :       gimple_set_location (switch_stmt, EXPR_LOCATION (switch_expr));
    2976              :       /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
    2977              :          ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
    2978              :          wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
    2979              :          so that we can easily find the start and end of the switch
    2980              :          statement.  */
    2981        49515 :       if (add_bind)
    2982              :         {
    2983         1420 :           gimple_seq bind_body = NULL;
    2984         1420 :           gimplify_seq_add_stmt (&bind_body, switch_stmt);
    2985         1420 :           gimple_seq_add_seq (&bind_body, switch_body_seq);
    2986         1420 :           gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
    2987         1420 :           gimple_set_location (bind, EXPR_LOCATION (switch_expr));
    2988         1420 :           gimplify_seq_add_stmt (pre_p, bind);
    2989              :         }
    2990              :       else
    2991              :         {
    2992        48095 :           gimplify_seq_add_stmt (pre_p, switch_stmt);
    2993        48095 :           gimplify_seq_add_seq (pre_p, switch_body_seq);
    2994              :         }
    2995        49515 :       labels.release ();
    2996              :     }
    2997              :   else
    2998            0 :     gcc_unreachable ();
    2999              : 
    3000        49515 :   return GS_ALL_DONE;
    3001              : }
    3002              : 
    3003              : /* Gimplify the LABEL_EXPR pointed to by EXPR_P.  */
    3004              : 
    3005              : static enum gimplify_status
    3006      2544320 : gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
    3007              : {
    3008      2544320 :   gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
    3009              :               == current_function_decl);
    3010              : 
    3011      2544320 :   tree label = LABEL_EXPR_LABEL (*expr_p);
    3012      2544320 :   glabel *label_stmt = gimple_build_label (label);
    3013      2544320 :   gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
    3014      2544320 :   gimplify_seq_add_stmt (pre_p, label_stmt);
    3015              : 
    3016      2544320 :   if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
    3017           21 :     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
    3018              :                                                       NOT_TAKEN));
    3019      2544299 :   else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
    3020           11 :     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
    3021              :                                                       TAKEN));
    3022              : 
    3023      2544320 :   return GS_ALL_DONE;
    3024              : }
    3025              : 
    3026              : /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P.  */
    3027              : 
    3028              : static enum gimplify_status
    3029      1034044 : gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
    3030              : {
    3031      1034044 :   struct gimplify_ctx *ctxp;
    3032      1034044 :   glabel *label_stmt;
    3033              : 
    3034              :   /* Invalid programs can play Duff's Device type games with, for example,
    3035              :      #pragma omp parallel.  At least in the C front end, we don't
    3036              :      detect such invalid branches until after gimplification, in the
    3037              :      diagnose_omp_blocks pass.  */
    3038      1034054 :   for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
    3039      1034054 :     if (ctxp->case_labels.exists ())
    3040              :       break;
    3041              : 
    3042      1034044 :   tree label = CASE_LABEL (*expr_p);
    3043      1034044 :   label_stmt = gimple_build_label (label);
    3044      1034044 :   gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
    3045      1034044 :   ctxp->case_labels.safe_push (*expr_p);
    3046      1034044 :   gimplify_seq_add_stmt (pre_p, label_stmt);
    3047              : 
    3048      1034044 :   if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
    3049           16 :     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
    3050              :                                                       NOT_TAKEN));
    3051      1034028 :   else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
    3052           20 :     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
    3053              :                                                       TAKEN));
    3054              : 
    3055      1034044 :   return GS_ALL_DONE;
    3056              : }
    3057              : 
    3058              : /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
    3059              :    if necessary.  */
    3060              : 
    3061              : tree
    3062      1769987 : build_and_jump (tree *label_p)
    3063              : {
    3064      1769987 :   if (label_p == NULL)
    3065              :     /* If there's nowhere to jump, just fall through.  */
    3066              :     return NULL_TREE;
    3067              : 
    3068      1200559 :   if (*label_p == NULL_TREE)
    3069              :     {
    3070       686740 :       tree label = create_artificial_label (UNKNOWN_LOCATION);
    3071       686740 :       *label_p = label;
    3072              :     }
    3073              : 
    3074      1200559 :   return build1 (GOTO_EXPR, void_type_node, *label_p);
    3075              : }
    3076              : 
    3077              : /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
    3078              :    This also involves building a label to jump to and communicating it to
    3079              :    gimplify_loop_expr through gimplify_ctxp->exit_label.  */
    3080              : 
    3081              : static enum gimplify_status
    3082         3069 : gimplify_exit_expr (tree *expr_p)
    3083              : {
    3084         3069 :   tree cond = TREE_OPERAND (*expr_p, 0);
    3085         3069 :   tree expr;
    3086              : 
    3087         3069 :   expr = build_and_jump (&gimplify_ctxp->exit_label);
    3088         3069 :   expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
    3089         3069 :   *expr_p = expr;
    3090              : 
    3091         3069 :   return GS_OK;
    3092              : }
    3093              : 
    3094              : /* *EXPR_P is a COMPONENT_REF being used as an rvalue.  If its type is
    3095              :    different from its canonical type, wrap the whole thing inside a
    3096              :    NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
    3097              :    type.
    3098              : 
    3099              :    The canonical type of a COMPONENT_REF is the type of the field being
    3100              :    referenced--unless the field is a bit-field which can be read directly
    3101              :    in a smaller mode, in which case the canonical type is the
    3102              :    sign-appropriate type corresponding to that mode.  */
    3103              : 
    3104              : static void
    3105     18466753 : canonicalize_component_ref (tree *expr_p)
    3106              : {
    3107     18466753 :   tree expr = *expr_p;
    3108     18466753 :   tree type;
    3109              : 
    3110     18466753 :   gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
    3111              : 
    3112     18466753 :   if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
    3113      7520014 :     type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
    3114              :   else
    3115     10946739 :     type = TREE_TYPE (TREE_OPERAND (expr, 1));
    3116              : 
    3117              :   /* One could argue that all the stuff below is not necessary for
    3118              :      the non-bitfield case and declare it a FE error if type
    3119              :      adjustment would be needed.  */
    3120     18466753 :   if (TREE_TYPE (expr) != type)
    3121              :     {
    3122              : #ifdef ENABLE_TYPES_CHECKING
    3123       739089 :       tree old_type = TREE_TYPE (expr);
    3124              : #endif
    3125       739089 :       int type_quals;
    3126              : 
    3127              :       /* We need to preserve qualifiers and propagate them from
    3128              :          operand 0.  */
    3129       739089 :       type_quals = TYPE_QUALS (type)
    3130       739089 :         | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
    3131       739089 :       if (TYPE_QUALS (type) != type_quals)
    3132       738929 :         type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
    3133              : 
    3134              :       /* Set the type of the COMPONENT_REF to the underlying type.  */
    3135       739089 :       TREE_TYPE (expr) = type;
    3136              : 
    3137              : #ifdef ENABLE_TYPES_CHECKING
    3138              :       /* It is now a FE error, if the conversion from the canonical
    3139              :          type to the original expression type is not useless.  */
    3140       739089 :       gcc_assert (useless_type_conversion_p (old_type, type));
    3141              : #endif
    3142              :     }
    3143     18466753 : }
    3144              : 
    3145              : /* If a NOP conversion is changing a pointer to array of foo to a pointer
    3146              :    to foo, embed that change in the ADDR_EXPR by converting
    3147              :       T array[U];
    3148              :       (T *)&array
    3149              :    ==>
    3150              :       &array[L]
    3151              :    where L is the lower bound.  For simplicity, only do this for constant
    3152              :    lower bound.
    3153              :    The constraint is that the type of &array[L] is trivially convertible
    3154              :    to T *.  */
    3155              : 
    3156              : static void
    3157       518447 : canonicalize_addr_expr (tree *expr_p)
    3158              : {
    3159       518447 :   tree expr = *expr_p;
    3160       518447 :   tree addr_expr = TREE_OPERAND (expr, 0);
    3161       518447 :   tree datype, ddatype, pddatype;
    3162              : 
    3163              :   /* We simplify only conversions from an ADDR_EXPR to a pointer type.  */
    3164      1036548 :   if (!POINTER_TYPE_P (TREE_TYPE (expr))
    3165       518447 :       || TREE_CODE (addr_expr) != ADDR_EXPR)
    3166              :     return;
    3167              : 
    3168              :   /* The addr_expr type should be a pointer to an array.  */
    3169          346 :   datype = TREE_TYPE (TREE_TYPE (addr_expr));
    3170          346 :   if (TREE_CODE (datype) != ARRAY_TYPE)
    3171              :     return;
    3172              : 
    3173              :   /* The pointer to element type shall be trivially convertible to
    3174              :      the expression pointer type.  */
    3175           28 :   ddatype = TREE_TYPE (datype);
    3176           28 :   pddatype = build_pointer_type (ddatype);
    3177           28 :   if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
    3178              :                                   pddatype))
    3179              :     return;
    3180              : 
    3181              :   /* The lower bound and element sizes must be constant.  */
    3182            0 :   if (!TYPE_SIZE_UNIT (ddatype)
    3183            0 :       || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
    3184            0 :       || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
    3185            0 :       || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
    3186              :     return;
    3187              : 
    3188              :   /* All checks succeeded.  Build a new node to merge the cast.  */
    3189            0 :   *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
    3190            0 :                     TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
    3191              :                     NULL_TREE, NULL_TREE);
    3192            0 :   *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
    3193              : 
    3194              :   /* We can have stripped a required restrict qualifier above.  */
    3195            0 :   if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
    3196            0 :     *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
    3197              : }
    3198              : 
    3199              : /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR.  Remove it and/or other conversions
    3200              :    underneath as appropriate.  */
    3201              : 
    3202              : static enum gimplify_status
    3203     12824675 : gimplify_conversion (tree *expr_p)
    3204              : {
    3205     12824675 :   location_t loc = EXPR_LOCATION (*expr_p);
    3206     12824675 :   gcc_assert (CONVERT_EXPR_P (*expr_p));
    3207              : 
    3208              :   /* Then strip away all but the outermost conversion.  */
    3209     12824675 :   STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
    3210              : 
    3211              :   /* And remove the outermost conversion if it's useless.  */
    3212     12824675 :   if (tree_ssa_useless_type_conversion (*expr_p))
    3213            0 :     *expr_p = TREE_OPERAND (*expr_p, 0);
    3214              : 
    3215              :   /* If we still have a conversion at the toplevel,
    3216              :      then canonicalize some constructs.  */
    3217     12824675 :   if (CONVERT_EXPR_P (*expr_p))
    3218              :     {
    3219     12824675 :       tree sub = TREE_OPERAND (*expr_p, 0);
    3220              : 
    3221              :       /* If a NOP conversion is changing the type of a COMPONENT_REF
    3222              :          expression, then canonicalize its type now in order to expose more
    3223              :          redundant conversions.  */
    3224     12824675 :       if (TREE_CODE (sub) == COMPONENT_REF)
    3225       272556 :         canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
    3226              : 
    3227              :       /* If a NOP conversion is changing a pointer to array of foo
    3228              :          to a pointer to foo, embed that change in the ADDR_EXPR.  */
    3229     12552119 :       else if (TREE_CODE (sub) == ADDR_EXPR)
    3230       518447 :         canonicalize_addr_expr (expr_p);
    3231              :     }
    3232              : 
    3233              :   /* If we have a conversion to a non-register type force the
    3234              :      use of a VIEW_CONVERT_EXPR instead.  */
    3235     12824675 :   if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
    3236           90 :     *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
    3237           90 :                                TREE_OPERAND (*expr_p, 0));
    3238              : 
    3239              :   /* Canonicalize CONVERT_EXPR to NOP_EXPR.  */
    3240     12824675 :   if (TREE_CODE (*expr_p) == CONVERT_EXPR)
    3241       227554 :     TREE_SET_CODE (*expr_p, NOP_EXPR);
    3242              : 
    3243     12824675 :   return GS_OK;
    3244              : }
    3245              : 
    3246              : /* Gimplify a VAR_DECL or PARM_DECL.  Return GS_OK if we expanded a
    3247              :    DECL_VALUE_EXPR, and it's worth re-examining things.  */
    3248              : 
    3249              : static enum gimplify_status
    3250    126210064 : gimplify_var_or_parm_decl (tree *expr_p)
    3251              : {
    3252    126210064 :   tree decl = *expr_p;
    3253              : 
    3254              :   /* ??? If this is a local variable, and it has not been seen in any
    3255              :      outer BIND_EXPR, then it's probably the result of a duplicate
    3256              :      declaration, for which we've already issued an error.  It would
    3257              :      be really nice if the front end wouldn't leak these at all.
    3258              :      Currently the only known culprit is C++ destructors, as seen
    3259              :      in g++.old-deja/g++.jason/binding.C.
    3260              :      Another possible culpit are size expressions for variably modified
    3261              :      types which are lost in the FE or not gimplified correctly.  */
    3262    126210064 :   if (VAR_P (decl)
    3263     98695927 :       && !DECL_SEEN_IN_BIND_EXPR_P (decl)
    3264     17066461 :       && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
    3265    126270058 :       && decl_function_context (decl) == current_function_decl)
    3266              :     {
    3267           75 :       gcc_assert (seen_error ());
    3268              :       return GS_ERROR;
    3269              :     }
    3270              : 
    3271              :   /* When within an OMP context, notice uses of variables.  */
    3272    126209989 :   if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
    3273              :     return GS_ALL_DONE;
    3274              : 
    3275              :   /* If the decl is an alias for another expression, substitute it now.  */
    3276    126204169 :   if (DECL_HAS_VALUE_EXPR_P (decl))
    3277              :     {
    3278       432049 :       *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
    3279       432049 :       return GS_OK;
    3280              :     }
    3281              : 
    3282              :   return GS_ALL_DONE;
    3283              : }
    3284              : 
    3285              : /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T.  */
    3286              : 
    3287              : static void
    3288    110194377 : recalculate_side_effects (tree t)
    3289              : {
    3290    110194377 :   enum tree_code code = TREE_CODE (t);
    3291    110194377 :   int len = TREE_OPERAND_LENGTH (t);
    3292    110194377 :   int i;
    3293              : 
    3294    110194377 :   switch (TREE_CODE_CLASS (code))
    3295              :     {
    3296       660970 :     case tcc_expression:
    3297       660970 :       switch (code)
    3298              :         {
    3299              :         case INIT_EXPR:
    3300              :         case MODIFY_EXPR:
    3301              :         case VA_ARG_EXPR:
    3302              :         case PREDECREMENT_EXPR:
    3303              :         case PREINCREMENT_EXPR:
    3304              :         case POSTDECREMENT_EXPR:
    3305              :         case POSTINCREMENT_EXPR:
    3306              :           /* All of these have side-effects, no matter what their
    3307              :              operands are.  */
    3308              :           return;
    3309              : 
    3310              :         default:
    3311              :           break;
    3312              :         }
    3313              :       /* Fall through.  */
    3314              : 
    3315    110194375 :     case tcc_comparison:  /* a comparison expression */
    3316    110194375 :     case tcc_unary:       /* a unary arithmetic expression */
    3317    110194375 :     case tcc_binary:      /* a binary arithmetic expression */
    3318    110194375 :     case tcc_reference:   /* a reference */
    3319    110194375 :     case tcc_vl_exp:        /* a function call */
    3320    110194375 :       TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
    3321    359375421 :       for (i = 0; i < len; ++i)
    3322              :         {
    3323    249181046 :           tree op = TREE_OPERAND (t, i);
    3324    249181046 :           if (op && TREE_SIDE_EFFECTS (op))
    3325      1276360 :             TREE_SIDE_EFFECTS (t) = 1;
    3326              :         }
    3327              :       break;
    3328              : 
    3329              :     case tcc_constant:
    3330              :       /* No side-effects.  */
    3331              :       return;
    3332              : 
    3333            2 :     default:
    3334            2 :       if (code == SSA_NAME)
    3335              :         /* No side-effects.  */
    3336              :         return;
    3337            0 :       gcc_unreachable ();
    3338              :    }
    3339              : }
    3340              : 
    3341              : /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
    3342              :    node *EXPR_P.
    3343              : 
    3344              :       compound_lval
    3345              :               : min_lval '[' val ']'
    3346              :               | min_lval '.' ID
    3347              :               | compound_lval '[' val ']'
    3348              :               | compound_lval '.' ID
    3349              : 
    3350              :    This is not part of the original SIMPLE definition, which separates
    3351              :    array and member references, but it seems reasonable to handle them
    3352              :    together.  Also, this way we don't run into problems with union
    3353              :    aliasing; gcc requires that for accesses through a union to alias, the
    3354              :    union reference must be explicit, which was not always the case when we
    3355              :    were splitting up array and member refs.
    3356              : 
    3357              :    PRE_P points to the sequence where side effects that must happen before
    3358              :      *EXPR_P should be stored.
    3359              : 
    3360              :    POST_P points to the sequence where side effects that must happen after
    3361              :      *EXPR_P should be stored.  */
    3362              : 
    3363              : static enum gimplify_status
    3364     29894761 : gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
    3365              :                         fallback_t fallback)
    3366              : {
    3367     29894761 :   tree *p;
    3368     29894761 :   enum gimplify_status ret = GS_ALL_DONE, tret;
    3369     29894761 :   int i;
    3370     29894761 :   location_t loc = EXPR_LOCATION (*expr_p);
    3371     29894761 :   tree expr = *expr_p;
    3372              : 
    3373              :   /* Create a stack of the subexpressions so later we can walk them in
    3374              :      order from inner to outer.  */
    3375     29894761 :   auto_vec<tree, 10> expr_stack;
    3376              : 
    3377              :   /* We can handle anything that get_inner_reference can deal with.  */
    3378     72171144 :   for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
    3379              :     {
    3380     42276383 :     restart:
    3381              :       /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs.  */
    3382     72237119 :       if (TREE_CODE (*p) == INDIRECT_REF)
    3383      3872789 :         *p = fold_indirect_ref_loc (loc, *p);
    3384              : 
    3385     72237119 :       if (handled_component_p (*p))
    3386              :         ;
    3387              :       /* Expand DECL_VALUE_EXPR now.  In some cases that may expose
    3388              :          additional COMPONENT_REFs.  */
    3389     13067651 :       else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
    3390     31404434 :                && gimplify_var_or_parm_decl (p) == GS_OK)
    3391        65975 :         goto restart;
    3392              :       else
    3393              :         break;
    3394              : 
    3395     42276383 :       expr_stack.safe_push (*p);
    3396              :     }
    3397              : 
    3398     29894761 :   gcc_assert (expr_stack.length ());
    3399              : 
    3400              :   /* Now EXPR_STACK is a stack of pointers to all the refs we've
    3401              :      walked through and P points to the innermost expression.
    3402              : 
    3403              :      Java requires that we elaborated nodes in source order.  That
    3404              :      means we must gimplify the inner expression followed by each of
    3405              :      the indices, in order.  But we can't gimplify the inner
    3406              :      expression until we deal with any variable bounds, sizes, or
    3407              :      positions in order to deal with PLACEHOLDER_EXPRs.
    3408              : 
    3409              :      The base expression may contain a statement expression that
    3410              :      has declarations used in size expressions, so has to be
    3411              :      gimplified before gimplifying the size expressions.
    3412              : 
    3413              :      So we do this in three steps.  First we deal with variable
    3414              :      bounds, sizes, and positions, then we gimplify the base and
    3415              :      ensure it is memory if needed, then we deal with the annotations
    3416              :      for any variables in the components and any indices, from left
    3417              :      to right.  */
    3418              : 
    3419     29894761 :   bool need_non_reg = false;
    3420     72171141 :   for (i = expr_stack.length () - 1; i >= 0; i--)
    3421              :     {
    3422     42276383 :       tree t = expr_stack[i];
    3423              : 
    3424     42276383 :       if (error_operand_p (TREE_OPERAND (t, 0)))
    3425              :         return GS_ERROR;
    3426              : 
    3427     42276380 :       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
    3428              :         {
    3429              :           /* Deal with the low bound and element type size and put them into
    3430              :              the ARRAY_REF.  If these values are set, they have already been
    3431              :              gimplified.  */
    3432      8954378 :           if (TREE_OPERAND (t, 2) == NULL_TREE)
    3433              :             {
    3434      8888491 :               tree low = unshare_expr (array_ref_low_bound (t));
    3435      8888491 :               if (!is_gimple_min_invariant (low))
    3436              :                 {
    3437            0 :                   TREE_OPERAND (t, 2) = low;
    3438              :                 }
    3439              :             }
    3440              : 
    3441      8954378 :           if (TREE_OPERAND (t, 3) == NULL_TREE)
    3442              :             {
    3443      8940853 :               tree elmt_size = array_ref_element_size (t);
    3444      8940853 :               if (!is_gimple_min_invariant (elmt_size))
    3445              :                 {
    3446         8497 :                   elmt_size = unshare_expr (elmt_size);
    3447         8497 :                   tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
    3448         8497 :                   tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
    3449              : 
    3450              :                   /* Divide the element size by the alignment of the element
    3451              :                      type (above).  */
    3452         8497 :                   elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
    3453              :                                               elmt_size, factor);
    3454              : 
    3455         8497 :                   TREE_OPERAND (t, 3) = elmt_size;
    3456              :                 }
    3457              :             }
    3458              :           need_non_reg = true;
    3459              :         }
    3460     33322002 :       else if (TREE_CODE (t) == COMPONENT_REF)
    3461              :         {
    3462              :           /* Set the field offset into T and gimplify it.  */
    3463     32144669 :           if (TREE_OPERAND (t, 2) == NULL_TREE)
    3464              :             {
    3465     32144290 :               tree offset = component_ref_field_offset (t);
    3466     32144290 :               if (!is_gimple_min_invariant (offset))
    3467              :                 {
    3468          287 :                   offset = unshare_expr (offset);
    3469          287 :                   tree field = TREE_OPERAND (t, 1);
    3470          287 :                   tree factor
    3471          287 :                     = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
    3472              : 
    3473              :                   /* Divide the offset by its alignment.  */
    3474          287 :                   offset = size_binop_loc (loc, EXACT_DIV_EXPR,
    3475              :                                            offset, factor);
    3476              : 
    3477          287 :                   TREE_OPERAND (t, 2) = offset;
    3478              :                 }
    3479              :             }
    3480              :           need_non_reg = true;
    3481              :         }
    3482      1177333 :       else if (!is_gimple_reg_type (TREE_TYPE (t)))
    3483              :         /* When the result of an operation, in particular a VIEW_CONVERT_EXPR
    3484              :            is a non-register type then require the base object to be a
    3485              :            non-register as well.  */
    3486     41377178 :         need_non_reg = true;
    3487              :     }
    3488              : 
    3489              :   /* Step 2 is to gimplify the base expression.  Make sure lvalue is set
    3490              :      so as to match the min_lval predicate.  Failure to do so may result
    3491              :      in the creation of large aggregate temporaries.  */
    3492     29894758 :   tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
    3493              :                         fallback | fb_lvalue);
    3494     29894758 :   ret = MIN (ret, tret);
    3495     29894758 :   if (ret == GS_ERROR)
    3496              :     return GS_ERROR;
    3497              : 
    3498              :   /* Step 2a: if we have component references we do not support on
    3499              :      registers then make sure the base isn't a register.  Of course
    3500              :      we can only do so if an rvalue is OK.  */
    3501     29894758 :   if (need_non_reg && (fallback & fb_rvalue))
    3502     22330460 :     prepare_gimple_addressable (p, pre_p);
    3503              : 
    3504              : 
    3505              :   /* Step 3: gimplify size expressions and the indices and operands of
    3506              :      ARRAY_REF.  During this loop we also remove any useless conversions.
    3507              :      If we operate on a register also make sure to properly gimplify
    3508              :      to individual operations.  */
    3509              : 
    3510     29894758 :   bool reg_operations = is_gimple_reg (*p);
    3511     72171138 :   for (; expr_stack.length () > 0; )
    3512              :     {
    3513     42276380 :       tree t = expr_stack.pop ();
    3514              : 
    3515     42276380 :       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
    3516              :         {
    3517      8954378 :           gcc_assert (!reg_operations);
    3518              : 
    3519              :           /* Gimplify the low bound and element type size. */
    3520      8954378 :           tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
    3521              :                                 is_gimple_reg, fb_rvalue);
    3522      8954378 :           ret = MIN (ret, tret);
    3523              : 
    3524      8954378 :           tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
    3525              :                                 is_gimple_reg, fb_rvalue);
    3526      8954378 :           ret = MIN (ret, tret);
    3527              : 
    3528              :           /* Gimplify the dimension.  */
    3529      8954378 :           tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
    3530              :                                 is_gimple_val, fb_rvalue);
    3531      8954378 :           ret = MIN (ret, tret);
    3532              :         }
    3533     33322002 :       else if (TREE_CODE (t) == COMPONENT_REF)
    3534              :         {
    3535     32144669 :           gcc_assert (!reg_operations);
    3536              : 
    3537     32144669 :           tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
    3538              :                                 is_gimple_reg, fb_rvalue);
    3539     32144669 :           ret = MIN (ret, tret);
    3540              :         }
    3541      1177333 :       else if (reg_operations)
    3542              :         {
    3543       780696 :           tret = gimplify_expr (&TREE_OPERAND (t, 0), pre_p, post_p,
    3544              :                                 is_gimple_val, fb_rvalue);
    3545      1177333 :           ret = MIN (ret, tret);
    3546              :         }
    3547              : 
    3548     42276380 :       STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
    3549              : 
    3550              :       /* The innermost expression P may have originally had
    3551              :          TREE_SIDE_EFFECTS set which would have caused all the outer
    3552              :          expressions in *EXPR_P leading to P to also have had
    3553              :          TREE_SIDE_EFFECTS set.  */
    3554     42276380 :       recalculate_side_effects (t);
    3555              :     }
    3556              : 
    3557              :   /* If the outermost expression is a COMPONENT_REF, canonicalize its type.  */
    3558     29894758 :   if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
    3559              :     {
    3560     18194197 :       canonicalize_component_ref (expr_p);
    3561              :     }
    3562              : 
    3563     29894758 :   expr_stack.release ();
    3564              : 
    3565     29894758 :   gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
    3566              : 
    3567              :   return ret;
    3568     29894761 : }
    3569              : 
    3570              : /*  Gimplify the self modifying expression pointed to by EXPR_P
    3571              :     (++, --, +=, -=).
    3572              : 
    3573              :     PRE_P points to the list where side effects that must happen before
    3574              :         *EXPR_P should be stored.
    3575              : 
    3576              :     POST_P points to the list where side effects that must happen after
    3577              :         *EXPR_P should be stored.
    3578              : 
    3579              :     WANT_VALUE is nonzero iff we want to use the value of this expression
    3580              :         in another expression.
    3581              : 
    3582              :     ARITH_TYPE is the type the computation should be performed in.  */
    3583              : 
    3584              : enum gimplify_status
    3585      1131142 : gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
    3586              :                         bool want_value, tree arith_type)
    3587              : {
    3588      1131142 :   enum tree_code code;
    3589      1131142 :   tree lhs, lvalue, rhs, t1;
    3590      1131142 :   gimple_seq post = NULL, *orig_post_p = post_p;
    3591      1131142 :   bool postfix;
    3592      1131142 :   enum tree_code arith_code;
    3593      1131142 :   enum gimplify_status ret;
    3594      1131142 :   location_t loc = EXPR_LOCATION (*expr_p);
    3595              : 
    3596      1131142 :   code = TREE_CODE (*expr_p);
    3597              : 
    3598      1131142 :   gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
    3599              :               || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
    3600              : 
    3601              :   /* Prefix or postfix?  */
    3602      1131142 :   if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
    3603              :     /* Faster to treat as prefix if result is not used.  */
    3604              :     postfix = want_value;
    3605              :   else
    3606              :     postfix = false;
    3607              : 
    3608              :   /* For postfix, make sure the inner expression's post side effects
    3609              :      are executed after side effects from this expression.  */
    3610       400067 :   if (postfix)
    3611      1131142 :     post_p = &post;
    3612              : 
    3613              :   /* Add or subtract?  */
    3614      1131142 :   if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
    3615              :     arith_code = PLUS_EXPR;
    3616              :   else
    3617        43665 :     arith_code = MINUS_EXPR;
    3618              : 
    3619              :   /* Gimplify the LHS into a GIMPLE lvalue.  */
    3620      1131142 :   lvalue = TREE_OPERAND (*expr_p, 0);
    3621      1131142 :   ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
    3622      1131142 :   if (ret == GS_ERROR)
    3623              :     return ret;
    3624              : 
    3625              :   /* Extract the operands to the arithmetic operation.  */
    3626      1131137 :   lhs = lvalue;
    3627      1131137 :   rhs = TREE_OPERAND (*expr_p, 1);
    3628              : 
    3629              :   /* For postfix operator, we evaluate the LHS to an rvalue and then use
    3630              :      that as the result value and in the postqueue operation.  */
    3631      1131137 :   if (postfix)
    3632              :     {
    3633       188196 :       ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
    3634       188196 :       if (ret == GS_ERROR)
    3635              :         return ret;
    3636              : 
    3637       188196 :       lhs = get_initialized_tmp_var (lhs, pre_p);
    3638              :     }
    3639              : 
    3640              :   /* For POINTERs increment, use POINTER_PLUS_EXPR.  */
    3641      1131137 :   if (POINTER_TYPE_P (TREE_TYPE (lhs)))
    3642              :     {
    3643       231315 :       rhs = convert_to_ptrofftype_loc (loc, rhs);
    3644       231315 :       if (arith_code == MINUS_EXPR)
    3645         9646 :         rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
    3646       231315 :       t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
    3647              :     }
    3648              :   else
    3649       899822 :     t1 = fold_convert (TREE_TYPE (*expr_p),
    3650              :                        fold_build2 (arith_code, arith_type,
    3651              :                                     fold_convert (arith_type, lhs),
    3652              :                                     fold_convert (arith_type, rhs)));
    3653              : 
    3654      1131137 :   if (postfix)
    3655              :     {
    3656       188196 :       gimplify_assign (lvalue, t1, pre_p);
    3657       188196 :       gimplify_seq_add_seq (orig_post_p, post);
    3658       188196 :       *expr_p = lhs;
    3659       188196 :       return GS_ALL_DONE;
    3660              :     }
    3661              :   else
    3662              :     {
    3663       942941 :       *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
    3664       942941 :       return GS_OK;
    3665              :     }
    3666              : }
    3667              : 
    3668              : /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR.  */
    3669              : 
    3670              : static void
    3671     80452196 : maybe_with_size_expr (tree *expr_p)
    3672              : {
    3673     80452196 :   tree expr = *expr_p;
    3674     80452196 :   tree type = TREE_TYPE (expr);
    3675     80452196 :   tree size;
    3676              : 
    3677              :   /* If we've already wrapped this or the type is error_mark_node, we can't do
    3678              :      anything.  */
    3679     80452196 :   if (TREE_CODE (expr) == WITH_SIZE_EXPR
    3680     80452071 :       || type == error_mark_node)
    3681              :     return;
    3682              : 
    3683              :   /* If the size isn't known or is a constant, we have nothing to do.  */
    3684     80451923 :   size = TYPE_SIZE_UNIT (type);
    3685     80451923 :   if (!size || poly_int_tree_p (size))
    3686              :     return;
    3687              : 
    3688              :   /* Otherwise, make a WITH_SIZE_EXPR.  */
    3689         1699 :   size = unshare_expr (size);
    3690         1699 :   size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
    3691         1699 :   *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
    3692              : }
    3693              : 
    3694              : /* Helper for gimplify_call_expr.  Gimplify a single argument *ARG_P
    3695              :    Store any side-effects in PRE_P.  CALL_LOCATION is the location of
    3696              :    the CALL_EXPR.  If ALLOW_SSA is set the actual parameter may be
    3697              :    gimplified to an SSA name.  */
    3698              : 
    3699              : enum gimplify_status
    3700     33006812 : gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
    3701              :               bool allow_ssa)
    3702              : {
    3703     33006812 :   bool (*test) (tree);
    3704     33006812 :   fallback_t fb;
    3705              : 
    3706              :   /* In general, we allow lvalues for function arguments to avoid
    3707              :      extra overhead of copying large aggregates out of even larger
    3708              :      aggregates into temporaries only to copy the temporaries to
    3709              :      the argument list.  Make optimizers happy by pulling out to
    3710              :      temporaries those types that fit in registers.  */
    3711     33006812 :   if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
    3712              :     test = is_gimple_val, fb = fb_rvalue;
    3713              :   else
    3714              :     {
    3715      1549438 :       test = is_gimple_lvalue, fb = fb_either;
    3716              :       /* Also strip a TARGET_EXPR that would force an extra copy.  */
    3717      1549438 :       if (TREE_CODE (*arg_p) == TARGET_EXPR)
    3718              :         {
    3719       299989 :           tree init = TARGET_EXPR_INITIAL (*arg_p);
    3720       299989 :           if (init
    3721       299986 :               && !VOID_TYPE_P (TREE_TYPE (init))
    3722              :               /* Currently, due to c++/116015, it is not desirable to
    3723              :                  strip a TARGET_EXPR whose initializer is a {}.  The
    3724              :                  problem is that if we do elide it, we also have to
    3725              :                  replace all the occurrences of the slot temporary in the
    3726              :                  initializer with the temporary created for the argument.
    3727              :                  But we do not have that temporary yet so the replacement
    3728              :                  would be quite awkward and it might be needed to resort
    3729              :                  back to a PLACEHOLDER_EXPR.  Note that stripping the
    3730              :                  TARGET_EXPR wouldn't help anyway, as gimplify_expr would
    3731              :                  just allocate a temporary to store the CONSTRUCTOR into.
    3732              :                  (FIXME PR116375.)
    3733              : 
    3734              :                  See convert_for_arg_passing for the C++ code that marks
    3735              :                  the TARGET_EXPR as eliding or not.  */
    3736       561505 :               && TREE_CODE (init) != CONSTRUCTOR)
    3737       231337 :             *arg_p = init;
    3738              :         }
    3739              :     }
    3740              : 
    3741              :   /* If this is a variable sized type, we must remember the size.  */
    3742     33006812 :   maybe_with_size_expr (arg_p);
    3743              : 
    3744              :   /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c.  */
    3745              :   /* Make sure arguments have the same location as the function call
    3746              :      itself.  */
    3747     33006812 :   protected_set_expr_location (*arg_p, call_location);
    3748              : 
    3749              :   /* There is a sequence point before a function call.  Side effects in
    3750              :      the argument list must occur before the actual call. So, when
    3751              :      gimplifying arguments, force gimplify_expr to use an internal
    3752              :      post queue which is then appended to the end of PRE_P.  */
    3753     33006812 :   return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
    3754              : }
    3755              : 
    3756              : /* Don't fold inside offloading or taskreg regions: it can break code by
    3757              :    adding decl references that weren't in the source.  We'll do it during
    3758              :    omplower pass instead.  */
    3759              : 
    3760              : static bool
    3761     58869966 : maybe_fold_stmt (gimple_stmt_iterator *gsi)
    3762              : {
    3763     58869966 :   struct gimplify_omp_ctx *ctx;
    3764     59398081 :   for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
    3765      1198525 :     if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
    3766              :       return false;
    3767       533064 :     else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
    3768              :       return false;
    3769              :   /* Delay folding of builtins until the IL is in consistent state
    3770              :      so the diagnostic machinery can do a better job.  */
    3771     58199556 :   if (gimple_call_builtin_p (gsi_stmt (*gsi)))
    3772              :     return false;
    3773     55849953 :   return fold_stmt (gsi);
    3774              : }
    3775              : 
    3776              : static tree
    3777              : expand_late_variant_directive (vec<struct omp_variant> all_candidates,
    3778              :                                tree construct_context);
    3779              : 
    3780              : 
    3781              : /* Helper function for calls to omp_dynamic_cond: find the current
    3782              :    enclosing block in the gimplification context.  */
    3783              : static tree
    3784          359 : find_supercontext (void)
    3785              : {
    3786          359 :   vec<gbind *>stack = gimple_bind_expr_stack ();
    3787          686 :   for (int i = stack.length () - 1; i >= 0; i++)
    3788              :     {
    3789          327 :       gbind *b = stack[i];
    3790          327 :       if (b->block)
    3791              :         return b->block;
    3792              :     }
    3793              :   return NULL_TREE;
    3794              : }
    3795              : 
    3796              : /* OpenMP: Handle the append_args and adjust_args clauses of
    3797              :    declare_variant for EXPR, which is a CALL_EXPR whose CALL_EXPR_FN
    3798              :    is the variant, within a dispatch construct with clauses DISPATCH_CLAUSES.
    3799              :    WANT_VALUE and POINTERIZE are as for expand_variant_call_expr.
    3800              : 
    3801              :    'append_args' causes interop objects are added after the last regular
    3802              :    (nonhidden, nonvariadic) arguments of the variant function.
    3803              :    'adjust_args' with need_device_{addr,ptr} converts the pointer target of
    3804              :    a pointer from a host to a device address. This uses either the default
    3805              :    device or the passed device number, which then sets the default device
    3806              :    address.  */
    3807              : static tree
    3808          471 : modify_call_for_omp_dispatch (tree expr, tree dispatch_clauses,
    3809              :                               bool want_value, bool pointerize)
    3810              : {
    3811          471 :   location_t loc = EXPR_LOCATION (expr);
    3812          471 :   tree fndecl = get_callee_fndecl (expr);
    3813              : 
    3814              :   /* Skip processing if we don't get the expected call form.  */
    3815          471 :   if (!fndecl)
    3816              :     return expr;
    3817              : 
    3818          471 :   tree init_code = NULL_TREE;
    3819          471 :   tree cleanup = NULL_TREE;
    3820          471 :   tree clobbers = NULL_TREE;
    3821          471 :   int nargs = call_expr_nargs (expr);
    3822          471 :   tree dispatch_device_num = NULL_TREE;
    3823          471 :   tree dispatch_interop = NULL_TREE;
    3824          471 :   tree dispatch_append_args = NULL_TREE;
    3825          471 :   int nfirst_args = 0;
    3826          471 :   tree dispatch_adjust_args_list
    3827          471 :     = lookup_attribute ("omp declare variant variant args",
    3828          471 :                         DECL_ATTRIBUTES (fndecl));
    3829              : 
    3830          471 :   if (dispatch_adjust_args_list)
    3831              :     {
    3832          389 :       dispatch_adjust_args_list = TREE_VALUE (dispatch_adjust_args_list);
    3833          389 :       dispatch_append_args = TREE_CHAIN (dispatch_adjust_args_list);
    3834          389 :       if (TREE_PURPOSE (dispatch_adjust_args_list) == NULL_TREE
    3835          389 :           && TREE_VALUE (dispatch_adjust_args_list) == NULL_TREE)
    3836              :         dispatch_adjust_args_list = NULL_TREE;
    3837              :     }
    3838          389 :   if (dispatch_append_args)
    3839              :     {
    3840          245 :       nfirst_args = tree_to_shwi (TREE_PURPOSE (dispatch_append_args));
    3841          245 :       dispatch_append_args = TREE_VALUE (dispatch_append_args);
    3842              :     }
    3843          471 :   dispatch_device_num = omp_find_clause (dispatch_clauses, OMP_CLAUSE_DEVICE);
    3844          471 :   if (dispatch_device_num)
    3845          287 :     dispatch_device_num = OMP_CLAUSE_DEVICE_ID (dispatch_device_num);
    3846          471 :   dispatch_interop = omp_find_clause (dispatch_clauses, OMP_CLAUSE_INTEROP);
    3847          471 :   int nappend = 0, ninterop = 0;
    3848          880 :   for (tree t = dispatch_append_args; t; t = TREE_CHAIN (t))
    3849          409 :     nappend++;
    3850              : 
    3851              :   /* FIXME: error checking should be taken out of this function and
    3852              :      handled before any attempt at filtering or resolution happens.
    3853              :      Otherwise whether or not diagnostics appear is determined by
    3854              :      GCC internals, how good the front ends are at constant-folding,
    3855              :      the split between early/late resolution, etc instead of the code
    3856              :      as written by the user.  */
    3857          471 :   if (dispatch_interop)
    3858          861 :     for (tree t = dispatch_interop; t; t = TREE_CHAIN (t))
    3859          605 :       if (OMP_CLAUSE_CODE (t) == OMP_CLAUSE_INTEROP)
    3860          409 :         ninterop++;
    3861          471 :   if (dispatch_interop && !dispatch_device_num)
    3862              :     {
    3863            7 :       gcc_checking_assert (ninterop > 1);
    3864            7 :       error_at (OMP_CLAUSE_LOCATION (dispatch_interop),
    3865              :                 "the %<device%> clause must be present if the %<interop%> "
    3866              :                 "clause has more than one list item");
    3867              :     }
    3868          471 :   if (nappend < ninterop)
    3869              :     {
    3870           48 :       error_at (OMP_CLAUSE_LOCATION (dispatch_interop),
    3871              :                 "number of list items in %<interop%> clause (%d) "
    3872              :                 "exceeds the number of %<append_args%> items (%d) for "
    3873              :                 "%<declare variant%> candidate %qD", ninterop, nappend, fndecl);
    3874           88 :       inform (dispatch_append_args
    3875            8 :               ? EXPR_LOCATION (TREE_PURPOSE (dispatch_append_args))
    3876           40 :               : DECL_SOURCE_LOCATION (fndecl),
    3877              :               "%<declare variant%> candidate %qD declared here", fndecl);
    3878           48 :       ninterop = nappend;
    3879              :     }
    3880          471 :   if (dispatch_append_args)
    3881              :     {
    3882          245 :       tree *buffer = XALLOCAVEC (tree, nargs + nappend);
    3883          245 :       tree arg = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
    3884              :       /* Copy the first arguments; insert then the interop objects,
    3885              :          and then copy the rest (nargs - nfirst_args) args.  */
    3886          245 :       int i;
    3887          679 :       for (i = 0; i < nfirst_args; i++)
    3888              :         {
    3889          434 :           arg = TREE_CHAIN (arg);
    3890          434 :           buffer[i] = CALL_EXPR_ARG (expr, i);
    3891              :         }
    3892              :       int j = ninterop;
    3893          583 :       for (tree t = dispatch_interop; t && j > 0; t = TREE_CHAIN (t))
    3894          338 :         if (OMP_CLAUSE_CODE (t) == OMP_CLAUSE_INTEROP)
    3895          338 :           buffer[i + --j] = OMP_CLAUSE_DECL (t);
    3896          245 :       gcc_checking_assert (j == 0);
    3897              : 
    3898              :       /* Do we need to create additional interop objects?  */
    3899          245 :       if (ninterop < nappend)
    3900              :         {
    3901           56 :           if (dispatch_device_num == NULL_TREE)
    3902              :             /* Not remapping device number.  */
    3903           22 :             dispatch_device_num = build_int_cst (integer_type_node,
    3904              :                                                  GOMP_DEVICE_DEFAULT_OMP_61);
    3905           56 :           int nnew = nappend - ninterop;
    3906           56 :           tree nobjs = build_int_cst (integer_type_node, nnew);
    3907           56 :           tree a, t;
    3908              : 
    3909              :           /* Skip to the append_args clause for the first constructed
    3910              :              interop argument.  */
    3911           56 :           tree apparg = dispatch_append_args;
    3912           83 :           for (j = 0; j < ninterop; j++)
    3913           27 :             apparg = TREE_CHAIN (apparg);
    3914              : 
    3915              :           /* omp_interop_t *objs[n]; */
    3916           56 :           tree objtype = build_pointer_type (pointer_sized_int_node);
    3917           56 :           t = build_array_type_nelts (objtype, nnew);
    3918           56 :           tree objs = create_tmp_var (t, "interopobjs");
    3919              : 
    3920              :           /* int target_tgtsync[n]; */
    3921           56 :           t = build_array_type_nelts (integer_type_node, nnew);
    3922           56 :           tree target_tgtsync = create_tmp_var (t, "tgt_tgtsync");
    3923              : 
    3924              :           /* Scan first to determine if we need a prefer_type array.  */
    3925           56 :           tree prefer_type = NULL_TREE;
    3926           56 :           tree prefer_type_type = NULL_TREE;
    3927          141 :           for (j = ninterop, a = apparg; j < nappend; j++, a = TREE_CHAIN (a))
    3928           64 :             if (TREE_VALUE (a) != NULL_TREE)
    3929              :               {
    3930              :                 /* const char *prefer_type[n];  */
    3931           35 :                 t = build_qualified_type (char_type_node, TYPE_QUAL_CONST);
    3932           35 :                 prefer_type_type = build_pointer_type (t);
    3933           35 :                 t = build_array_type_nelts (prefer_type_type, nnew);
    3934           35 :                 prefer_type = create_tmp_var (t, "pref_type");
    3935           35 :                 break;
    3936              :               }
    3937              : 
    3938              :           /* Initialize the arrays, generating temp vars and clobbers for
    3939              :              the interop objects.  (The constructed array holding the
    3940              :              pointers to these objects shouldn't need clobbering as there's
    3941              :              no reason for GOMP_interop to modify its contents.)  */
    3942          127 :           for (j = ninterop, a = apparg; j < nappend; j++, a = TREE_CHAIN (a))
    3943              :             {
    3944              :               /* The allocated temporaries for the interop objects
    3945              :                  have type omp_interop_t, which is an integer type that
    3946              :                  can encode a pointer.  */
    3947           71 :               tree objvar = create_tmp_var (pointer_sized_int_node, "interop");
    3948           71 :               buffer[i + j] = objvar;
    3949           71 :               TREE_ADDRESSABLE (objvar) = 1;
    3950              :               /* Generate a clobber for the temporary for when we're done
    3951              :                  with it.  */
    3952           71 :               tree c = build_clobber (pointer_sized_int_node,
    3953              :                                       CLOBBER_OBJECT_END);
    3954           71 :               c = build2 (MODIFY_EXPR, pointer_sized_int_node, objvar, c);
    3955           71 :               if (clobbers)
    3956           15 :                 clobbers = build2 (COMPOUND_EXPR, TREE_TYPE (clobbers),
    3957              :                                    c, clobbers);
    3958              :               else
    3959              :                 clobbers = c;
    3960              : 
    3961              :               /* objs[offset] = &objvar;  */
    3962           71 :               tree offset = build_int_cst (integer_type_node, j - ninterop);
    3963           71 :               tree init = build4 (ARRAY_REF, objtype, objs, offset,
    3964              :                                   NULL_TREE, NULL_TREE);
    3965           71 :               init = build2 (MODIFY_EXPR, objtype, init,
    3966              :                              build_fold_addr_expr (objvar));
    3967           71 :               if (init_code)
    3968           15 :                 init_code = build2 (COMPOUND_EXPR, TREE_TYPE (init),
    3969              :                                     init_code, init);
    3970              :               else
    3971              :                 init_code = init;
    3972              : 
    3973              :               /* target_tgtsync[offset] = tgt;
    3974              :                  (Don't blame me, I didn't design the encoding of this
    3975              :                  info into the dispatch interop clause data structure,
    3976              :                  but the runtime wants a bit mask.)  */
    3977           71 :               tree tree_tgt = TREE_OPERAND (TREE_PURPOSE (a), 0);
    3978           71 :               int tgt = 0;
    3979           71 :               if (TREE_PURPOSE (tree_tgt) == boolean_true_node)
    3980           42 :                 tgt |= GOMP_INTEROP_TARGET;
    3981           71 :               if (TREE_VALUE (tree_tgt) == boolean_true_node)
    3982           36 :                 tgt |= GOMP_INTEROP_TARGETSYNC;
    3983           71 :               init = build4 (ARRAY_REF, integer_type_node,
    3984              :                              target_tgtsync, offset, NULL_TREE, NULL_TREE);
    3985           71 :               init = build2 (MODIFY_EXPR, integer_type_node, init,
    3986           71 :                              build_int_cst (integer_type_node, tgt));
    3987           71 :               init_code = build2 (COMPOUND_EXPR, TREE_TYPE (init),
    3988              :                                   init_code, init);
    3989              : 
    3990           71 :               if (prefer_type)
    3991              :                 {
    3992           45 :                   tree pref = TREE_VALUE (a);
    3993           45 :                   if (pref == NULL_TREE)
    3994            6 :                     pref = null_pointer_node;
    3995              :                   else
    3996           39 :                     pref = build_fold_addr_expr (pref);
    3997           45 :                   init = build4 (ARRAY_REF, prefer_type_type, prefer_type,
    3998              :                                  offset, NULL_TREE, NULL_TREE);
    3999           45 :                   init = build2 (MODIFY_EXPR, prefer_type_type, init,
    4000              :                                  pref);
    4001           45 :                   init_code = build2 (COMPOUND_EXPR, TREE_TYPE (init),
    4002              :                                       init_code, init);
    4003              :                 }
    4004              :             }
    4005              : 
    4006           56 :           objs = build_fold_addr_expr (objs);
    4007           56 :           target_tgtsync = build_fold_addr_expr (target_tgtsync);
    4008           56 :           prefer_type = prefer_type ? build_fold_addr_expr (prefer_type)
    4009              :                                     : null_pointer_node;
    4010           56 :           tree fn = builtin_decl_explicit (BUILT_IN_GOMP_INTEROP);
    4011           56 :           tree create
    4012           56 :             = build_call_expr_loc (loc, fn, 11, dispatch_device_num,
    4013              :                                    nobjs, objs, target_tgtsync, prefer_type,
    4014              :                                    integer_zero_node, null_pointer_node,
    4015              :                                    integer_zero_node, null_pointer_node,
    4016              :                                    integer_zero_node, null_pointer_node);
    4017           56 :           if (init_code)
    4018           56 :             init_code = build2 (COMPOUND_EXPR, TREE_TYPE (create),
    4019              :                                 init_code, create);
    4020              :           else
    4021              :             init_code = create;
    4022              : 
    4023           56 :           cleanup
    4024           56 :             = build_call_expr_loc (loc, fn, 11, dispatch_device_num,
    4025              :                                    integer_zero_node, null_pointer_node,
    4026              :                                    null_pointer_node, null_pointer_node,
    4027              :                                    integer_zero_node, null_pointer_node,
    4028              :                                    nobjs, objs,
    4029              :                                    integer_zero_node, null_pointer_node);
    4030           56 :           if (clobbers)
    4031           56 :             cleanup = build2 (COMPOUND_EXPR, TREE_TYPE (clobbers),
    4032              :                               cleanup, clobbers);
    4033              :         }
    4034              : 
    4035          654 :       for (j = 0; j < nappend; j++)
    4036              :         {
    4037              :           /* Fortran permits by-reference or by-value for the dummy arg
    4038              :              and by-value, by-reference, ptr by-reference as actual
    4039              :              argument. Handle this.  */
    4040          409 :           tree obj = buffer[i + j];  // interop object
    4041          409 :           tree a2 = TREE_VALUE (arg);  // parameter type
    4042          766 :           if (POINTER_TYPE_P (TREE_TYPE (obj))
    4043          436 :               && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (obj))))
    4044              :             {
    4045           32 :               tree t = TREE_TYPE (TREE_TYPE (obj));
    4046           32 :               gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (t)));
    4047           32 :               obj = fold_build1 (INDIRECT_REF, t, obj);
    4048              :             }
    4049          750 :           if (POINTER_TYPE_P (TREE_TYPE (obj))
    4050          420 :               && INTEGRAL_TYPE_P (a2))
    4051              :             {
    4052           43 :               tree t = TREE_TYPE (TREE_TYPE (obj));
    4053           43 :               gcc_checking_assert (INTEGRAL_TYPE_P (t));
    4054           43 :               obj = fold_build1 (INDIRECT_REF, t, obj);
    4055              :             }
    4056          497 :           else if (INTEGRAL_TYPE_P (TREE_TYPE (obj))
    4057          461 :                    && POINTER_TYPE_P (a2))
    4058              :             {
    4059           18 :               gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (a2)));
    4060           18 :               obj = build_fold_addr_expr (obj);
    4061              :             }
    4062          348 :           else if (!INTEGRAL_TYPE_P (a2)
    4063          348 :                    || !INTEGRAL_TYPE_P (TREE_TYPE (obj)))
    4064              :             {
    4065           36 :               tree t = TREE_TYPE (obj);
    4066           36 :               gcc_checking_assert (POINTER_TYPE_P (t)
    4067              :                                    && POINTER_TYPE_P (a2)
    4068              :                                    && INTEGRAL_TYPE_P (TREE_TYPE (t))
    4069              :                                    && INTEGRAL_TYPE_P (TREE_TYPE (a2)));
    4070              :             }
    4071          409 :           buffer[i + j] = obj;
    4072          409 :           arg = TREE_CHAIN (arg);
    4073              :         }
    4074          245 :       i += nappend;
    4075          534 :       for (j = nfirst_args; j < nargs; j++)
    4076          289 :         buffer[i++] = CALL_EXPR_ARG (expr, j);
    4077          245 :       nargs += nappend;
    4078          245 :       tree call = expr;
    4079          490 :       expr = build_call_array_loc (EXPR_LOCATION (expr), TREE_TYPE (call),
    4080          245 :                                    CALL_EXPR_FN (call), nargs, buffer);
    4081              : 
    4082              :       /* Copy all CALL_EXPR flags.  */
    4083          245 :       CALL_EXPR_STATIC_CHAIN (expr) = CALL_EXPR_STATIC_CHAIN (call);
    4084          245 :       CALL_EXPR_TAILCALL (expr) = CALL_EXPR_TAILCALL (call);
    4085          245 :       CALL_EXPR_RETURN_SLOT_OPT (expr)
    4086          245 :         = CALL_EXPR_RETURN_SLOT_OPT (call);
    4087          245 :       CALL_FROM_THUNK_P (expr) = CALL_FROM_THUNK_P (call);
    4088          245 :       SET_EXPR_LOCATION (expr, EXPR_LOCATION (call));
    4089          245 :       CALL_EXPR_VA_ARG_PACK (expr) = CALL_EXPR_VA_ARG_PACK (call);
    4090              :     }
    4091              : 
    4092              :   /* Nothing to do for adjust_args?  */
    4093          471 :   if (!dispatch_adjust_args_list || !TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
    4094          260 :     goto add_cleanup;
    4095              : 
    4096              :   /* Handle adjust_args.  */
    4097          966 :   for (int i = 0; i < nargs; i++)
    4098              :     {
    4099          755 :       tree *arg_p = &CALL_EXPR_ARG (expr, i);
    4100              : 
    4101              :       /* Nothing to do if arg is constant null pointer.  */
    4102          755 :       if (integer_zerop (*arg_p))
    4103            6 :         continue;
    4104              : 
    4105              :       bool need_device_ptr = false;
    4106              :       bool need_device_addr = false;
    4107         2247 :       for (int need_addr = 0; need_addr <= 1; need_addr++)
    4108         2301 :         for (tree arg = (need_addr
    4109         1498 :                          ? TREE_VALUE (dispatch_adjust_args_list)
    4110         1498 :                          : TREE_PURPOSE (dispatch_adjust_args_list));
    4111         2301 :              arg != NULL; arg = TREE_CHAIN (arg))
    4112              :           {
    4113         1152 :             if (TREE_VALUE (arg)
    4114         1152 :                 && TREE_CODE (TREE_VALUE (arg)) == INTEGER_CST
    4115         2304 :                 && wi::eq_p (i, wi::to_wide (TREE_VALUE (arg))))
    4116              :               {
    4117          349 :                 if (need_addr)
    4118              :                   need_device_addr = true;
    4119              :                 else
    4120          349 :                   need_device_ptr = true;
    4121              :                 break;
    4122              :               }
    4123              :           }
    4124              : 
    4125          749 :       if (need_device_ptr || need_device_addr)
    4126              :         {
    4127          740 :           bool is_device_ptr = false;
    4128          740 :           bool has_device_addr = false;
    4129              : 
    4130          740 :           for (tree c = dispatch_clauses; c; c = TREE_CHAIN (c))
    4131              :             {
    4132          454 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR
    4133          454 :                   || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
    4134              :                 {
    4135          164 :                   tree decl1 = DECL_NAME (OMP_CLAUSE_DECL (c));
    4136          164 :                   tree decl2 = tree_strip_nop_conversions (*arg_p);
    4137          164 :                   if (TREE_CODE (decl2) == ADDR_EXPR)
    4138           19 :                     decl2 = TREE_OPERAND (decl2, 0);
    4139          164 :                   if (VAR_P (decl2) || TREE_CODE (decl2) == PARM_DECL)
    4140              :                     {
    4141          140 :                       decl2 = DECL_NAME (decl2);
    4142          140 :                       if (decl1 == decl2
    4143          203 :                           && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
    4144              :                         {
    4145           58 :                           if (need_device_addr)
    4146            0 :                             warning_at (OMP_CLAUSE_LOCATION (c),
    4147            0 :                                         OPT_Wopenmp,
    4148              :                                         "%<is_device_ptr%> for %qD does"
    4149              :                                         " not imply %<has_device_addr%> "
    4150              :                                         "required for %<need_device_addr%>",
    4151            0 :                                         OMP_CLAUSE_DECL (c));
    4152              :                           is_device_ptr = true;
    4153              :                           break;
    4154              :                         }
    4155           82 :                       else if (decl1 == decl2)
    4156              :                         {
    4157            5 :                           if (need_device_ptr)
    4158           10 :                             warning_at (OMP_CLAUSE_LOCATION (c),
    4159            5 :                                         OPT_Wopenmp,
    4160              :                                         "%<has_device_addr%> for %qD does"
    4161              :                                         " not imply %<is_device_ptr%> "
    4162              :                                         "required for %<need_device_ptr%>",
    4163            5 :                                         OMP_CLAUSE_DECL (c));
    4164              :                           has_device_addr = true;
    4165              :                           break;
    4166              :                         }
    4167              :                     }
    4168              :                 }
    4169              :             }
    4170              : 
    4171          349 :           if ((need_device_ptr && !is_device_ptr)
    4172           58 :               || (need_device_addr && !has_device_addr))
    4173              :             {
    4174          291 :               if (dispatch_device_num == NULL_TREE)
    4175              :                 {
    4176              :                   // device_num = omp_get_default_device ()
    4177          105 :                   tree fn
    4178          105 :                     = builtin_decl_explicit (BUILT_IN_OMP_GET_DEFAULT_DEVICE);
    4179          105 :                   tree call = build_call_expr (fn, 0);
    4180          105 :                   dispatch_device_num = create_tmp_var_raw (TREE_TYPE (call));
    4181          105 :                   tree init
    4182          105 :                     = build4 (TARGET_EXPR, TREE_TYPE (call),
    4183              :                               dispatch_device_num, call, NULL_TREE, NULL_TREE);
    4184          105 :                   if (init_code)
    4185            0 :                     init_code = build2 (COMPOUND_EXPR, TREE_TYPE (init),
    4186              :                                         init_code, init);
    4187              :                   else
    4188              :                     init_code = init;
    4189              :                 }
    4190              : 
    4191              :               // We want to emit the following statement:
    4192              :               //   mapped_arg = omp_get_mapped_ptr (arg,
    4193              :               //                device_num)
    4194              :               // but arg has to be the actual pointer, not a
    4195              :               // reference or a conversion expression.
    4196          291 :               tree actual_ptr
    4197          291 :                 = ((TREE_CODE (*arg_p) == ADDR_EXPR)
    4198          291 :                    ? TREE_OPERAND (*arg_p, 0)
    4199           38 :                    : *arg_p);
    4200          291 :               if (TREE_CODE (actual_ptr) == NOP_EXPR
    4201          291 :                   && (TREE_CODE (TREE_TYPE (TREE_OPERAND (actual_ptr, 0)))
    4202              :                       == REFERENCE_TYPE))
    4203              :                 {
    4204            6 :                   actual_ptr = TREE_OPERAND (actual_ptr, 0);
    4205            6 :                   actual_ptr = build1 (INDIRECT_REF,
    4206            6 :                                        TREE_TYPE (actual_ptr),
    4207              :                                        actual_ptr);
    4208              :                 }
    4209          291 :               tree fn = builtin_decl_explicit (BUILT_IN_OMP_GET_MAPPED_PTR);
    4210          291 :               tree mapped_arg = build_call_expr_loc (loc, fn, 2, actual_ptr,
    4211              :                                                      dispatch_device_num);
    4212              : 
    4213          291 :               if (TREE_CODE (*arg_p) == ADDR_EXPR
    4214          291 :                   || (TREE_CODE (TREE_TYPE (actual_ptr)) == REFERENCE_TYPE))
    4215           47 :                 mapped_arg = build_fold_addr_expr (mapped_arg);
    4216          244 :               else if (TREE_CODE (*arg_p) == NOP_EXPR)
    4217           35 :                 mapped_arg = build1 (NOP_EXPR, TREE_TYPE (*arg_p),
    4218              :                                      mapped_arg);
    4219          291 :               *arg_p = mapped_arg;
    4220              :             }
    4221              :         }
    4222              :     }
    4223              : 
    4224          471 :  add_cleanup:
    4225          471 :   if (cleanup)
    4226              :     {
    4227           56 :       tree result = NULL_TREE;
    4228           56 :       if (want_value && pointerize)
    4229              :         {
    4230            0 :           tree tmp = create_tmp_var (build_pointer_type (TREE_TYPE (expr)),
    4231              :                                      "cleanuptmp");
    4232            0 :           result = build_simple_mem_ref (tmp);
    4233            0 :           expr = build2 (INIT_EXPR, TREE_TYPE (tmp), tmp,
    4234              :                          build_fold_addr_expr (expr));
    4235              :         }
    4236           56 :       else if (want_value)
    4237              :         {
    4238           18 :           tree tmp = create_tmp_var (TREE_TYPE (expr), "cleanuptmp");
    4239           18 :           result = tmp;
    4240           18 :           expr = build2 (INIT_EXPR, TREE_TYPE (tmp), tmp, expr);
    4241              :         }
    4242           56 :       if (init_code)
    4243           56 :         expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init_code, expr);
    4244           56 :       expr = build2 (TRY_FINALLY_EXPR, void_type_node, expr, cleanup);
    4245              : 
    4246           56 :       if (result)
    4247           18 :         expr = build2 (COMPOUND_EXPR, TREE_TYPE (result), expr, result);
    4248              :     }
    4249          415 :   else if (init_code)
    4250          105 :     expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init_code, expr);
    4251              : 
    4252              :   return expr;
    4253              : }
    4254              : 
    4255              : /* Helper function for gimplify_call_expr: handle "declare variant"
    4256              :    resolution and expansion of the CALL_EXPR EXPR.  WANT_VALUE is true
    4257              :    if the result value of the call is needed; POINTERIZE is true if it
    4258              :    also needs to be pointerized.  If OMP_DISPATCH_P is true, apply
    4259              :    associated transformations using DISPATCH_CLAUSES.
    4260              :    This function may return either the original call or some other
    4261              :    expression such as a conditional to select one of multiple calls.
    4262              : 
    4263              :    FIXME: this function is written to be independent of gimplifier internals
    4264              :    so that it could be moved to omp-general.cc and invoked from the
    4265              :    front ends instead, per PR115076.  */
    4266              : 
    4267              : static tree
    4268         1326 : expand_variant_call_expr (tree expr, bool want_value, bool pointerize,
    4269              :                           bool omp_dispatch_p, tree dispatch_clauses)
    4270              : {
    4271              :   /* If we've already processed this call, stop now.  This can happen
    4272              :      if the variant call resolves to the original function, or to
    4273              :      a dynamic conditional that includes the default call to the original
    4274              :      function.  */
    4275         1326 :   gcc_assert (omp_resolved_variant_calls != NULL);
    4276         1326 :   if (omp_resolved_variant_calls->contains (expr))
    4277          131 :     return expr;
    4278              : 
    4279         1195 :   tree fndecl = get_callee_fndecl (expr);
    4280         1195 :   tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (expr));
    4281         1195 :   location_t loc = EXPR_LOCATION (expr);
    4282         1195 :   tree construct_context = omp_get_construct_context ();
    4283         1195 :   vec<struct omp_variant> all_candidates
    4284         1195 :     = omp_declare_variant_candidates (fndecl, construct_context);
    4285         1195 :   gcc_assert (!all_candidates.is_empty ());
    4286         1195 :   vec<struct omp_variant> candidates
    4287         1195 :     = omp_get_dynamic_candidates (all_candidates, construct_context);
    4288              : 
    4289              :   /* If the variant call could be resolved now, build a nest of COND_EXPRs
    4290              :      if there are dynamic candidates, and/or a new CALL_EXPR for each
    4291              :      candidate call.  */
    4292         1195 :   if (!candidates.is_empty ())
    4293              :     {
    4294         1183 :       int n = candidates.length ();
    4295         1183 :       tree tail = NULL_TREE;
    4296              : 
    4297         2404 :       for (int i = n - 1; i >= 0; i--)
    4298              :         {
    4299         1221 :           if (tail)
    4300           38 :             gcc_assert (candidates[i].dynamic_selector);
    4301              :           else
    4302         1183 :             gcc_assert (!candidates[i].dynamic_selector);
    4303         1221 :           if (candidates[i].alternative == fndecl)
    4304              :             {
    4305              :               /* We should only get the original function back as the
    4306              :                  default.  */
    4307          261 :               gcc_assert (!tail);
    4308          261 :               omp_resolved_variant_calls->add (expr);
    4309          261 :               tail = expr;
    4310              :             }
    4311              :           else
    4312              :             {
    4313              :               /* For the final static selector, we can re-use the old
    4314              :                  CALL_EXPR and just replace the function, unless it may
    4315              :                  need dispatch argument modification.  Otherwise,
    4316              :                  make a copy of it.  */
    4317          960 :               tree thiscall = (tail || omp_dispatch_p
    4318          960 :                                ? unshare_expr (expr) : expr);
    4319          960 :               CALL_EXPR_FN (thiscall) = build1 (ADDR_EXPR, fnptrtype,
    4320          960 :                                                 candidates[i].alternative);
    4321          960 :               if (omp_dispatch_p)
    4322          471 :                 thiscall = modify_call_for_omp_dispatch (thiscall,
    4323              :                                                          dispatch_clauses,
    4324              :                                                          want_value,
    4325              :                                                          pointerize);
    4326          960 :               if (!tail)
    4327              :                 tail = thiscall;
    4328              :               else
    4329           76 :                 tail = build3 (COND_EXPR, TREE_TYPE (expr),
    4330           38 :                                omp_dynamic_cond (candidates[i].selector,
    4331              :                                                  find_supercontext ()),
    4332              :                                thiscall, tail);
    4333              :             }
    4334              :         }
    4335              :       return tail;
    4336              :     }
    4337              : 
    4338              :   /* If we couldn't resolve the variant call now, expand it into a loop using
    4339              :      a switch and OMP_NEXT_VARIANT for dispatch.  The ompdevlow pass will
    4340              :      handle OMP_NEXT_VARIANT expansion.  */
    4341              :   else
    4342              :     {
    4343              :       /* If we need a usable return value, we need a temporary
    4344              :          and an assignment in each alternative.  This logic was borrowed
    4345              :          from gimplify_cond_expr.  */
    4346           12 :       tree type = TREE_TYPE (expr);
    4347           12 :       tree tmp = NULL_TREE, result = NULL_TREE;
    4348              : 
    4349           12 :       if (want_value)
    4350              :         {
    4351           12 :           if (pointerize)
    4352              :             {
    4353            0 :               type = build_pointer_type (type);
    4354            0 :               tmp = create_tmp_var (type, "iftmp");
    4355            0 :               result = build_simple_mem_ref_loc (loc, tmp);
    4356              :             }
    4357              :           else
    4358              :             {
    4359           12 :               tmp = create_tmp_var (type, "iftmp");
    4360           12 :               result = tmp;
    4361              :             }
    4362              :         }
    4363              : 
    4364              :       /* Preprocess the all_candidates array so that the alternative field of
    4365              :          each element holds the actual function call expression and possible
    4366              :          assignment, instead of just the decl for the variant function.  */
    4367           60 :       for (unsigned int i = 0; i < all_candidates.length (); i++)
    4368              :         {
    4369           48 :           tree decl = all_candidates[i].alternative;
    4370           48 :           tree thiscall;
    4371              : 
    4372              :           /* We need to turn the decl from the candidate into a function
    4373              :              call and possible assignment, and stuff that in
    4374              :              the directive seq of the gomp_variant.  */
    4375           48 :           if (decl == fndecl)
    4376              :             {
    4377           12 :               thiscall = expr;
    4378           12 :               omp_resolved_variant_calls->add (expr);
    4379              :             }
    4380              :           else
    4381              :             {
    4382           36 :               thiscall = unshare_expr (expr);
    4383           36 :               CALL_EXPR_FN (thiscall) = build1 (ADDR_EXPR, fnptrtype, decl);
    4384           36 :               if (omp_dispatch_p)
    4385            0 :                 thiscall = modify_call_for_omp_dispatch (thiscall,
    4386              :                                                          dispatch_clauses,
    4387              :                                                          want_value,
    4388              :                                                          pointerize);
    4389              :             }
    4390           48 :           if (pointerize)
    4391            0 :             thiscall = build_fold_addr_expr_loc (loc, thiscall);
    4392           48 :           if (want_value)
    4393           48 :             thiscall = build2 (INIT_EXPR, type, tmp, thiscall);
    4394           48 :           all_candidates[i].alternative = thiscall;
    4395              :         }
    4396              : 
    4397           12 :       cgraph_node::get (cfun->decl)->has_omp_variant_constructs = 1;
    4398           12 :       tree expansion = expand_late_variant_directive (all_candidates,
    4399              :                                                       construct_context);
    4400           12 :       if (result)
    4401           12 :         expansion = build2 (COMPOUND_EXPR, TREE_TYPE (result),
    4402              :                             expansion, result);
    4403           12 :       return expansion;
    4404              :     }
    4405              : }
    4406              : 
    4407              : /* Wrapper around expand_variant_call_expr to interface with gimplifier
    4408              :    state.  EXPR and OMP_DISPATCH_P are as for expand_variant_call_expr,
    4409              :    FALLBACK is used to compute the WANT_VALUE and POINTERIZE arguments.  */
    4410              : static tree
    4411         1326 : gimplify_variant_call_expr (tree expr, fallback_t fallback,
    4412              :                             bool omp_dispatch_p)
    4413              : {
    4414         1326 :   tree type = TREE_TYPE (expr);
    4415         1326 :   bool want_value = (fallback != fb_none && !VOID_TYPE_P (type));
    4416          673 :   bool pointerize = false;
    4417              :   /* If the result value must be an lvalue or the result type must
    4418              :      live in memory, then we have to pointerize it if we need a temporary.  */
    4419          673 :   if (want_value
    4420          673 :       && ((!(fallback & fb_rvalue) && (fallback & fb_lvalue))
    4421          673 :           || TREE_ADDRESSABLE (type)))
    4422            0 :     pointerize = true;
    4423              : 
    4424         1838 :   return expand_variant_call_expr (expr, want_value, pointerize,
    4425              :                                    omp_dispatch_p,
    4426              :                                    (omp_dispatch_p
    4427          512 :                                     ? gimplify_omp_ctxp->clauses
    4428         1326 :                                     : NULL_TREE));
    4429              : }
    4430              : 
    4431              : 
    4432              : /* Helper function for gimplify_call_expr, called via walk_tree.
    4433              :    Find used user labels.  */
    4434              : 
    4435              : static tree
    4436          766 : find_used_user_labels (tree *tp, int *, void *)
    4437              : {
    4438          766 :   if (TREE_CODE (*tp) == LABEL_EXPR
    4439           15 :       && !DECL_ARTIFICIAL (LABEL_EXPR_LABEL (*tp))
    4440           15 :       && DECL_NAME (LABEL_EXPR_LABEL (*tp))
    4441          781 :       && TREE_USED (LABEL_EXPR_LABEL (*tp)))
    4442           15 :     return *tp;
    4443              :   return NULL_TREE;
    4444              : }
    4445              : 
    4446              : 
    4447              : /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
    4448              :    WANT_VALUE is true if the result of the call is desired.  */
    4449              : 
    4450              : static enum gimplify_status
    4451     16669640 : gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
    4452              : {
    4453     16669640 :   bool want_value = (fallback != fb_none);
    4454     16669640 :   tree fndecl, parms, p, fnptrtype;
    4455     16669640 :   enum gimplify_status ret;
    4456     16669640 :   int i, nargs;
    4457     16669640 :   gcall *call;
    4458     16669640 :   bool builtin_va_start_p = false, omp_dispatch_p = false;
    4459     16669640 :   location_t loc = EXPR_LOCATION (*expr_p);
    4460              : 
    4461     16669640 :   gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
    4462              : 
    4463              :   /* For reliable diagnostics during inlining, it is necessary that
    4464              :      every call_expr be annotated with file and line.  */
    4465     16669640 :   if (! EXPR_HAS_LOCATION (*expr_p))
    4466       562691 :     SET_EXPR_LOCATION (*expr_p, input_location);
    4467              : 
    4468              :   /* Gimplify internal functions created in the FEs.  */
    4469     16669640 :   if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
    4470              :     {
    4471       563746 :       enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
    4472       563746 :       if (ifn == IFN_GOMP_DISPATCH)
    4473              :         {
    4474          884 :           gcc_assert (flag_openmp
    4475              :                       && gimplify_omp_ctxp
    4476              :                       && gimplify_omp_ctxp->code == OMP_DISPATCH);
    4477          884 :           *expr_p = CALL_EXPR_ARG (*expr_p, 0);
    4478          884 :           gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
    4479          884 :           if (! EXPR_HAS_LOCATION (*expr_p))
    4480           94 :             SET_EXPR_LOCATION (*expr_p, input_location);
    4481              :           omp_dispatch_p = true;
    4482              :         }
    4483              :       else
    4484              :         {
    4485       562862 :           if (want_value)
    4486              :             return GS_ALL_DONE;
    4487              : 
    4488        19580 :           nargs = call_expr_nargs (*expr_p);
    4489        19580 :           auto_vec<tree> vargs (nargs);
    4490              : 
    4491        19580 :           if (ifn == IFN_ASSUME)
    4492              :             {
    4493          513 :               if (simple_condition_p (CALL_EXPR_ARG (*expr_p, 0)))
    4494              :                 {
    4495              :                   /* If the [[assume (cond)]]; condition is simple
    4496              :                      enough and can be evaluated unconditionally
    4497              :                      without side-effects, expand it as
    4498              :                      if (!cond) __builtin_unreachable ();  */
    4499          293 :                   tree fndecl = builtin_decl_explicit (BUILT_IN_UNREACHABLE);
    4500          293 :                   *expr_p
    4501          586 :                     = build3 (COND_EXPR, void_type_node,
    4502          293 :                               CALL_EXPR_ARG (*expr_p, 0), void_node,
    4503          293 :                               build_call_expr_loc (EXPR_LOCATION (*expr_p),
    4504              :                                                    fndecl, 0));
    4505          293 :                   return GS_OK;
    4506              :                 }
    4507              :               /* If not optimizing, ignore the assumptions unless there
    4508              :                  are used user labels in it.  */
    4509          220 :               if ((!optimize
    4510           98 :                    && !walk_tree_without_duplicates (&CALL_EXPR_ARG (*expr_p,
    4511              :                                                                      0),
    4512              :                                                      find_used_user_labels,
    4513              :                                                      NULL))
    4514          235 :                   || seen_error ())
    4515              :                 {
    4516           94 :                   *expr_p = NULL_TREE;
    4517           94 :                   return GS_ALL_DONE;
    4518              :                 }
    4519              :               /* Temporarily, until gimple lowering, transform
    4520              :                  .ASSUME (cond);
    4521              :                  into:
    4522              :                  [[assume (guard)]]
    4523              :                  {
    4524              :                    guard = cond;
    4525              :                  }
    4526              :                  such that gimple lowering can outline the condition into
    4527              :                  a separate function easily.  */
    4528          126 :               tree guard = create_tmp_var (boolean_type_node);
    4529          126 :               *expr_p = build2 (MODIFY_EXPR, void_type_node, guard,
    4530          126 :                                 gimple_boolify (CALL_EXPR_ARG (*expr_p, 0)));
    4531          126 :               *expr_p = build3 (BIND_EXPR, void_type_node, NULL, *expr_p, NULL);
    4532          126 :               push_gimplify_context ();
    4533          126 :               gimple_seq body = NULL;
    4534          126 :               gimple *g = gimplify_and_return_first (*expr_p, &body);
    4535          126 :               pop_gimplify_context (g);
    4536          126 :               g = gimple_build_assume (guard, body);
    4537          126 :               gimple_set_location (g, loc);
    4538          126 :               gimplify_seq_add_stmt (pre_p, g);
    4539          126 :               *expr_p = NULL_TREE;
    4540          126 :               return GS_ALL_DONE;
    4541              :             }
    4542        19067 :           else if (ifn == IFN_UBSAN_BOUNDS
    4543        19067 :                    && nargs == 3
    4544        19067 :                    && integer_onep (CALL_EXPR_ARG (*expr_p, 0)))
    4545              :             {
    4546              :               /* If first argument is one, add TYPE_MAX_VALUE (TYPE_DOMAIN (t))
    4547              :                  to 3rd argument and change first argument to 0.  This is
    4548              :                  done by ubsan_instrument_bounds so that we can use the
    4549              :                  max value from gimplify_type_sizes here instead of original
    4550              :                  expression for VLAs.  */
    4551          406 :               tree type = TREE_TYPE (CALL_EXPR_ARG (*expr_p, 0));
    4552          406 :               CALL_EXPR_ARG (*expr_p, 0) = build_int_cst (type, 0);
    4553          406 :               gcc_assert (TREE_CODE (type) == POINTER_TYPE);
    4554          406 :               type = TREE_TYPE (type);
    4555          406 :               gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
    4556          406 :               tree maxv = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
    4557          406 :               gcc_assert (maxv);
    4558          406 :               tree arg3 = CALL_EXPR_ARG (*expr_p, 2);
    4559          406 :               CALL_EXPR_ARG (*expr_p, 2)
    4560          812 :                 = fold_build2 (PLUS_EXPR, TREE_TYPE (arg3), maxv, arg3);
    4561              :             }
    4562              : 
    4563        44694 :           for (i = 0; i < nargs; i++)
    4564              :             {
    4565        25627 :               gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
    4566        25627 :                             EXPR_LOCATION (*expr_p));
    4567        25627 :               vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
    4568              :             }
    4569              : 
    4570        19067 :           gcall *call = gimple_build_call_internal_vec (ifn, vargs);
    4571        19067 :           gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
    4572        19067 :           gimplify_seq_add_stmt (pre_p, call);
    4573        19067 :           return GS_ALL_DONE;
    4574        19580 :         }
    4575              :     }
    4576              : 
    4577              :   /* This may be a call to a builtin function.
    4578              : 
    4579              :      Builtin function calls may be transformed into different
    4580              :      (and more efficient) builtin function calls under certain
    4581              :      circumstances.  Unfortunately, gimplification can muck things
    4582              :      up enough that the builtin expanders are not aware that certain
    4583              :      transformations are still valid.
    4584              : 
    4585              :      So we attempt transformation/gimplification of the call before
    4586              :      we gimplify the CALL_EXPR.  At this time we do not manage to
    4587              :      transform all calls in the same manner as the expanders do, but
    4588              :      we do transform most of them.  */
    4589     16106778 :   fndecl = get_callee_fndecl (*expr_p);
    4590     16106778 :   if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
    4591      3943829 :     switch (DECL_FUNCTION_CODE (fndecl))
    4592              :       {
    4593        95347 :       CASE_BUILT_IN_ALLOCA:
    4594              :         /* If the call has been built for a variable-sized object, then we
    4595              :            want to restore the stack level when the enclosing BIND_EXPR is
    4596              :            exited to reclaim the allocated space; otherwise, we precisely
    4597              :            need to do the opposite and preserve the latest stack level.  */
    4598        95347 :         if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
    4599         8965 :           gimplify_ctxp->save_stack = true;
    4600              :         else
    4601        86382 :           gimplify_ctxp->keep_stack = true;
    4602              :         break;
    4603              : 
    4604        20884 :       case BUILT_IN_VA_START:
    4605        20884 :         {
    4606        20884 :           builtin_va_start_p = true;
    4607        20884 :           if (call_expr_nargs (*expr_p) < 2)
    4608              :             {
    4609            1 :               error ("too few arguments to function %<va_start%>");
    4610            1 :               *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
    4611            1 :               return GS_OK;
    4612              :             }
    4613              : 
    4614        20883 :           if (fold_builtin_next_arg (*expr_p, true))
    4615              :             {
    4616            8 :               *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
    4617            8 :               return GS_OK;
    4618              :             }
    4619              :           break;
    4620              :         }
    4621              : 
    4622           30 :       case BUILT_IN_EH_RETURN:
    4623           30 :         cfun->calls_eh_return = true;
    4624           30 :         break;
    4625              : 
    4626         1030 :       case BUILT_IN_CLEAR_PADDING:
    4627         1030 :         if (call_expr_nargs (*expr_p) == 1)
    4628              :           {
    4629              :             /* Remember the original type of the argument in an internal
    4630              :                dummy second argument, as in GIMPLE pointer conversions are
    4631              :                useless.  Also mark this call as not for automatic
    4632              :                initialization in the internal dummy third argument.  */
    4633          515 :             p = CALL_EXPR_ARG (*expr_p, 0);
    4634          515 :             *expr_p
    4635          515 :               = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
    4636          515 :                                      build_zero_cst (TREE_TYPE (p)));
    4637          515 :             return GS_OK;
    4638              :           }
    4639              :         break;
    4640              : 
    4641              :       default:
    4642              :         ;
    4643              :       }
    4644     16106254 :   if (fndecl && fndecl_built_in_p (fndecl))
    4645              :     {
    4646      4179412 :       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
    4647      4179412 :       if (new_tree && new_tree != *expr_p)
    4648              :         {
    4649              :           /* There was a transformation of this call which computes the
    4650              :              same value, but in a more efficient way.  Return and try
    4651              :              again.  */
    4652          755 :           *expr_p = new_tree;
    4653          755 :           return GS_OK;
    4654              :         }
    4655              :     }
    4656              : 
    4657              :   /* Remember the original function pointer type.  */
    4658     16105499 :   fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
    4659              : 
    4660              :   /* Handle "declare variant" resolution and arglist processing.  */
    4661     16105499 :   if (flag_openmp
    4662       448281 :       && fndecl
    4663       447600 :       && cfun
    4664       447600 :       && (cfun->curr_properties & PROP_gimple_any) == 0
    4665       250405 :       && !omp_has_novariants ()
    4666     16355792 :       && lookup_attribute ("omp declare variant base",
    4667       250293 :                            DECL_ATTRIBUTES (fndecl)))
    4668              :     {
    4669         1326 :       tree orig = *expr_p;
    4670         1326 :       *expr_p = gimplify_variant_call_expr (*expr_p, fallback,
    4671              :                                             omp_dispatch_p);
    4672              : 
    4673              :       /* This may resolve to the same call, or the call expr with just
    4674              :          the function replaced, in which case we should just continue to
    4675              :          gimplify it normally.  Otherwise, if we get something else back,
    4676              :          stop here and re-gimplify the whole replacement expr.  */
    4677         1326 :       if (*expr_p != orig)
    4678              :         return GS_OK;
    4679              :     }
    4680              : 
    4681              :   /* There is a sequence point before the call, so any side effects in
    4682              :      the calling expression must occur before the actual call.  Force
    4683              :      gimplify_expr to use an internal post queue.  */
    4684     16105010 :   ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
    4685              :                        is_gimple_call_addr, fb_rvalue);
    4686              : 
    4687     16105010 :   if (ret == GS_ERROR)
    4688              :     return GS_ERROR;
    4689              : 
    4690     16105008 :   nargs = call_expr_nargs (*expr_p);
    4691              : 
    4692              :   /* Get argument types for verification.  */
    4693     16105008 :   fndecl = get_callee_fndecl (*expr_p);
    4694     16105008 :   parms = NULL_TREE;
    4695     16105008 :   if (fndecl)
    4696     15884085 :     parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
    4697              :   else
    4698       220923 :     parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
    4699              : 
    4700     31989093 :   if (fndecl && DECL_ARGUMENTS (fndecl))
    4701              :     p = DECL_ARGUMENTS (fndecl);
    4702      7309010 :   else if (parms)
    4703              :     p = parms;
    4704              :   else
    4705              :     p = NULL_TREE;
    4706     42773876 :   for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
    4707              :     ;
    4708              : 
    4709              :   /* If the last argument is __builtin_va_arg_pack () and it is not
    4710              :      passed as a named argument, decrease the number of CALL_EXPR
    4711              :      arguments and set instead the CALL_EXPR_VA_ARG_PACK flag.  */
    4712     16105008 :   if (!p
    4713     16105008 :       && i < nargs
    4714     16105008 :       && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
    4715              :     {
    4716         5946 :       tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
    4717         5946 :       tree last_arg_fndecl = get_callee_fndecl (last_arg);
    4718              : 
    4719         5946 :       if (last_arg_fndecl
    4720         5946 :           && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
    4721              :         {
    4722          131 :           tree call = *expr_p;
    4723              : 
    4724          131 :           --nargs;
    4725          262 :           *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
    4726          131 :                                           CALL_EXPR_FN (call),
    4727          131 :                                           nargs, CALL_EXPR_ARGP (call));
    4728              : 
    4729              :           /* Copy all CALL_EXPR flags, location and block, except
    4730              :              CALL_EXPR_VA_ARG_PACK flag.  */
    4731          131 :           CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
    4732          131 :           CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
    4733          131 :           CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
    4734          131 :             = CALL_EXPR_RETURN_SLOT_OPT (call);
    4735          131 :           CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
    4736          131 :           SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
    4737              : 
    4738              :           /* Set CALL_EXPR_VA_ARG_PACK.  */
    4739          131 :           CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
    4740              :         }
    4741              :     }
    4742              : 
    4743              :   /* If the call returns twice then after building the CFG the call
    4744              :      argument computations will no longer dominate the call because
    4745              :      we add an abnormal incoming edge to the call.  So do not use SSA
    4746              :      vars there.  */
    4747     16105008 :   bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
    4748              : 
    4749              : 
    4750              :   /* Gimplify the function arguments.  */
    4751     16105008 :   if (nargs > 0)
    4752              :     {
    4753     13941431 :       for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
    4754     42048684 :            PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
    4755     28107253 :            PUSH_ARGS_REVERSED ? i-- : i++)
    4756              :         {
    4757     28107253 :           enum gimplify_status t;
    4758              : 
    4759              :           /* Avoid gimplifying the second argument to va_start, which needs to
    4760              :              be the plain PARM_DECL.  */
    4761     28107253 :           if ((i != 1) || !builtin_va_start_p)
    4762              :             {
    4763     28086378 :               tree *arg_p = &CALL_EXPR_ARG (*expr_p, i);
    4764              : 
    4765     28086378 :               if (gimplify_omp_ctxp && gimplify_omp_ctxp->code == OMP_DISPATCH)
    4766         6687 :                 gimplify_omp_ctxp->in_call_args = true;
    4767     28086378 :               t = gimplify_arg (arg_p, pre_p, EXPR_LOCATION (*expr_p),
    4768     28086378 :                                 !returns_twice);
    4769     28086378 :               if (gimplify_omp_ctxp && gimplify_omp_ctxp->code == OMP_DISPATCH)
    4770         6687 :                 gimplify_omp_ctxp->in_call_args = false;
    4771              : 
    4772     28086378 :               if (t == GS_ERROR)
    4773     28107253 :                 ret = GS_ERROR;
    4774              :             }
    4775              :         }
    4776              :     }
    4777              : 
    4778              :   /* Gimplify the static chain.  */
    4779     16105008 :   if (CALL_EXPR_STATIC_CHAIN (*expr_p))
    4780              :     {
    4781        28852 :       if (fndecl && !DECL_STATIC_CHAIN (fndecl))
    4782            3 :         CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
    4783              :       else
    4784              :         {
    4785        28173 :           enum gimplify_status t;
    4786        28173 :           t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
    4787        28173 :                             EXPR_LOCATION (*expr_p), ! returns_twice);
    4788        28173 :           if (t == GS_ERROR)
    4789     16105008 :             ret = GS_ERROR;
    4790              :         }
    4791              :     }
    4792              : 
    4793              :   /* Verify the function result.  */
    4794     16105008 :   if (want_value && fndecl
    4795     16105008 :       && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
    4796              :     {
    4797            0 :       error_at (loc, "using result of function returning %<void%>");
    4798            0 :       ret = GS_ERROR;
    4799              :     }
    4800              : 
    4801              :   /* Try this again in case gimplification exposed something.  */
    4802     16105008 :   if (ret != GS_ERROR)
    4803              :     {
    4804     16104860 :       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
    4805              : 
    4806     16104860 :       if (new_tree && new_tree != *expr_p)
    4807              :         {
    4808              :           /* There was a transformation of this call which computes the
    4809              :              same value, but in a more efficient way.  Return and try
    4810              :              again.  */
    4811        11459 :           *expr_p = new_tree;
    4812        11459 :           return GS_OK;
    4813              :         }
    4814              :     }
    4815              :   else
    4816              :     {
    4817          148 :       *expr_p = error_mark_node;
    4818          148 :       return GS_ERROR;
    4819              :     }
    4820              : 
    4821              :   /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
    4822              :      decl.  This allows us to eliminate redundant or useless
    4823              :      calls to "const" functions.  */
    4824     16093401 :   if (TREE_CODE (*expr_p) == CALL_EXPR)
    4825              :     {
    4826     16093401 :       int flags = call_expr_flags (*expr_p);
    4827     16093401 :       if (flags & (ECF_CONST | ECF_PURE)
    4828              :           /* An infinite loop is considered a side effect.  */
    4829      2439141 :           && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
    4830      2066699 :         TREE_SIDE_EFFECTS (*expr_p) = 0;
    4831              :     }
    4832              : 
    4833              :   /* If the value is not needed by the caller, emit a new GIMPLE_CALL
    4834              :      and clear *EXPR_P.  Otherwise, leave *EXPR_P in its gimplified
    4835              :      form and delegate the creation of a GIMPLE_CALL to
    4836              :      gimplify_modify_expr.  This is always possible because when
    4837              :      WANT_VALUE is true, the caller wants the result of this call into
    4838              :      a temporary, which means that we will emit an INIT_EXPR in
    4839              :      internal_get_tmp_var which will then be handled by
    4840              :      gimplify_modify_expr.  */
    4841     16093401 :   if (!want_value)
    4842              :     {
    4843              :       /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
    4844              :          have to do is replicate it as a GIMPLE_CALL tuple.  */
    4845      6148687 :       gimple_stmt_iterator gsi;
    4846      6148687 :       call = gimple_build_call_from_tree (*expr_p, fnptrtype);
    4847      6148687 :       notice_special_calls (call);
    4848      6148687 :       gimplify_seq_add_stmt (pre_p, call);
    4849      6148687 :       gsi = gsi_last (*pre_p);
    4850      6148687 :       maybe_fold_stmt (&gsi);
    4851      6148687 :       *expr_p = NULL_TREE;
    4852              :     }
    4853              :   else
    4854              :     /* Remember the original function type.  */
    4855      9944714 :     CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
    4856      9944714 :                                      CALL_EXPR_FN (*expr_p));
    4857              : 
    4858              :   return ret;
    4859              : }
    4860              : 
    4861              : /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
    4862              :    rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
    4863              : 
    4864              :    TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
    4865              :    condition is true or false, respectively.  If null, we should generate
    4866              :    our own to skip over the evaluation of this specific expression.
    4867              : 
    4868              :    LOCUS is the source location of the COND_EXPR.
    4869              : 
    4870              :    The condition_uid is a discriminator tag for condition coverage used to map
    4871              :    conditions to its corresponding full Boolean function.
    4872              : 
    4873              :    This function is the tree equivalent of do_jump.
    4874              : 
    4875              :    shortcut_cond_r should only be called by shortcut_cond_expr.  */
    4876              : 
    4877              : static tree
    4878      1308126 : shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
    4879              :                  location_t locus, unsigned condition_uid)
    4880              : {
    4881      1308126 :   tree local_label = NULL_TREE;
    4882      1308126 :   tree t, expr = NULL;
    4883              : 
    4884              :   /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
    4885              :      retain the shortcut semantics.  Just insert the gotos here;
    4886              :      shortcut_cond_expr will append the real blocks later.  */
    4887      1308126 :   if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
    4888              :     {
    4889       120646 :       location_t new_locus;
    4890              : 
    4891              :       /* Turn if (a && b) into
    4892              : 
    4893              :          if (a); else goto no;
    4894              :          if (b) goto yes; else goto no;
    4895              :          (no:) */
    4896              : 
    4897       120646 :       if (false_label_p == NULL)
    4898         3981 :         false_label_p = &local_label;
    4899              : 
    4900              :       /* Keep the original source location on the first 'if'.  */
    4901       120646 :       t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus,
    4902              :                            condition_uid);
    4903       120646 :       append_to_statement_list (t, &expr);
    4904              : 
    4905              :       /* Set the source location of the && on the second 'if'.  */
    4906       120646 :       new_locus = rexpr_location (pred, locus);
    4907       120646 :       t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
    4908              :                            new_locus, condition_uid);
    4909       120646 :       append_to_statement_list (t, &expr);
    4910              :     }
    4911      1187480 :   else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
    4912              :     {
    4913       380858 :       location_t new_locus;
    4914              : 
    4915              :       /* Turn if (a || b) into
    4916              : 
    4917              :          if (a) goto yes;
    4918              :          if (b) goto yes; else goto no;
    4919              :          (yes:) */
    4920              : 
    4921       380858 :       if (true_label_p == NULL)
    4922       227736 :         true_label_p = &local_label;
    4923              : 
    4924              :       /* Keep the original source location on the first 'if'.  */
    4925       380858 :       t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus,
    4926              :                            condition_uid);
    4927       380858 :       append_to_statement_list (t, &expr);
    4928              : 
    4929              :       /* Set the source location of the || on the second 'if'.  */
    4930       380858 :       new_locus = rexpr_location (pred, locus);
    4931       380858 :       t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
    4932              :                            new_locus, condition_uid);
    4933       380858 :       append_to_statement_list (t, &expr);
    4934              :     }
    4935       806622 :   else if (TREE_CODE (pred) == COND_EXPR
    4936          852 :            && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
    4937       807474 :            && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
    4938              :     {
    4939          846 :       location_t new_locus;
    4940              : 
    4941              :       /* As long as we're messing with gotos, turn if (a ? b : c) into
    4942              :          if (a)
    4943              :            if (b) goto yes; else goto no;
    4944              :          else
    4945              :            if (c) goto yes; else goto no;
    4946              : 
    4947              :          Don't do this if one of the arms has void type, which can happen
    4948              :          in C++ when the arm is throw.  */
    4949              : 
    4950              :       /* Keep the original source location on the first 'if'.  Set the source
    4951              :          location of the ? on the second 'if'.  */
    4952          846 :       new_locus = rexpr_location (pred, locus);
    4953         1692 :       expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
    4954          846 :                      shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
    4955              :                                       false_label_p, locus, condition_uid),
    4956          846 :                      shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
    4957              :                                       false_label_p, new_locus,
    4958              :                                       condition_uid));
    4959          846 :       tree_associate_condition_with_expr (expr, condition_uid);
    4960              :     }
    4961              :   else
    4962              :     {
    4963       805776 :       expr = build3 (COND_EXPR, void_type_node, pred,
    4964              :                      build_and_jump (true_label_p),
    4965              :                      build_and_jump (false_label_p));
    4966       805776 :       SET_EXPR_LOCATION (expr, locus);
    4967       805776 :       tree_associate_condition_with_expr (expr, condition_uid);
    4968              :     }
    4969              : 
    4970      1308126 :   if (local_label)
    4971              :     {
    4972       231717 :       t = build1 (LABEL_EXPR, void_type_node, local_label);
    4973       231717 :       append_to_statement_list (t, &expr);
    4974              :     }
    4975              : 
    4976      1308126 :   return expr;
    4977              : }
    4978              : 
    4979              : /* If EXPR is a GOTO_EXPR, return it.  If it is a STATEMENT_LIST, skip
    4980              :    any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
    4981              :    statement, if it is the last one.  Otherwise, return NULL.  */
    4982              : 
    4983              : static tree
    4984     11454954 : find_goto (tree expr)
    4985              : {
    4986     11783268 :   if (!expr)
    4987              :     return NULL_TREE;
    4988              : 
    4989      9842738 :   if (TREE_CODE (expr) == GOTO_EXPR)
    4990              :     return expr;
    4991              : 
    4992      7857705 :   if (TREE_CODE (expr) != STATEMENT_LIST)
    4993              :     return NULL_TREE;
    4994              : 
    4995      1029513 :   tree_stmt_iterator i = tsi_start (expr);
    4996              : 
    4997      1383162 :   while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
    4998       353649 :     tsi_next (&i);
    4999              : 
    5000     10396113 :   if (!tsi_one_before_end_p (i))
    5001              :     return NULL_TREE;
    5002              : 
    5003       328314 :   return find_goto (tsi_stmt (i));
    5004              : }
    5005              : 
    5006              : /* Same as find_goto, except that it returns NULL if the destination
    5007              :    is not a LABEL_DECL.  */
    5008              : 
    5009              : static inline tree
    5010     11454954 : find_goto_label (tree expr)
    5011              : {
    5012     11454954 :   tree dest = find_goto (expr);
    5013     13439987 :   if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
    5014      1984922 :     return dest;
    5015              :   return NULL_TREE;
    5016              : }
    5017              : 
    5018              : 
    5019              : /* Given a multi-term condition (ANDIF, ORIF), walk the predicate PRED and tag
    5020              :    every basic condition with CONDITION_UID.  Two basic conditions share the
    5021              :    CONDITION_UID discriminator when they belong to the same predicate, which is
    5022              :    used by the condition coverage.  Doing this as an explicit step makes for a
    5023              :    simpler implementation than weaving it into the splitting code as the
    5024              :    splitting code eventually calls the entry point gimplfiy_expr which makes
    5025              :    bookkeeping complicated.  */
    5026              : static void
    5027       564813 : tag_shortcut_cond (tree pred, unsigned condition_uid)
    5028              : {
    5029       603642 :   if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR
    5030       603642 :       || TREE_CODE (pred) == TRUTH_ORIF_EXPR)
    5031              :     {
    5032       554593 :       tree fst = TREE_OPERAND (pred, 0);
    5033       554593 :       tree lst = TREE_OPERAND (pred, 1);
    5034              : 
    5035       554593 :       if (TREE_CODE (fst) == TRUTH_ANDIF_EXPR
    5036       554593 :           || TREE_CODE (fst) == TRUTH_ORIF_EXPR)
    5037       166922 :         tag_shortcut_cond (fst, condition_uid);
    5038       387671 :       else if (TREE_CODE (fst) == COND_EXPR)
    5039          244 :         tree_associate_condition_with_expr (fst, condition_uid);
    5040              : 
    5041       554593 :       if (TREE_CODE (lst) == TRUTH_ANDIF_EXPR
    5042       554593 :           || TREE_CODE (lst) == TRUTH_ORIF_EXPR)
    5043              :         tag_shortcut_cond (lst, condition_uid);
    5044       515764 :       else if (TREE_CODE (lst) == COND_EXPR)
    5045          445 :         tree_associate_condition_with_expr (lst, condition_uid);
    5046              :     }
    5047       564813 : }
    5048              : 
    5049              : /* Given a conditional expression EXPR with short-circuit boolean
    5050              :    predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
    5051              :    predicate apart into the equivalent sequence of conditionals.  CONDITION_UID
    5052              :    is a the tag/discriminator for this EXPR - all basic conditions in the
    5053              :    expression will be given the same CONDITION_UID.  */
    5054              : static tree
    5055       397891 : shortcut_cond_expr (tree expr, unsigned condition_uid)
    5056              : {
    5057       397891 :   tree pred = TREE_OPERAND (expr, 0);
    5058       397891 :   tree then_ = TREE_OPERAND (expr, 1);
    5059       397891 :   tree else_ = TREE_OPERAND (expr, 2);
    5060       397891 :   tree true_label, false_label, end_label, t;
    5061       397891 :   tree *true_label_p;
    5062       397891 :   tree *false_label_p;
    5063       397891 :   bool emit_end, emit_false, jump_over_else;
    5064       397891 :   bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
    5065       397891 :   bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
    5066              : 
    5067       397891 :   tag_shortcut_cond (pred, condition_uid);
    5068              : 
    5069              :   /* First do simple transformations.  */
    5070       397891 :   if (!else_se)
    5071              :     {
    5072              :       /* If there is no 'else', turn
    5073              :            if (a && b) then c
    5074              :          into
    5075              :            if (a) if (b) then c.  */
    5076       287851 :       while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
    5077              :         {
    5078              :           /* Keep the original source location on the first 'if'.  */
    5079        49904 :           location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
    5080        49904 :           TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
    5081              :           /* Set the source location of the && on the second 'if'.  */
    5082        49904 :           if (rexpr_has_location (pred))
    5083        48880 :             SET_EXPR_LOCATION (expr, rexpr_location (pred));
    5084        49904 :           then_ = shortcut_cond_expr (expr, condition_uid);
    5085        49904 :           then_se = then_ && TREE_SIDE_EFFECTS (then_);
    5086        49904 :           pred = TREE_OPERAND (pred, 0);
    5087        49904 :           expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
    5088        49904 :           SET_EXPR_LOCATION (expr, locus);
    5089              :         }
    5090              :     }
    5091              : 
    5092       397891 :   if (!then_se)
    5093              :     {
    5094              :       /* If there is no 'then', turn
    5095              :            if (a || b); else d
    5096              :          into
    5097              :            if (a); else if (b); else d.  */
    5098        25281 :       while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
    5099              :         {
    5100              :           /* Keep the original source location on the first 'if'.  */
    5101          795 :           location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
    5102          795 :           TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
    5103              :           /* Set the source location of the || on the second 'if'.  */
    5104          795 :           if (rexpr_has_location (pred))
    5105          794 :             SET_EXPR_LOCATION (expr, rexpr_location (pred));
    5106          795 :           else_ = shortcut_cond_expr (expr, condition_uid);
    5107          795 :           else_se = else_ && TREE_SIDE_EFFECTS (else_);
    5108          795 :           pred = TREE_OPERAND (pred, 0);
    5109          795 :           expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
    5110          795 :           SET_EXPR_LOCATION (expr, locus);
    5111              :         }
    5112              :     }
    5113              : 
    5114              :   /* The expr tree should also have the expression id set.  */
    5115       397891 :   tree_associate_condition_with_expr (expr, condition_uid);
    5116              : 
    5117              :   /* If we're done, great.  */
    5118       397891 :   if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
    5119       397891 :       && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
    5120        94465 :     return expr;
    5121              : 
    5122              :   /* Otherwise we need to mess with gotos.  Change
    5123              :        if (a) c; else d;
    5124              :      to
    5125              :        if (a); else goto no;
    5126              :        c; goto end;
    5127              :        no: d; end:
    5128              :      and recursively gimplify the condition.  */
    5129              : 
    5130       303426 :   true_label = false_label = end_label = NULL_TREE;
    5131              : 
    5132              :   /* If our arms just jump somewhere, hijack those labels so we don't
    5133              :      generate jumps to jumps.  */
    5134              : 
    5135       303426 :   if (tree then_goto = find_goto_label (then_))
    5136              :     {
    5137         4555 :       true_label = GOTO_DESTINATION (then_goto);
    5138         4555 :       then_ = NULL;
    5139         4555 :       then_se = false;
    5140              :     }
    5141              : 
    5142       303426 :   if (tree else_goto = find_goto_label (else_))
    5143              :     {
    5144         4148 :       false_label = GOTO_DESTINATION (else_goto);
    5145         4148 :       else_ = NULL;
    5146         4148 :       else_se = false;
    5147              :     }
    5148              : 
    5149              :   /* If we aren't hijacking a label for the 'then' branch, it falls through.  */
    5150       303426 :   if (true_label)
    5151              :     true_label_p = &true_label;
    5152              :   else
    5153       298871 :     true_label_p = NULL;
    5154              : 
    5155              :   /* The 'else' branch also needs a label if it contains interesting code.  */
    5156       303426 :   if (false_label || else_se)
    5157              :     false_label_p = &false_label;
    5158              :   else
    5159              :     false_label_p = NULL;
    5160              : 
    5161              :   /* If there was nothing else in our arms, just forward the label(s).  */
    5162       148597 :   if (!then_se && !else_se)
    5163         8440 :     return shortcut_cond_r (pred, true_label_p, false_label_p,
    5164        12660 :                             EXPR_LOC_OR_LOC (expr, input_location), condition_uid);
    5165              : 
    5166              :   /* If our last subexpression already has a terminal label, reuse it.  */
    5167       299206 :   if (else_se)
    5168       154829 :     t = expr_last (else_);
    5169       144377 :   else if (then_se)
    5170       144377 :     t = expr_last (then_);
    5171              :   else
    5172              :     t = NULL;
    5173       299206 :   if (t && TREE_CODE (t) == LABEL_EXPR)
    5174          963 :     end_label = LABEL_EXPR_LABEL (t);
    5175              : 
    5176              :   /* If we don't care about jumping to the 'else' branch, jump to the end
    5177              :      if the condition is false.  */
    5178       299206 :   if (!false_label_p)
    5179       144135 :     false_label_p = &end_label;
    5180              : 
    5181              :   /* We only want to emit these labels if we aren't hijacking them.  */
    5182       299206 :   emit_end = (end_label == NULL_TREE);
    5183       299206 :   emit_false = (false_label == NULL_TREE);
    5184              : 
    5185              :   /* We only emit the jump over the else clause if we have to--if the
    5186              :      then clause may fall through.  Otherwise we can wind up with a
    5187              :      useless jump and a useless label at the end of gimplified code,
    5188              :      which will cause us to think that this conditional as a whole
    5189              :      falls through even if it doesn't.  If we then inline a function
    5190              :      which ends with such a condition, that can cause us to issue an
    5191              :      inappropriate warning about control reaching the end of a
    5192              :      non-void function.  */
    5193       299206 :   jump_over_else = block_may_fallthru (then_);
    5194              : 
    5195       597789 :   pred = shortcut_cond_r (pred, true_label_p, false_label_p,
    5196       597789 :                           EXPR_LOC_OR_LOC (expr, input_location),
    5197              :                           condition_uid);
    5198              : 
    5199       299206 :   expr = NULL;
    5200       299206 :   append_to_statement_list (pred, &expr);
    5201              : 
    5202       299206 :   append_to_statement_list (then_, &expr);
    5203       299206 :   if (else_se)
    5204              :     {
    5205       154829 :       if (jump_over_else)
    5206              :         {
    5207       152379 :           tree last = expr_last (expr);
    5208       152379 :           t = build_and_jump (&end_label);
    5209       152379 :           if (rexpr_has_location (last))
    5210        37178 :             SET_EXPR_LOCATION (t, rexpr_location (last));
    5211       152379 :           append_to_statement_list (t, &expr);
    5212              :         }
    5213       154829 :       if (emit_false)
    5214              :         {
    5215       154829 :           t = build1 (LABEL_EXPR, void_type_node, false_label);
    5216       154829 :           append_to_statement_list (t, &expr);
    5217              :         }
    5218       154829 :       append_to_statement_list (else_, &expr);
    5219              :     }
    5220       299206 :   if (emit_end && end_label)
    5221              :     {
    5222       295556 :       t = build1 (LABEL_EXPR, void_type_node, end_label);
    5223       295556 :       append_to_statement_list (t, &expr);
    5224              :     }
    5225              : 
    5226       299206 :   return expr;
    5227              : }
    5228              : 
    5229              : /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE.  */
    5230              : 
    5231              : tree
    5232     16364196 : gimple_boolify (tree expr)
    5233              : {
    5234     16364196 :   tree type = TREE_TYPE (expr);
    5235     16364196 :   location_t loc = EXPR_LOCATION (expr);
    5236              : 
    5237     16364196 :   if (TREE_CODE (expr) == NE_EXPR
    5238      5667310 :       && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
    5239     17302170 :       && integer_zerop (TREE_OPERAND (expr, 1)))
    5240              :     {
    5241       484547 :       tree call = TREE_OPERAND (expr, 0);
    5242       484547 :       tree fn = get_callee_fndecl (call);
    5243              : 
    5244              :       /* For __builtin_expect ((long) (x), y) recurse into x as well
    5245              :          if x is truth_value_p.  */
    5246       484547 :       if (fn
    5247       483576 :           && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
    5248       617746 :           && call_expr_nargs (call) == 2)
    5249              :         {
    5250       133199 :           tree arg = CALL_EXPR_ARG (call, 0);
    5251       133199 :           if (arg)
    5252              :             {
    5253       133199 :               if (TREE_CODE (arg) == NOP_EXPR
    5254       133199 :                   && TREE_TYPE (arg) == TREE_TYPE (call))
    5255        62715 :                 arg = TREE_OPERAND (arg, 0);
    5256       133199 :               if (truth_value_p (TREE_CODE (arg)))
    5257              :                 {
    5258       110099 :                   arg = gimple_boolify (arg);
    5259       110099 :                   CALL_EXPR_ARG (call, 0)
    5260       220198 :                     = fold_convert_loc (loc, TREE_TYPE (call), arg);
    5261              :                 }
    5262              :             }
    5263              :         }
    5264              :     }
    5265              : 
    5266     16364196 :   switch (TREE_CODE (expr))
    5267              :     {
    5268      1215654 :     case TRUTH_AND_EXPR:
    5269      1215654 :     case TRUTH_OR_EXPR:
    5270      1215654 :     case TRUTH_XOR_EXPR:
    5271      1215654 :     case TRUTH_ANDIF_EXPR:
    5272      1215654 :     case TRUTH_ORIF_EXPR:
    5273              :       /* Also boolify the arguments of truth exprs.  */
    5274      1215654 :       TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
    5275              :       /* FALLTHRU */
    5276              : 
    5277      1635409 :     case TRUTH_NOT_EXPR:
    5278      1635409 :       TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
    5279              : 
    5280              :       /* These expressions always produce boolean results.  */
    5281      1635409 :       if (TREE_CODE (type) != BOOLEAN_TYPE)
    5282       306418 :         TREE_TYPE (expr) = boolean_type_node;
    5283              :       return expr;
    5284              : 
    5285         5222 :     case ANNOTATE_EXPR:
    5286         5222 :       switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
    5287              :         {
    5288         5222 :         case annot_expr_ivdep_kind:
    5289         5222 :         case annot_expr_unroll_kind:
    5290         5222 :         case annot_expr_no_vector_kind:
    5291         5222 :         case annot_expr_vector_kind:
    5292         5222 :         case annot_expr_parallel_kind:
    5293         5222 :         case annot_expr_maybe_infinite_kind:
    5294         5222 :           TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
    5295         5222 :           if (TREE_CODE (type) != BOOLEAN_TYPE)
    5296         3323 :             TREE_TYPE (expr) = boolean_type_node;
    5297              :           return expr;
    5298            0 :         default:
    5299            0 :           gcc_unreachable ();
    5300              :         }
    5301              : 
    5302     14723565 :     default:
    5303     14723565 :       if (COMPARISON_CLASS_P (expr))
    5304              :         {
    5305              :           /* These expressions always produce boolean results.  */
    5306     12885396 :           if (TREE_CODE (type) != BOOLEAN_TYPE)
    5307      1583153 :             TREE_TYPE (expr) = boolean_type_node;
    5308     12885396 :           return expr;
    5309              :         }
    5310              :       /* Other expressions that get here must have boolean values, but
    5311              :          might need to be converted to the appropriate mode.  */
    5312      1838169 :       if (TREE_CODE (type) == BOOLEAN_TYPE)
    5313              :         return expr;
    5314       202150 :       return fold_convert_loc (loc, boolean_type_node, expr);
    5315              :     }
    5316              : }
    5317              : 
    5318              : /* Given a conditional expression *EXPR_P without side effects, gimplify
    5319              :    its operands.  New statements are inserted to PRE_P.  */
    5320              : 
    5321              : static enum gimplify_status
    5322        46264 : gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
    5323              : {
    5324        46264 :   tree expr = *expr_p, cond;
    5325        46264 :   enum gimplify_status ret, tret;
    5326        46264 :   enum tree_code code;
    5327              : 
    5328        46264 :   cond = gimple_boolify (COND_EXPR_COND (expr));
    5329              : 
    5330              :   /* We need to handle && and || specially, as their gimplification
    5331              :      creates pure cond_expr, thus leading to an infinite cycle otherwise.  */
    5332        46264 :   code = TREE_CODE (cond);
    5333        46264 :   if (code == TRUTH_ANDIF_EXPR)
    5334           35 :     TREE_SET_CODE (cond, TRUTH_AND_EXPR);
    5335        46229 :   else if (code == TRUTH_ORIF_EXPR)
    5336         4641 :     TREE_SET_CODE (cond, TRUTH_OR_EXPR);
    5337        46264 :   ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_val, fb_rvalue);
    5338        46264 :   COND_EXPR_COND (*expr_p) = cond;
    5339              : 
    5340        46264 :   tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
    5341              :                         is_gimple_val, fb_rvalue);
    5342        46264 :   ret = MIN (ret, tret);
    5343        46264 :   tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
    5344              :                         is_gimple_val, fb_rvalue);
    5345              : 
    5346        46264 :   return MIN (ret, tret);
    5347              : }
    5348              : 
    5349              : /* Return true if evaluating EXPR could trap.
    5350              :    EXPR is GENERIC, while tree_could_trap_p can be called
    5351              :    only on GIMPLE.  */
    5352              : 
    5353              : bool
    5354     15876794 : generic_expr_could_trap_p (tree expr)
    5355              : {
    5356     15876794 :   unsigned i, n;
    5357              : 
    5358     15876794 :   if (!expr || is_gimple_val (expr))
    5359      7081227 :     return false;
    5360              : 
    5361      8795567 :   if (!EXPR_P (expr) || tree_could_trap_p (expr))
    5362      2319171 :     return true;
    5363              : 
    5364      6476396 :   n = TREE_OPERAND_LENGTH (expr);
    5365     15590159 :   for (i = 0; i < n; i++)
    5366     11276742 :     if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
    5367              :       return true;
    5368              : 
    5369              :   return false;
    5370              : }
    5371              : 
    5372              : /* Associate the condition STMT with the discriminator UID.  STMTs that are
    5373              :    broken down with ANDIF/ORIF from the same Boolean expression should be given
    5374              :    the same UID; 'if (a && b && c) { if (d || e) ... } ...' should yield the
    5375              :    { a: 1, b: 1, c: 1, d: 2, e: 2 } when gimplification is done.  This is used
    5376              :    for condition coverage.  */
    5377              : static void
    5378      5424051 : gimple_associate_condition_with_expr (struct function *fn, gcond *stmt,
    5379              :                                       unsigned uid)
    5380              : {
    5381      5424051 :   if (!condition_coverage_flag)
    5382              :     return;
    5383              : 
    5384          641 :   if (!fn->cond_uids)
    5385          139 :     fn->cond_uids = new hash_map <gcond*, unsigned> ();
    5386              : 
    5387          641 :   fn->cond_uids->put (stmt, uid);
    5388              : }
    5389              : 
    5390              : /*  Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
    5391              :     into
    5392              : 
    5393              :     if (p)                      if (p)
    5394              :       t1 = a;                     a;
    5395              :     else                or      else
    5396              :       t1 = b;                     b;
    5397              :     t1;
    5398              : 
    5399              :     The second form is used when *EXPR_P is of type void.
    5400              : 
    5401              :     PRE_P points to the list where side effects that must happen before
    5402              :       *EXPR_P should be stored.  */
    5403              : 
    5404              : static enum gimplify_status
    5405      6186388 : gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
    5406              : {
    5407      6186388 :   tree expr = *expr_p;
    5408      6186388 :   tree type = TREE_TYPE (expr);
    5409      6186388 :   location_t loc = EXPR_LOCATION (expr);
    5410      6186388 :   tree tmp, arm1, arm2;
    5411      6186388 :   enum gimplify_status ret;
    5412      6186388 :   tree label_true, label_false, label_cont;
    5413      6186388 :   bool have_then_clause_p, have_else_clause_p;
    5414      6186388 :   gcond *cond_stmt;
    5415      6186388 :   enum tree_code pred_code;
    5416      6186388 :   gimple_seq seq = NULL;
    5417              : 
    5418              :   /* If this COND_EXPR has a value, copy the values into a temporary within
    5419              :      the arms.  */
    5420      6186388 :   if (!VOID_TYPE_P (type))
    5421              :     {
    5422       414369 :       tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
    5423       414369 :       tree result;
    5424              : 
    5425              :       /* If either an rvalue is ok or we do not require an lvalue, create the
    5426              :          temporary.  But we cannot do that if the type is addressable.  */
    5427       414369 :       if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
    5428       414362 :           && !TREE_ADDRESSABLE (type))
    5429              :         {
    5430       414362 :           if (gimplify_ctxp->allow_rhs_cond_expr
    5431              :               /* If either branch has side effects or could trap, it can't be
    5432              :                  evaluated unconditionally.  */
    5433        46264 :               && !TREE_SIDE_EFFECTS (then_)
    5434        46264 :               && !generic_expr_could_trap_p (then_)
    5435        46264 :               && !TREE_SIDE_EFFECTS (else_)
    5436       460626 :               && !generic_expr_could_trap_p (else_))
    5437        46264 :             return gimplify_pure_cond_expr (expr_p, pre_p);
    5438              : 
    5439       368098 :           tmp = create_tmp_var (type, "iftmp");
    5440       368098 :           result = tmp;
    5441              :         }
    5442              : 
    5443              :       /* Otherwise, only create and copy references to the values.  */
    5444              :       else
    5445              :         {
    5446            7 :           type = build_pointer_type (type);
    5447              : 
    5448            7 :           if (!VOID_TYPE_P (TREE_TYPE (then_)))
    5449            7 :             then_ = build_fold_addr_expr_loc (loc, then_);
    5450              : 
    5451            7 :           if (!VOID_TYPE_P (TREE_TYPE (else_)))
    5452            7 :             else_ = build_fold_addr_expr_loc (loc, else_);
    5453              : 
    5454            7 :           expr
    5455            7 :             = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
    5456              : 
    5457            7 :           tmp = create_tmp_var (type, "iftmp");
    5458            7 :           result = build_simple_mem_ref_loc (loc, tmp);
    5459              :         }
    5460              : 
    5461              :       /* Build the new then clause, `tmp = then_;'.  But don't build the
    5462              :          assignment if the value is void; in C++ it can be if it's a throw.  */
    5463       368105 :       if (!VOID_TYPE_P (TREE_TYPE (then_)))
    5464       286545 :         TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
    5465              : 
    5466              :       /* Similarly, build the new else clause, `tmp = else_;'.  */
    5467       368105 :       if (!VOID_TYPE_P (TREE_TYPE (else_)))
    5468       357475 :         TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
    5469              : 
    5470       368105 :       TREE_TYPE (expr) = void_type_node;
    5471       368105 :       recalculate_side_effects (expr);
    5472              : 
    5473              :       /* Move the COND_EXPR to the prequeue.  */
    5474       368105 :       gimplify_stmt (&expr, pre_p);
    5475              : 
    5476       368105 :       *expr_p = result;
    5477       368105 :       return GS_ALL_DONE;
    5478              :     }
    5479              : 
    5480              :   /* Remove any COMPOUND_EXPR so the following cases will be caught.  */
    5481      5787266 :   STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
    5482      5772019 :   if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
    5483        80968 :     gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
    5484              : 
    5485              :   /* Make sure the condition has BOOLEAN_TYPE.  */
    5486      5772019 :   TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
    5487              : 
    5488              :   /* Break apart && and || conditions.  */
    5489      5772019 :   if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
    5490      5772019 :       || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
    5491              :     {
    5492       347192 :       expr = shortcut_cond_expr (expr, next_cond_uid ());
    5493              : 
    5494       347192 :       if (expr != *expr_p)
    5495              :         {
    5496       347192 :           *expr_p = expr;
    5497              : 
    5498              :           /* We can't rely on gimplify_expr to re-gimplify the expanded
    5499              :              form properly, as cleanups might cause the target labels to be
    5500              :              wrapped in a TRY_FINALLY_EXPR.  To prevent that, we need to
    5501              :              set up a conditional context.  */
    5502       347192 :           gimple_push_condition ();
    5503       347192 :           gimplify_stmt (expr_p, &seq);
    5504       347192 :           gimple_pop_condition (pre_p);
    5505       347192 :           gimple_seq_add_seq (pre_p, seq);
    5506              : 
    5507       347192 :           return GS_ALL_DONE;
    5508              :         }
    5509              :     }
    5510              : 
    5511              :   /* Now do the normal gimplification.  */
    5512              : 
    5513              :   /* Gimplify condition.  */
    5514      5424827 :   ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
    5515              :                        is_gimple_condexpr_for_cond, fb_rvalue);
    5516      5424827 :   if (ret == GS_ERROR)
    5517              :     return GS_ERROR;
    5518      5424051 :   gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
    5519              : 
    5520      5424051 :   gimple_push_condition ();
    5521              : 
    5522      5424051 :   have_then_clause_p = have_else_clause_p = false;
    5523      5424051 :   label_true = find_goto_label (TREE_OPERAND (expr, 1));
    5524      5424051 :   if (label_true
    5525      1268723 :       && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
    5526              :       /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
    5527              :          have different locations, otherwise we end up with incorrect
    5528              :          location information on the branches.  */
    5529      6692774 :       && (optimize
    5530       231903 :           || !EXPR_HAS_LOCATION (expr)
    5531       205035 :           || !rexpr_has_location (label_true)
    5532        71846 :           || EXPR_LOCATION (expr) == rexpr_location (label_true)))
    5533              :     {
    5534      1267563 :       have_then_clause_p = true;
    5535      1267563 :       label_true = GOTO_DESTINATION (label_true);
    5536              :     }
    5537              :   else
    5538      4156488 :     label_true = create_artificial_label (UNKNOWN_LOCATION);
    5539      5424051 :   label_false = find_goto_label (TREE_OPERAND (expr, 2));
    5540      5424051 :   if (label_false
    5541       707496 :       && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
    5542              :       /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
    5543              :          have different locations, otherwise we end up with incorrect
    5544              :          location information on the branches.  */
    5545      6131547 :       && (optimize
    5546       101626 :           || !EXPR_HAS_LOCATION (expr)
    5547       100748 :           || !rexpr_has_location (label_false)
    5548          157 :           || EXPR_LOCATION (expr) == rexpr_location (label_false)))
    5549              :     {
    5550       707351 :       have_else_clause_p = true;
    5551       707351 :       label_false = GOTO_DESTINATION (label_false);
    5552              :     }
    5553              :   else
    5554      4716700 :     label_false = create_artificial_label (UNKNOWN_LOCATION);
    5555              : 
    5556      5424051 :   unsigned cond_uid = 0;
    5557      5424051 :   if (cond_uids)
    5558          455 :     if (unsigned *v = cond_uids->get (expr))
    5559          435 :       cond_uid = *v;
    5560          435 :   if (cond_uid == 0)
    5561      5423616 :     cond_uid = next_cond_uid ();
    5562              : 
    5563      5424051 :   gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
    5564              :                                  &arm2);
    5565      5424051 :   cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
    5566              :                                  label_false);
    5567      5424051 :   gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
    5568      5424051 :   gimple_associate_condition_with_expr (cfun, cond_stmt, cond_uid);
    5569      5424051 :   copy_warning (cond_stmt, COND_EXPR_COND (expr));
    5570      5424051 :   gimplify_seq_add_stmt (&seq, cond_stmt);
    5571      5424051 :   gimple_stmt_iterator gsi = gsi_last (seq);
    5572      5424051 :   maybe_fold_stmt (&gsi);
    5573              : 
    5574      5424051 :   label_cont = NULL_TREE;
    5575      5424051 :   if (!have_then_clause_p)
    5576              :     {
    5577              :       /* For if (...) {} else { code; } put label_true after
    5578              :          the else block.  */
    5579      4156488 :       if (TREE_OPERAND (expr, 1) == NULL_TREE
    5580       193899 :           && !have_else_clause_p
    5581      4157256 :           && TREE_OPERAND (expr, 2) != NULL_TREE)
    5582              :         {
    5583              :           /* For if (0) {} else { code; } tell -Wimplicit-fallthrough
    5584              :              handling that label_cont == label_true can be only reached
    5585              :              through fallthrough from { code; }.  */
    5586          768 :           if (integer_zerop (COND_EXPR_COND (expr)))
    5587            0 :             UNUSED_LABEL_P (label_true) = 1;
    5588              :           label_cont = label_true;
    5589              :         }
    5590              :       else
    5591              :         {
    5592      4155720 :           bool then_side_effects
    5593      4155720 :             = (TREE_OPERAND (expr, 1)
    5594      4155720 :                && TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)));
    5595      4155720 :           gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
    5596      4155720 :           have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
    5597              :           /* For if (...) { code; } else {} or
    5598              :              if (...) { code; } else goto label; or
    5599              :              if (...) { code; return; } else { ... }
    5600              :              label_cont isn't needed.  */
    5601      4155720 :           if (!have_else_clause_p
    5602      3961443 :               && TREE_OPERAND (expr, 2) != NULL_TREE
    5603      6900141 :               && gimple_seq_may_fallthru (seq))
    5604              :             {
    5605      1911571 :               gimple *g;
    5606      1911571 :               label_cont = create_artificial_label (UNKNOWN_LOCATION);
    5607              : 
    5608              :               /* For if (0) { non-side-effect-code } else { code }
    5609              :                  tell -Wimplicit-fallthrough handling that label_cont can
    5610              :                  be only reached through fallthrough from { code }.  */
    5611      1911571 :               if (integer_zerop (COND_EXPR_COND (expr)))
    5612              :                 {
    5613        72707 :                   UNUSED_LABEL_P (label_true) = 1;
    5614        72707 :                   if (!then_side_effects)
    5615        12081 :                     UNUSED_LABEL_P (label_cont) = 1;
    5616              :                 }
    5617              : 
    5618      1911571 :               g = gimple_build_goto (label_cont);
    5619              : 
    5620              :               /* GIMPLE_COND's are very low level; they have embedded
    5621              :                  gotos.  This particular embedded goto should not be marked
    5622              :                  with the location of the original COND_EXPR, as it would
    5623              :                  correspond to the COND_EXPR's condition, not the ELSE or the
    5624              :                  THEN arms.  To avoid marking it with the wrong location, flag
    5625              :                  it as "no location".  */
    5626      1911571 :               gimple_set_do_not_emit_location (g);
    5627              : 
    5628      1911571 :               gimplify_seq_add_stmt (&seq, g);
    5629              :             }
    5630              :         }
    5631              :     }
    5632      5424051 :   if (!have_else_clause_p)
    5633              :     {
    5634              :       /* For if (1) { code } or if (1) { code } else { non-side-effect-code }
    5635              :          tell -Wimplicit-fallthrough handling that label_false can be only
    5636              :          reached through fallthrough from { code }.  */
    5637      4716700 :       if (integer_nonzerop (COND_EXPR_COND (expr))
    5638      4716700 :           && (TREE_OPERAND (expr, 2) == NULL_TREE
    5639        56684 :               || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2))))
    5640         7039 :         UNUSED_LABEL_P (label_false) = 1;
    5641      4716700 :       gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
    5642      4716700 :       have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
    5643              :     }
    5644      5424051 :   if (label_cont)
    5645      1912339 :     gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
    5646              : 
    5647      5424051 :   gimple_pop_condition (pre_p);
    5648      5424051 :   gimple_seq_add_seq (pre_p, seq);
    5649              : 
    5650      5424051 :   if (ret == GS_ERROR)
    5651              :     ; /* Do nothing.  */
    5652      5424051 :   else if (have_then_clause_p || have_else_clause_p)
    5653              :     ret = GS_ALL_DONE;
    5654              :   else
    5655              :     {
    5656              :       /* Both arms are empty; replace the COND_EXPR with its predicate.  */
    5657         2761 :       expr = TREE_OPERAND (expr, 0);
    5658         2761 :       gimplify_stmt (&expr, pre_p);
    5659              :     }
    5660              : 
    5661      5424051 :   *expr_p = NULL;
    5662      5424051 :   return ret;
    5663              : }
    5664              : 
    5665              : /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
    5666              :    to be marked addressable.
    5667              : 
    5668              :    We cannot rely on such an expression being directly markable if a temporary
    5669              :    has been created by the gimplification.  In this case, we create another
    5670              :    temporary and initialize it with a copy, which will become a store after we
    5671              :    mark it addressable.  This can happen if the front-end passed us something
    5672              :    that it could not mark addressable yet, like a Fortran pass-by-reference
    5673              :    parameter (int) floatvar.  */
    5674              : 
    5675              : static void
    5676     54773279 : prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
    5677              : {
    5678     60052419 :   while (handled_component_p (*expr_p))
    5679      5279140 :     expr_p = &TREE_OPERAND (*expr_p, 0);
    5680              : 
    5681              :   /* Do not allow an SSA name as the temporary.  */
    5682     54773279 :   if (is_gimple_reg (*expr_p))
    5683        12021 :     *expr_p = internal_get_tmp_var (*expr_p, seq_p, NULL, false, false, true);
    5684     54773279 : }
    5685              : 
    5686              : /* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
    5687              :    a call to __builtin_memcpy.  */
    5688              : 
    5689              : static enum gimplify_status
    5690         1106 : gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
    5691              :                                 gimple_seq *seq_p)
    5692              : {
    5693         1106 :   tree t, to, to_ptr, from, from_ptr;
    5694         1106 :   gcall *gs;
    5695         1106 :   location_t loc = EXPR_LOCATION (*expr_p);
    5696              : 
    5697         1106 :   to = TREE_OPERAND (*expr_p, 0);
    5698         1106 :   from = TREE_OPERAND (*expr_p, 1);
    5699         1106 :   gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to)))
    5700              :               && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from))));
    5701              : 
    5702              :   /* Mark the RHS addressable.  Beware that it may not be possible to do so
    5703              :      directly if a temporary has been created by the gimplification.  */
    5704         1106 :   prepare_gimple_addressable (&from, seq_p);
    5705              : 
    5706         1106 :   mark_addressable (from);
    5707         1106 :   from_ptr = build_fold_addr_expr_loc (loc, from);
    5708         1106 :   gimplify_arg (&from_ptr, seq_p, loc);
    5709              : 
    5710         1106 :   mark_addressable (to);
    5711         1106 :   to_ptr = build_fold_addr_expr_loc (loc, to);
    5712         1106 :   gimplify_arg (&to_ptr, seq_p, loc);
    5713              : 
    5714         1106 :   t = builtin_decl_implicit (BUILT_IN_MEMCPY);
    5715              : 
    5716         1106 :   gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
    5717         1106 :   gimple_call_set_alloca_for_var (gs, true);
    5718              : 
    5719         1106 :   if (want_value)
    5720              :     {
    5721              :       /* tmp = memcpy() */
    5722            8 :       t = create_tmp_var (TREE_TYPE (to_ptr));
    5723            8 :       gimple_call_set_lhs (gs, t);
    5724            8 :       gimplify_seq_add_stmt (seq_p, gs);
    5725              : 
    5726            8 :       *expr_p = build_simple_mem_ref (t);
    5727            8 :       return GS_ALL_DONE;
    5728              :     }
    5729              : 
    5730         1098 :   gimplify_seq_add_stmt (seq_p, gs);
    5731         1098 :   *expr_p = NULL;
    5732         1098 :   return GS_ALL_DONE;
    5733              : }
    5734              : 
    5735              : /* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
    5736              :    a call to __builtin_memset.  In this case we know that the RHS is
    5737              :    a CONSTRUCTOR with an empty element list.  */
    5738              : 
    5739              : static enum gimplify_status
    5740           84 : gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
    5741              :                                 gimple_seq *seq_p)
    5742              : {
    5743           84 :   tree t, from, to, to_ptr;
    5744           84 :   gcall *gs;
    5745           84 :   location_t loc = EXPR_LOCATION (*expr_p);
    5746              : 
    5747              :   /* Assert our assumptions, to abort instead of producing wrong code
    5748              :      silently if they are not met.  Beware that the RHS CONSTRUCTOR might
    5749              :      not be immediately exposed.  */
    5750           84 :   from = TREE_OPERAND (*expr_p, 1);
    5751           84 :   if (TREE_CODE (from) == WITH_SIZE_EXPR)
    5752           84 :     from = TREE_OPERAND (from, 0);
    5753              : 
    5754           84 :   gcc_assert (TREE_CODE (from) == CONSTRUCTOR
    5755              :               && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
    5756              : 
    5757              :   /* Now proceed.  */
    5758           84 :   to = TREE_OPERAND (*expr_p, 0);
    5759           84 :   gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to))));
    5760              : 
    5761           84 :   to_ptr = build_fold_addr_expr_loc (loc, to);
    5762           84 :   gimplify_arg (&to_ptr, seq_p, loc);
    5763           84 :   t = builtin_decl_implicit (BUILT_IN_MEMSET);
    5764              : 
    5765           84 :   gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
    5766              : 
    5767           84 :   if (want_value)
    5768              :     {
    5769              :       /* tmp = memset() */
    5770            0 :       t = create_tmp_var (TREE_TYPE (to_ptr));
    5771            0 :       gimple_call_set_lhs (gs, t);
    5772            0 :       gimplify_seq_add_stmt (seq_p, gs);
    5773              : 
    5774            0 :       *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
    5775            0 :       return GS_ALL_DONE;
    5776              :     }
    5777              : 
    5778           84 :   gimplify_seq_add_stmt (seq_p, gs);
    5779           84 :   *expr_p = NULL;
    5780           84 :   return GS_ALL_DONE;
    5781              : }
    5782              : 
    5783              : /* A subroutine of gimplify_init_ctor_preeval.  Called via walk_tree,
    5784              :    determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
    5785              :    assignment.  Return non-null if we detect a potential overlap.  */
    5786              : 
    5787              : struct gimplify_init_ctor_preeval_data
    5788              : {
    5789              :   /* The base decl of the lhs object.  May be NULL, in which case we
    5790              :      have to assume the lhs is indirect.  */
    5791              :   tree lhs_base_decl;
    5792              : 
    5793              :   /* The alias set of the lhs object.  */
    5794              :   alias_set_type lhs_alias_set;
    5795              : };
    5796              : 
    5797              : static tree
    5798       116067 : gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
    5799              : {
    5800       116067 :   struct gimplify_init_ctor_preeval_data *data
    5801              :     = (struct gimplify_init_ctor_preeval_data *) xdata;
    5802       116067 :   tree t = *tp;
    5803              : 
    5804              :   /* If we find the base object, obviously we have overlap.  */
    5805       116067 :   if (data->lhs_base_decl == t)
    5806              :     return t;
    5807              : 
    5808              :   /* If the constructor component is indirect, determine if we have a
    5809              :      potential overlap with the lhs.  The only bits of information we
    5810              :      have to go on at this point are addressability and alias sets.  */
    5811       116066 :   if ((INDIRECT_REF_P (t)
    5812       116066 :        || TREE_CODE (t) == MEM_REF)
    5813          651 :       && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
    5814       116582 :       && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
    5815              :     return t;
    5816              : 
    5817              :   /* If the constructor component is a call, determine if it can hide a
    5818              :      potential overlap with the lhs through an INDIRECT_REF like above.
    5819              :      ??? Ugh - this is completely broken.  In fact this whole analysis
    5820              :      doesn't look conservative.  */
    5821       115550 :   if (TREE_CODE (t) == CALL_EXPR)
    5822              :     {
    5823            0 :       tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
    5824              : 
    5825            0 :       for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
    5826            0 :         if (POINTER_TYPE_P (TREE_VALUE (type))
    5827            0 :             && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
    5828            0 :             && alias_sets_conflict_p (data->lhs_alias_set,
    5829              :                                       get_alias_set
    5830            0 :                                         (TREE_TYPE (TREE_VALUE (type)))))
    5831              :           return t;
    5832              :     }
    5833              : 
    5834       115550 :   if (IS_TYPE_OR_DECL_P (t))
    5835        10968 :     *walk_subtrees = 0;
    5836              :   return NULL;
    5837              : }
    5838              : 
    5839              : /* A subroutine of gimplify_init_constructor.  Pre-evaluate EXPR,
    5840              :    force values that overlap with the lhs (as described by *DATA)
    5841              :    into temporaries.  */
    5842              : 
    5843              : static void
    5844       413037 : gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
    5845              :                             struct gimplify_init_ctor_preeval_data *data)
    5846              : {
    5847       413037 :   enum gimplify_status one;
    5848              : 
    5849              :   /* If the value is constant, then there's nothing to pre-evaluate.  */
    5850       413037 :   if (TREE_CONSTANT (*expr_p))
    5851              :     {
    5852              :       /* Ensure it does not have side effects, it might contain a reference to
    5853              :          the object we're initializing.  */
    5854       195599 :       gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
    5855              :       return;
    5856              :     }
    5857              : 
    5858              :   /* If the type has non-trivial constructors, we can't pre-evaluate.  */
    5859       217438 :   if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
    5860              :     return;
    5861              : 
    5862              :   /* Recurse for nested constructors.  */
    5863       217438 :   if (TREE_CODE (*expr_p) == CONSTRUCTOR)
    5864              :     {
    5865        73614 :       unsigned HOST_WIDE_INT ix;
    5866        73614 :       constructor_elt *ce;
    5867        73614 :       vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
    5868              : 
    5869       270973 :       FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
    5870       197359 :         gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
    5871              : 
    5872              :       return;
    5873              :     }
    5874              : 
    5875              :   /* If this is a variable sized type, we must remember the size.  */
    5876       143824 :   maybe_with_size_expr (expr_p);
    5877              : 
    5878              :   /* Gimplify the constructor element to something appropriate for the rhs
    5879              :      of a MODIFY_EXPR.  Given that we know the LHS is an aggregate, we know
    5880              :      the gimplifier will consider this a store to memory.  Doing this
    5881              :      gimplification now means that we won't have to deal with complicated
    5882              :      language-specific trees, nor trees like SAVE_EXPR that can induce
    5883              :      exponential search behavior.  */
    5884       143824 :   one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
    5885       143824 :   if (one == GS_ERROR)
    5886              :     {
    5887            0 :       *expr_p = NULL;
    5888            0 :       return;
    5889              :     }
    5890              : 
    5891              :   /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
    5892              :      with the lhs, since "a = { .x=a }" doesn't make sense.  This will
    5893              :      always be true for all scalars, since is_gimple_mem_rhs insists on a
    5894              :      temporary variable for them.  */
    5895       143824 :   if (DECL_P (*expr_p))
    5896              :     return;
    5897              : 
    5898              :   /* If this is of variable size, we have no choice but to assume it doesn't
    5899              :      overlap since we can't make a temporary for it.  */
    5900       104503 :   if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
    5901              :     return;
    5902              : 
    5903              :   /* Otherwise, we must search for overlap ...  */
    5904       104503 :   if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
    5905              :     return;
    5906              : 
    5907              :   /* ... and if found, force the value into a temporary.  */
    5908          517 :   *expr_p = get_formal_tmp_var (*expr_p, pre_p);
    5909              : }
    5910              : 
    5911              : /* A subroutine of gimplify_init_ctor_eval.  Create a loop for
    5912              :    a RANGE_EXPR in a CONSTRUCTOR for an array.
    5913              : 
    5914              :       var = lower;
    5915              :     loop_entry:
    5916              :       object[var] = value;
    5917              :       if (var == upper)
    5918              :         goto loop_exit;
    5919              :       var = var + 1;
    5920              :       goto loop_entry;
    5921              :     loop_exit:
    5922              : 
    5923              :    We increment var _after_ the loop exit check because we might otherwise
    5924              :    fail if upper == TYPE_MAX_VALUE (type for upper).
    5925              : 
    5926              :    Note that we never have to deal with SAVE_EXPRs here, because this has
    5927              :    already been taken care of for us, in gimplify_init_ctor_preeval().  */
    5928              : 
    5929              : static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
    5930              :                                      gimple_seq *, bool);
    5931              : 
    5932              : static void
    5933          437 : gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
    5934              :                                tree value, tree array_elt_type,
    5935              :                                gimple_seq *pre_p, bool cleared)
    5936              : {
    5937          437 :   tree loop_entry_label, loop_exit_label, fall_thru_label;
    5938          437 :   tree var, var_type, cref, tmp;
    5939              : 
    5940          437 :   loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
    5941          437 :   loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
    5942          437 :   fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
    5943              : 
    5944              :   /* Create and initialize the index variable.  */
    5945          437 :   var_type = TREE_TYPE (upper);
    5946          437 :   var = create_tmp_var (var_type);
    5947          437 :   gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
    5948              : 
    5949              :   /* Add the loop entry label.  */
    5950          437 :   gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
    5951              : 
    5952              :   /* Build the reference.  */
    5953          437 :   cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
    5954              :                  var, NULL_TREE, NULL_TREE);
    5955              : 
    5956              :   /* If we are a constructor, just call gimplify_init_ctor_eval to do
    5957              :      the store.  Otherwise just assign value to the reference.  */
    5958              : 
    5959          437 :   if (TREE_CODE (value) == CONSTRUCTOR)
    5960              :     /* NB we might have to call ourself recursively through
    5961              :        gimplify_init_ctor_eval if the value is a constructor.  */
    5962          120 :     gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
    5963              :                              pre_p, cleared);
    5964              :   else
    5965              :     {
    5966          317 :       if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
    5967              :           != GS_ERROR)
    5968          317 :         gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
    5969              :     }
    5970              : 
    5971              :   /* We exit the loop when the index var is equal to the upper bound.  */
    5972          874 :   gimplify_seq_add_stmt (pre_p,
    5973          437 :                          gimple_build_cond (EQ_EXPR, var, upper,
    5974              :                                             loop_exit_label, fall_thru_label));
    5975              : 
    5976          437 :   gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
    5977              : 
    5978              :   /* Otherwise, increment the index var...  */
    5979          437 :   tmp = build2 (PLUS_EXPR, var_type, var,
    5980              :                 fold_convert (var_type, integer_one_node));
    5981          437 :   gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
    5982              : 
    5983              :   /* ...and jump back to the loop entry.  */
    5984          437 :   gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
    5985              : 
    5986              :   /* Add the loop exit label.  */
    5987          437 :   gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
    5988          437 : }
    5989              : 
    5990              : /* A subroutine of gimplify_init_constructor.  Generate individual
    5991              :    MODIFY_EXPRs for a CONSTRUCTOR.  OBJECT is the LHS against which the
    5992              :    assignments should happen.  ELTS is the CONSTRUCTOR_ELTS of the
    5993              :    CONSTRUCTOR.  CLEARED is true if the entire LHS object has been
    5994              :    zeroed first.  */
    5995              : 
    5996              : static void
    5997      1234701 : gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
    5998              :                          gimple_seq *pre_p, bool cleared)
    5999              : {
    6000      1234701 :   tree array_elt_type = NULL;
    6001      1234701 :   unsigned HOST_WIDE_INT ix;
    6002      1234701 :   tree purpose, value;
    6003              : 
    6004      1234701 :   if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
    6005       139252 :     array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
    6006              : 
    6007      4590192 :   FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
    6008              :     {
    6009      3355491 :       tree cref;
    6010              : 
    6011              :       /* NULL values are created above for gimplification errors.  */
    6012      3355491 :       if (value == NULL)
    6013       317673 :         continue;
    6014              : 
    6015      3355491 :       if (cleared && initializer_zerop (value))
    6016       317074 :         continue;
    6017              : 
    6018              :       /* ??? Here's to hoping the front end fills in all of the indices,
    6019              :          so we don't have to figure out what's missing ourselves.  */
    6020      3038417 :       gcc_assert (purpose);
    6021              : 
    6022              :       /* Skip zero-sized fields, unless value has side-effects.  This can
    6023              :          happen with calls to functions returning a empty type, which
    6024              :          we shouldn't discard.  As a number of downstream passes don't
    6025              :          expect sets of empty type fields, we rely on the gimplification of
    6026              :          the MODIFY_EXPR we make below to drop the assignment statement.  */
    6027      3038417 :       if (!TREE_SIDE_EFFECTS (value)
    6028      2745679 :           && TREE_CODE (purpose) == FIELD_DECL
    6029      5319447 :           && is_empty_type (TREE_TYPE (purpose)))
    6030          162 :         continue;
    6031              : 
    6032              :       /* If we have a RANGE_EXPR, we have to build a loop to assign the
    6033              :          whole range.  */
    6034      3038255 :       if (TREE_CODE (purpose) == RANGE_EXPR)
    6035              :         {
    6036          447 :           tree lower = TREE_OPERAND (purpose, 0);
    6037          447 :           tree upper = TREE_OPERAND (purpose, 1);
    6038              : 
    6039              :           /* If the lower bound is equal to upper, just treat it as if
    6040              :              upper was the index.  */
    6041          447 :           if (simple_cst_equal (lower, upper))
    6042              :             purpose = upper;
    6043              :           else
    6044              :             {
    6045          437 :               gimplify_init_ctor_eval_range (object, lower, upper, value,
    6046              :                                              array_elt_type, pre_p, cleared);
    6047          437 :               continue;
    6048              :             }
    6049              :         }
    6050              : 
    6051      3037818 :       if (array_elt_type)
    6052              :         {
    6053              :           /* Do not use bitsizetype for ARRAY_REF indices.  */
    6054       554655 :           if (TYPE_DOMAIN (TREE_TYPE (object)))
    6055       554655 :             purpose
    6056       554655 :               = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
    6057              :                               purpose);
    6058       554655 :           cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
    6059              :                          purpose, NULL_TREE, NULL_TREE);
    6060              :         }
    6061              :       else
    6062              :         {
    6063      2483163 :           gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
    6064      2483163 :           cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
    6065              :                          unshare_expr (object), purpose, NULL_TREE);
    6066              :         }
    6067              : 
    6068      3037818 :       if (TREE_CODE (value) == CONSTRUCTOR
    6069      3037818 :           && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
    6070       291086 :         gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
    6071              :                                  pre_p, cleared);
    6072      2746732 :       else if (TREE_CODE (value) == RAW_DATA_CST)
    6073              :         {
    6074           43 :           if (RAW_DATA_LENGTH (value) <= 32)
    6075              :             {
    6076           13 :               for (unsigned int i = 0; i < (unsigned) RAW_DATA_LENGTH (value);
    6077              :                    ++i)
    6078           12 :                 if (!cleared || RAW_DATA_POINTER (value)[i])
    6079              :                   {
    6080           12 :                     if (i)
    6081              :                       {
    6082           11 :                         tree p
    6083           11 :                           = fold_build2 (PLUS_EXPR, TREE_TYPE (purpose),
    6084              :                                          purpose,
    6085              :                                          build_int_cst (TREE_TYPE (purpose),
    6086              :                                                         i));
    6087           11 :                         cref = build4 (ARRAY_REF, array_elt_type,
    6088              :                                        unshare_expr (object), p, NULL_TREE,
    6089              :                                        NULL_TREE);
    6090              :                       }
    6091           12 :                     tree init
    6092           12 :                       = build2 (INIT_EXPR, TREE_TYPE (cref), cref,
    6093           12 :                                 build_int_cst (TREE_TYPE (value),
    6094           12 :                                                RAW_DATA_UCHAR_ELT (value, i)));
    6095           12 :                     gimplify_and_add (init, pre_p);
    6096           12 :                     ggc_free (init);
    6097              :                   }
    6098              :             }
    6099              :           else
    6100              :             {
    6101           42 :               tree rtype = build_array_type_nelts (TREE_TYPE (value),
    6102           42 :                                                    RAW_DATA_LENGTH (value));
    6103           42 :               tree rctor = build_constructor_single (rtype, bitsize_zero_node,
    6104              :                                                      value);
    6105           42 :               tree addr = build_fold_addr_expr (cref);
    6106           42 :               cref = build2 (MEM_REF, rtype, addr,
    6107              :                              build_int_cst (ptr_type_node, 0));
    6108           42 :               rctor = tree_output_constant_def (rctor);
    6109           42 :               if (!useless_type_conversion_p (rtype, TREE_TYPE (rctor)))
    6110            4 :                 rctor = build1 (VIEW_CONVERT_EXPR, rtype, rctor);
    6111           42 :               if (gimplify_expr (&cref, pre_p, NULL, is_gimple_lvalue,
    6112              :                                  fb_lvalue) != GS_ERROR)
    6113           84 :                 gimplify_seq_add_stmt (pre_p,
    6114           42 :                                        gimple_build_assign (cref, rctor));
    6115              :             }
    6116              :         }
    6117              :       else
    6118              :         {
    6119      2746689 :           tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
    6120      2746689 :           gimplify_and_add (init, pre_p);
    6121      2746689 :           ggc_free (init);
    6122              :         }
    6123              :     }
    6124      1234701 : }
    6125              : 
    6126              : /* Return the appropriate RHS predicate for this LHS.  */
    6127              : 
    6128              : gimple_predicate
    6129     48428227 : rhs_predicate_for (tree lhs)
    6130              : {
    6131     48428227 :   if (is_gimple_reg (lhs))
    6132              :     return is_gimple_reg_rhs_or_call;
    6133              :   else
    6134     11384935 :     return is_gimple_mem_rhs_or_call;
    6135              : }
    6136              : 
    6137              : /* Return the initial guess for an appropriate RHS predicate for this LHS,
    6138              :    before the LHS has been gimplified.  */
    6139              : 
    6140              : static gimple_predicate
    6141     47301476 : initial_rhs_predicate_for (tree lhs)
    6142              : {
    6143     47301476 :   if (is_gimple_reg_type (TREE_TYPE (lhs)))
    6144              :     return is_gimple_reg_rhs_or_call;
    6145              :   else
    6146      2354251 :     return is_gimple_mem_rhs_or_call;
    6147              : }
    6148              : 
    6149              : /* Gimplify a C99 compound literal expression.  This just means adding
    6150              :    the DECL_EXPR before the current statement and using its anonymous
    6151              :    decl instead.  */
    6152              : 
    6153              : static enum gimplify_status
    6154        37190 : gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
    6155              :                                 bool (*gimple_test_f) (tree),
    6156              :                                 fallback_t fallback)
    6157              : {
    6158        37190 :   tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
    6159        37190 :   tree decl = DECL_EXPR_DECL (decl_s);
    6160        37190 :   tree init = DECL_INITIAL (decl);
    6161              :   /* Mark the decl as addressable if the compound literal
    6162              :      expression is addressable now, otherwise it is marked too late
    6163              :      after we gimplify the initialization expression.  */
    6164        37190 :   if (TREE_ADDRESSABLE (*expr_p))
    6165          542 :     TREE_ADDRESSABLE (decl) = 1;
    6166              :   /* Otherwise, if we don't need an lvalue and have a literal directly
    6167              :      substitute it.  Check if it matches the gimple predicate, as
    6168              :      otherwise we'd generate a new temporary, and we can as well just
    6169              :      use the decl we already have.  */
    6170        36648 :   else if (!TREE_ADDRESSABLE (decl)
    6171        36648 :            && !TREE_THIS_VOLATILE (decl)
    6172        36643 :            && init
    6173        36635 :            && (fallback & fb_lvalue) == 0
    6174        73131 :            && gimple_test_f (init))
    6175              :     {
    6176        35395 :       *expr_p = init;
    6177        35395 :       return GS_OK;
    6178              :     }
    6179              : 
    6180              :   /* If the decl is not addressable, then it is being used in some
    6181              :      expression or on the right hand side of a statement, and it can
    6182              :      be put into a readonly data section.  */
    6183         1795 :   if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
    6184         1093 :     TREE_READONLY (decl) = 1;
    6185              : 
    6186              :   /* This decl isn't mentioned in the enclosing block, so add it to the
    6187              :      list of temps.  FIXME it seems a bit of a kludge to say that
    6188              :      anonymous artificial vars aren't pushed, but everything else is.  */
    6189         1795 :   if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
    6190            2 :     gimple_add_tmp_var (decl);
    6191              : 
    6192         1795 :   gimplify_and_add (decl_s, pre_p);
    6193         1795 :   *expr_p = decl;
    6194         1795 :   return GS_OK;
    6195              : }
    6196              : 
    6197              : /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
    6198              :    return a new CONSTRUCTOR if something changed.  */
    6199              : 
    6200              : static tree
    6201      1836632 : optimize_compound_literals_in_ctor (tree orig_ctor)
    6202              : {
    6203      1836632 :   tree ctor = orig_ctor;
    6204      1836632 :   vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
    6205      1836632 :   unsigned int idx, num = vec_safe_length (elts);
    6206              : 
    6207      6140241 :   for (idx = 0; idx < num; idx++)
    6208              :     {
    6209      4303609 :       tree value = (*elts)[idx].value;
    6210      4303609 :       tree newval = value;
    6211      4303609 :       if (TREE_CODE (value) == CONSTRUCTOR)
    6212       528025 :         newval = optimize_compound_literals_in_ctor (value);
    6213      3775584 :       else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
    6214              :         {
    6215          103 :           tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
    6216          103 :           tree decl = DECL_EXPR_DECL (decl_s);
    6217          103 :           tree init = DECL_INITIAL (decl);
    6218              : 
    6219          103 :           if (!TREE_ADDRESSABLE (value)
    6220          103 :               && !TREE_ADDRESSABLE (decl)
    6221          103 :               && init
    6222          103 :               && TREE_CODE (init) == CONSTRUCTOR)
    6223           52 :             newval = optimize_compound_literals_in_ctor (init);
    6224              :         }
    6225      4303609 :       if (newval == value)
    6226      4303549 :         continue;
    6227              : 
    6228           60 :       if (ctor == orig_ctor)
    6229              :         {
    6230           49 :           ctor = copy_node (orig_ctor);
    6231           98 :           CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
    6232           49 :           elts = CONSTRUCTOR_ELTS (ctor);
    6233              :         }
    6234           60 :       (*elts)[idx].value = newval;
    6235              :     }
    6236      1836632 :   return ctor;
    6237              : }
    6238              : 
    6239              : /* A subroutine of gimplify_modify_expr.  Break out elements of a
    6240              :    CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
    6241              : 
    6242              :    Note that we still need to clear any elements that don't have explicit
    6243              :    initializers, so if not all elements are initialized we keep the
    6244              :    original MODIFY_EXPR, we just remove all of the constructor elements.
    6245              : 
    6246              :    If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
    6247              :    GS_ERROR if we would have to create a temporary when gimplifying
    6248              :    this constructor.  Otherwise, return GS_OK.
    6249              : 
    6250              :    If NOTIFY_TEMP_CREATION is false, just do the gimplification.  */
    6251              : 
    6252              : static enum gimplify_status
    6253      1308555 : gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
    6254              :                            bool want_value, bool notify_temp_creation)
    6255              : {
    6256      1308555 :   tree object, ctor, type;
    6257      1308555 :   enum gimplify_status ret;
    6258      1308555 :   vec<constructor_elt, va_gc> *elts;
    6259      1308555 :   bool cleared = false;
    6260      1308555 :   bool is_empty_ctor = false;
    6261      1308555 :   bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
    6262              : 
    6263      1308555 :   gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
    6264              : 
    6265      1308555 :   if (!notify_temp_creation)
    6266              :     {
    6267      1300357 :       ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
    6268              :                            is_gimple_lvalue, fb_lvalue);
    6269      1300357 :       if (ret == GS_ERROR)
    6270              :         return ret;
    6271              :     }
    6272              : 
    6273      1308555 :   object = TREE_OPERAND (*expr_p, 0);
    6274      1308555 :   ctor = TREE_OPERAND (*expr_p, 1)
    6275      1308555 :     = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
    6276      1308555 :   type = TREE_TYPE (ctor);
    6277      1308555 :   elts = CONSTRUCTOR_ELTS (ctor);
    6278      1308555 :   ret = GS_ALL_DONE;
    6279              : 
    6280      1308555 :   switch (TREE_CODE (type))
    6281              :     {
    6282      1301251 :     case RECORD_TYPE:
    6283      1301251 :     case UNION_TYPE:
    6284      1301251 :     case QUAL_UNION_TYPE:
    6285      1301251 :     case ARRAY_TYPE:
    6286      1301251 :       {
    6287              :         /* Use readonly data for initializers of this or smaller size
    6288              :            regardless of the num_nonzero_elements / num_unique_nonzero_elements
    6289              :            ratio.  */
    6290      1301251 :         const HOST_WIDE_INT min_unique_size = 64;
    6291              :         /* If num_nonzero_elements / num_unique_nonzero_elements ratio
    6292              :            is smaller than this, use readonly data.  */
    6293      1301251 :         const int unique_nonzero_ratio = 8;
    6294              :         /* True if a single access of the object must be ensured.  This is the
    6295              :            case if the target is volatile, the type is non-addressable and more
    6296              :            than one field need to be assigned.  */
    6297      1301251 :         const bool ensure_single_access
    6298      1301251 :           = TREE_THIS_VOLATILE (object)
    6299          255 :             && !TREE_ADDRESSABLE (type)
    6300      1301454 :             && vec_safe_length (elts) > 1;
    6301      1301251 :         struct gimplify_init_ctor_preeval_data preeval_data;
    6302      1301251 :         HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
    6303      1301251 :         HOST_WIDE_INT num_unique_nonzero_elements;
    6304      1301251 :         ctor_completeness complete_p;
    6305      1301251 :         bool valid_const_initializer;
    6306              : 
    6307              :         /* Aggregate types must lower constructors to initialization of
    6308              :            individual elements.  The exception is that a CONSTRUCTOR node
    6309              :            with no elements indicates zero-initialization of the whole.  */
    6310      1301251 :         if (vec_safe_is_empty (elts))
    6311              :           {
    6312       328068 :             if (notify_temp_creation)
    6313         9781 :               return GS_OK;
    6314              : 
    6315              :             /* The var will be initialized and so appear on lhs of
    6316              :                assignment, it can't be TREE_READONLY anymore.  */
    6317       328020 :             if (VAR_P (object))
    6318       182928 :               TREE_READONLY (object) = 0;
    6319              : 
    6320              :             is_empty_ctor = true;
    6321       330604 :             break;
    6322              :           }
    6323              : 
    6324              :         /* Fetch information about the constructor to direct later processing.
    6325              :            We might want to make static versions of it in various cases, and
    6326              :            can only do so if it known to be a valid constant initializer.  */
    6327       973183 :         valid_const_initializer
    6328       973183 :           = categorize_ctor_elements (ctor, &num_nonzero_elements,
    6329              :                                       &num_unique_nonzero_elements,
    6330              :                                       &num_ctor_elements, &complete_p);
    6331              : 
    6332              :         /* If a const aggregate variable is being initialized, then it
    6333              :            should never be a lose to promote the variable to be static.  */
    6334       973183 :         if (valid_const_initializer
    6335       595806 :             && num_nonzero_elements > 1
    6336       443565 :             && TREE_READONLY (object)
    6337         5204 :             && VAR_P (object)
    6338         4827 :             && !DECL_REGISTER (object)
    6339         4820 :             && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)
    6340         3837 :                 || DECL_MERGEABLE (object))
    6341              :             /* For ctors that have many repeated nonzero elements
    6342              :                represented through RANGE_EXPRs, prefer initializing
    6343              :                those through runtime loops over copies of large amounts
    6344              :                of data from readonly data section.  */
    6345       973183 :             && (num_unique_nonzero_elements
    6346         2584 :                 > num_nonzero_elements / unique_nonzero_ratio
    6347            0 :                 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
    6348              :                     <= (unsigned HOST_WIDE_INT) min_unique_size)))
    6349              :           {
    6350         2584 :             if (notify_temp_creation)
    6351              :               return GS_ERROR;
    6352              : 
    6353         2584 :             DECL_INITIAL (object) = ctor;
    6354         2584 :             TREE_STATIC (object) = 1;
    6355         2584 :             if (!DECL_NAME (object) || DECL_NAMELESS (object))
    6356         2122 :               DECL_NAME (object) = create_tmp_var_name ("C");
    6357         2584 :             walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
    6358              : 
    6359              :             /* ??? C++ doesn't automatically append a .<number> to the
    6360              :                assembler name, and even when it does, it looks at FE private
    6361              :                data structures to figure out what that number should be,
    6362              :                which are not set for this variable.  I suppose this is
    6363              :                important for local statics for inline functions, which aren't
    6364              :                "local" in the object file sense.  So in order to get a unique
    6365              :                TU-local symbol, we must invoke the lhd version now.  */
    6366         2584 :             lhd_set_decl_assembler_name (object);
    6367              : 
    6368         2584 :             *expr_p = NULL_TREE;
    6369         2584 :             break;
    6370              :           }
    6371              : 
    6372              :         /* The var will be initialized and so appear on lhs of
    6373              :            assignment, it can't be TREE_READONLY anymore.  */
    6374       970599 :         if (VAR_P (object) && !notify_temp_creation)
    6375       765871 :           TREE_READONLY (object) = 0;
    6376              : 
    6377              :         /* If there are "lots" of initialized elements, even discounting
    6378              :            those that are not address constants (and thus *must* be
    6379              :            computed at runtime), then partition the constructor into
    6380              :            constant and non-constant parts.  Block copy the constant
    6381              :            parts in, then generate code for the non-constant parts.  */
    6382              :         /* TODO.  There's code in cp/typeck.cc to do this.  */
    6383              : 
    6384       970599 :         if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
    6385              :           /* store_constructor will ignore the clearing of variable-sized
    6386              :              objects.  Initializers for such objects must explicitly set
    6387              :              every field that needs to be set.  */
    6388              :           cleared = false;
    6389       970579 :         else if (complete_p.sparse)
    6390              :           /* If the constructor isn't complete, clear the whole object
    6391              :              beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
    6392              : 
    6393              :              ??? This ought not to be needed.  For any element not present
    6394              :              in the initializer, we should simply set them to zero.  Except
    6395              :              we'd need to *find* the elements that are not present, and that
    6396              :              requires trickery to avoid quadratic compile-time behavior in
    6397              :              large cases or excessive memory use in small cases.  */
    6398       183017 :           cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
    6399       787562 :         else if (num_ctor_elements - num_nonzero_elements
    6400       787562 :                  > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
    6401       787562 :                  && num_nonzero_elements < num_ctor_elements / 4)
    6402              :           /* If there are "lots" of zeros, it's more efficient to clear
    6403              :              the memory and then set the nonzero elements.  */
    6404              :           cleared = true;
    6405       786688 :         else if (ensure_single_access && num_nonzero_elements == 0)
    6406              :           /* If a single access to the target must be ensured and all elements
    6407              :              are zero, then it's optimal to clear whatever their number.  */
    6408              :           cleared = true;
    6409              :         /* If the object is small enough to go in registers, and it's
    6410              :            not required to be constructed in memory, clear it first.
    6411              :            That will avoid wasting cycles preserving any padding bits
    6412              :            that might be there, and if there aren't any, the compiler
    6413              :            is smart enough to optimize the clearing out.  */
    6414       786679 :         else if ((complete_p.sparse || complete_p.padded_union
    6415       786455 :                   || complete_p.padded_non_union)
    6416        13805 :                  && !TREE_ADDRESSABLE (ctor)
    6417        13719 :                  && !TREE_THIS_VOLATILE (object)
    6418        13716 :                  && (TYPE_MODE (type) != BLKmode || TYPE_NO_FORCE_BLK (type))
    6419       793443 :                  && optimize)
    6420              :           cleared = true;
    6421              :         else
    6422              :           cleared = false;
    6423              : 
    6424              :         /* If there are "lots" of initialized elements, and all of them
    6425              :            are valid address constants, then the entire initializer can
    6426              :            be dropped to memory, and then memcpy'd out.  Don't do this
    6427              :            for sparse arrays, though, as it's more efficient to follow
    6428              :            the standard CONSTRUCTOR behavior of memset followed by
    6429              :            individual element initialization.  Also don't do this for small
    6430              :            all-zero initializers (which aren't big enough to merit
    6431              :            clearing), and don't try to make bitwise copies of
    6432              :            TREE_ADDRESSABLE types.  */
    6433       970599 :         if (valid_const_initializer
    6434       593222 :             && !complete_p.sparse
    6435       425201 :             && !(cleared || num_nonzero_elements == 0)
    6436       332165 :             && !TREE_ADDRESSABLE (type))
    6437              :           {
    6438       330614 :             HOST_WIDE_INT size = int_size_in_bytes (type);
    6439       330614 :             unsigned int align;
    6440              : 
    6441              :             /* ??? We can still get unbounded array types, at least
    6442              :                from the C++ front end.  This seems wrong, but attempt
    6443              :                to work around it for now.  */
    6444       330614 :             if (size < 0)
    6445              :               {
    6446            9 :                 size = int_size_in_bytes (TREE_TYPE (object));
    6447            9 :                 if (size >= 0)
    6448            0 :                   TREE_TYPE (ctor) = type = TREE_TYPE (object);
    6449              :               }
    6450              : 
    6451              :             /* Find the maximum alignment we can assume for the object.  */
    6452              :             /* ??? Make use of DECL_OFFSET_ALIGN.  */
    6453       330614 :             if (DECL_P (object))
    6454       316858 :               align = DECL_ALIGN (object);
    6455              :             else
    6456        13756 :               align = TYPE_ALIGN (type);
    6457              : 
    6458              :             /* Do a block move either if the size is so small as to make
    6459              :                each individual move a sub-unit move on average, or if it
    6460              :                is so large as to make individual moves inefficient.  */
    6461       330614 :             if (size > 0
    6462       330605 :                 && num_nonzero_elements > 1
    6463              :                 /* For ctors that have many repeated nonzero elements
    6464              :                    represented through RANGE_EXPRs, prefer initializing
    6465              :                    those through runtime loops over copies of large amounts
    6466              :                    of data from readonly data section.  */
    6467       298184 :                 && (num_unique_nonzero_elements
    6468       298184 :                     > num_nonzero_elements / unique_nonzero_ratio
    6469           56 :                     || size <= min_unique_size)
    6470       628742 :                 && (size < num_nonzero_elements
    6471       298022 :                     || !can_move_by_pieces (size, align)))
    6472              :               {
    6473         2840 :                 if (notify_temp_creation)
    6474              :                   return GS_ERROR;
    6475              : 
    6476         1422 :                 walk_tree (&ctor, force_labels_r, NULL, NULL);
    6477         1422 :                 ctor = tree_output_constant_def (ctor);
    6478         1422 :                 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
    6479            0 :                   ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
    6480         1422 :                 TREE_OPERAND (*expr_p, 1) = ctor;
    6481              : 
    6482              :                 /* This is no longer an assignment of a CONSTRUCTOR, but
    6483              :                    we still may have processing to do on the LHS.  So
    6484              :                    pretend we didn't do anything here to let that happen.  */
    6485         1422 :                 return GS_UNHANDLED;
    6486              :               }
    6487              :           }
    6488              : 
    6489       963329 :         if (!cleared)
    6490              :           {
    6491       777804 :             if (complete_p.padded_non_union
    6492         7128 :                 && warn_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_ALL)
    6493           12 :                 warning (OPT_Wzero_init_padding_bits_,
    6494              :                          "padding might not be initialized to zero; "
    6495              :                          "if code relies on it being zero, consider "
    6496              :                          "using %<-fzero-init-padding-bits=all%>");
    6497       777792 :             else if (complete_p.padded_union
    6498          116 :                      && warn_zero_init_padding_bits
    6499              :                         >= ZERO_INIT_PADDING_BITS_UNIONS)
    6500           14 :                 warning (OPT_Wzero_init_padding_bits_,
    6501              :                          "padding might not be initialized to zero; "
    6502              :                          "if code relies on it being zero, consider "
    6503              :                          "using %<-fzero-init-padding-bits=unions%> "
    6504              :                          "or %<-fzero-init-padding-bits=all%>");
    6505              :           }
    6506              : 
    6507              :         /* If a single access to the target must be ensured and there are
    6508              :            nonzero elements or the zero elements are not assigned en masse,
    6509              :            initialize the target from a temporary.  */
    6510       967759 :         if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
    6511              :           {
    6512          167 :             if (notify_temp_creation)
    6513              :               return GS_ERROR;
    6514              : 
    6515          161 :             tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
    6516          161 :             TREE_OPERAND (*expr_p, 0) = temp;
    6517          161 :             *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
    6518              :                               *expr_p,
    6519              :                               build2 (MODIFY_EXPR, void_type_node,
    6520              :                                       object, temp));
    6521          161 :             return GS_OK;
    6522              :           }
    6523              : 
    6524       967592 :         if (notify_temp_creation)
    6525              :           return GS_OK;
    6526              : 
    6527              :         /* If there are nonzero elements and if needed, pre-evaluate to capture
    6528              :            elements overlapping with the lhs into temporaries.  We must do this
    6529              :            before clearing to fetch the values before they are zeroed-out.  */
    6530       960866 :         if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
    6531              :           {
    6532       215678 :             preeval_data.lhs_base_decl = get_base_address (object);
    6533       215678 :             if (!DECL_P (preeval_data.lhs_base_decl))
    6534        41151 :               preeval_data.lhs_base_decl = NULL;
    6535       215678 :             preeval_data.lhs_alias_set = get_alias_set (object);
    6536              : 
    6537       215678 :             gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
    6538              :                                         pre_p, post_p, &preeval_data);
    6539              :           }
    6540              : 
    6541       960866 :         bool ctor_has_side_effects_p
    6542       960866 :           = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
    6543              : 
    6544       960866 :         if (cleared)
    6545              :           {
    6546              :             /* Zap the CONSTRUCTOR element list, which simplifies this case.
    6547              :                Note that we still have to gimplify, in order to handle the
    6548              :                case of variable sized types.  Avoid shared tree structures.  */
    6549       189754 :             CONSTRUCTOR_ELTS (ctor) = NULL;
    6550       189754 :             TREE_SIDE_EFFECTS (ctor) = 0;
    6551       189754 :             object = unshare_expr (object);
    6552       189754 :             gimplify_stmt (expr_p, pre_p);
    6553              :           }
    6554              : 
    6555              :         /* If we have not block cleared the object, or if there are nonzero
    6556              :            elements in the constructor, or if the constructor has side effects,
    6557              :            add assignments to the individual scalar fields of the object.  */
    6558       189754 :         if (!cleared
    6559       189754 :             || num_nonzero_elements > 0
    6560        17766 :             || ctor_has_side_effects_p)
    6561       943495 :           gimplify_init_ctor_eval (object, elts, pre_p, cleared);
    6562              : 
    6563       960866 :         *expr_p = NULL_TREE;
    6564              :       }
    6565       960866 :       break;
    6566              : 
    6567            0 :     case COMPLEX_TYPE:
    6568            0 :       {
    6569            0 :         tree r, i;
    6570              : 
    6571            0 :         if (notify_temp_creation)
    6572              :           return GS_OK;
    6573              : 
    6574              :         /* Extract the real and imaginary parts out of the ctor.  */
    6575            0 :         gcc_assert (elts->length () == 2);
    6576            0 :         r = (*elts)[0].value;
    6577            0 :         i = (*elts)[1].value;
    6578            0 :         if (r == NULL || i == NULL)
    6579              :           {
    6580            0 :             tree zero = build_zero_cst (TREE_TYPE (type));
    6581            0 :             if (r == NULL)
    6582            0 :               r = zero;
    6583            0 :             if (i == NULL)
    6584            0 :               i = zero;
    6585              :           }
    6586              : 
    6587              :         /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
    6588              :            represent creation of a complex value.  */
    6589            0 :         if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
    6590              :           {
    6591            0 :             ctor = build_complex (type, r, i);
    6592            0 :             TREE_OPERAND (*expr_p, 1) = ctor;
    6593              :           }
    6594              :         else
    6595              :           {
    6596            0 :             ctor = build2 (COMPLEX_EXPR, type, r, i);
    6597            0 :             TREE_OPERAND (*expr_p, 1) = ctor;
    6598            0 :             ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
    6599              :                                  pre_p,
    6600              :                                  post_p,
    6601            0 :                                  rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
    6602              :                                  fb_rvalue);
    6603              :           }
    6604              :       }
    6605              :       break;
    6606              : 
    6607         7304 :     case VECTOR_TYPE:
    6608         7304 :       {
    6609         7304 :         unsigned HOST_WIDE_INT ix;
    6610         7304 :         constructor_elt *ce;
    6611              : 
    6612         7304 :         if (notify_temp_creation)
    6613      1308555 :           return GS_OK;
    6614              : 
    6615              :         /* Vector types use CONSTRUCTOR all the way through gimple
    6616              :            compilation as a general initializer.  */
    6617        67322 :         FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
    6618              :           {
    6619        60018 :             enum gimplify_status tret;
    6620        60018 :             tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
    6621              :                                   fb_rvalue);
    6622        60018 :             if (tret == GS_ERROR)
    6623              :               ret = GS_ERROR;
    6624        60017 :             else if (TREE_STATIC (ctor)
    6625        60049 :                      && !initializer_constant_valid_p (ce->value,
    6626           32 :                                                        TREE_TYPE (ce->value)))
    6627           32 :               TREE_STATIC (ctor) = 0;
    6628              :           }
    6629         7304 :         recompute_constructor_flags (ctor);
    6630              : 
    6631              :         /* Go ahead and simplify constant constructors to VECTOR_CST.  */
    6632         7304 :         if (TREE_CONSTANT (ctor))
    6633              :           {
    6634         2705 :             bool constant_p = true;
    6635              :             tree value;
    6636              : 
    6637              :             /* Even when ctor is constant, it might contain non-*_CST
    6638              :                elements, such as addresses or trapping values like
    6639              :                1.0/0.0 - 1.0/0.0.  Such expressions don't belong
    6640              :                in VECTOR_CST nodes.  */
    6641         2705 :             FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
    6642         2483 :               if (!CONSTANT_CLASS_P (value))
    6643              :                 {
    6644              :                   constant_p = false;
    6645              :                   break;
    6646              :                 }
    6647              : 
    6648          222 :             if (constant_p)
    6649              :               {
    6650          222 :                 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
    6651          222 :                 break;
    6652              :               }
    6653              :           }
    6654              : 
    6655         7082 :         if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
    6656          918 :           TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
    6657              :       }
    6658              :       break;
    6659              : 
    6660            0 :     default:
    6661              :       /* So how did we get a CONSTRUCTOR for a scalar type?  */
    6662            0 :       gcc_unreachable ();
    6663              :     }
    6664              : 
    6665      1298774 :   if (ret == GS_ERROR)
    6666              :     return GS_ERROR;
    6667              :   /* If we have gimplified both sides of the initializer but have
    6668              :      not emitted an assignment, do so now.   */
    6669      1298773 :   if (*expr_p
    6670              :       /* If the type is an empty type, we don't need to emit the
    6671              :          assignment. */
    6672      1298773 :       && !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
    6673              :     {
    6674       331485 :       tree lhs = TREE_OPERAND (*expr_p, 0);
    6675       331485 :       tree rhs = TREE_OPERAND (*expr_p, 1);
    6676       331485 :       if (want_value && object == lhs)
    6677           12 :         lhs = unshare_expr (lhs);
    6678       331485 :       gassign *init = gimple_build_assign (lhs, rhs);
    6679       331485 :       gimplify_seq_add_stmt (pre_p, init);
    6680              :     }
    6681      1298773 :   if (want_value)
    6682              :     {
    6683           19 :       *expr_p = object;
    6684           19 :       ret = GS_OK;
    6685              :     }
    6686              :   else
    6687              :     {
    6688      1298754 :       *expr_p = NULL;
    6689      1298754 :       ret = GS_ALL_DONE;
    6690              :     }
    6691              : 
    6692              :   /* If the user requests to initialize automatic variables, we
    6693              :      should initialize paddings inside the variable.  Add a call to
    6694              :      __builtin_clear_pading (&object, 0, for_auto_init = true) to
    6695              :      initialize paddings of object always to zero regardless of
    6696              :      INIT_TYPE.  Note, we will not insert this call if the aggregate
    6697              :      variable has be completely cleared already or it's initialized
    6698              :      with an empty constructor.  We cannot insert this call if the
    6699              :      variable is a gimple register since __builtin_clear_padding will take
    6700              :      the address of the variable.  As a result, if a long double/_Complex long
    6701              :      double variable will be spilled into stack later, its padding cannot
    6702              :      be cleared with __builtin_clear_padding.  We should clear its padding
    6703              :      when it is spilled into memory.  */
    6704      1298773 :   if (is_init_expr
    6705       920489 :       && !is_gimple_reg (object)
    6706       915927 :       && clear_padding_type_may_have_padding_p (type)
    6707       873431 :       && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
    6708       217350 :           || !AGGREGATE_TYPE_P (type))
    6709       656081 :       && var_needs_auto_init_p (object)
    6710      1319050 :       && flag_auto_var_init != AUTO_INIT_CXX26)
    6711           41 :     gimple_add_padding_init_for_auto_var (object, false, pre_p);
    6712              : 
    6713              :   return ret;
    6714              : }
    6715              : 
    6716              : /* Given a pointer value OP0, return a simplified version of an
    6717              :    indirection through OP0, or NULL_TREE if no simplification is
    6718              :    possible.  This may only be applied to a rhs of an expression.
    6719              :    Note that the resulting type may be different from the type pointed
    6720              :    to in the sense that it is still compatible from the langhooks
    6721              :    point of view. */
    6722              : 
    6723              : static tree
    6724       515738 : gimple_fold_indirect_ref_rhs (tree t)
    6725              : {
    6726            0 :   return gimple_fold_indirect_ref (t);
    6727              : }
    6728              : 
    6729              : /* Subroutine of gimplify_modify_expr to do simplifications of
    6730              :    MODIFY_EXPRs based on the code of the RHS.  We loop for as long as
    6731              :    something changes.  */
    6732              : 
    6733              : static enum gimplify_status
    6734     96607429 : gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
    6735              :                           gimple_seq *pre_p, gimple_seq *post_p,
    6736              :                           bool want_value)
    6737              : {
    6738     96607429 :   enum gimplify_status ret = GS_UNHANDLED;
    6739     97229736 :   bool changed;
    6740              : 
    6741     95781449 :   do
    6742              :     {
    6743     97229736 :       changed = false;
    6744     97229736 :       switch (TREE_CODE (*from_p))
    6745              :         {
    6746     11897748 :         case VAR_DECL:
    6747              :           /* If we're assigning from a read-only variable initialized with
    6748              :              a constructor and not volatile, do the direct assignment from
    6749              :              the constructor, but only if the target is not volatile either
    6750              :              since this latter assignment might end up being done on a per
    6751              :              field basis.  However, if the target is volatile and the type
    6752              :              is aggregate and non-addressable, gimplify_init_constructor
    6753              :              knows that it needs to ensure a single access to the target
    6754              :              and it will return GS_OK only in this case.  */
    6755     11897748 :           if (TREE_READONLY (*from_p)
    6756        92130 :               && DECL_INITIAL (*from_p)
    6757        61086 :               && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
    6758         8198 :               && !TREE_THIS_VOLATILE (*from_p)
    6759     11905946 :               && (!TREE_THIS_VOLATILE (*to_p)
    6760            6 :                   || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
    6761            6 :                       && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
    6762              :             {
    6763         8198 :               tree old_from = *from_p;
    6764         8198 :               enum gimplify_status subret;
    6765              : 
    6766              :               /* Move the constructor into the RHS.  */
    6767         8198 :               *from_p = unshare_expr (DECL_INITIAL (*from_p));
    6768              : 
    6769              :               /* Let's see if gimplify_init_constructor will need to put
    6770              :                  it in memory.  */
    6771         8198 :               subret = gimplify_init_constructor (expr_p, NULL, NULL,
    6772              :                                                   false, true);
    6773         8198 :               if (subret == GS_ERROR)
    6774              :                 {
    6775              :                   /* If so, revert the change.  */
    6776         1424 :                   *from_p = old_from;
    6777              :                 }
    6778              :               else
    6779              :                 {
    6780              :                   ret = GS_OK;
    6781              :                   changed = true;
    6782              :                 }
    6783              :             }
    6784              :           break;
    6785       523573 :         case INDIRECT_REF:
    6786       523573 :           if (!TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
    6787              :             /* If we have code like
    6788              : 
    6789              :              *(const A*)(A*)&x
    6790              : 
    6791              :              where the type of "x" is a (possibly cv-qualified variant
    6792              :              of "A"), treat the entire expression as identical to "x".
    6793              :              This kind of code arises in C++ when an object is bound
    6794              :              to a const reference, and if "x" is a TARGET_EXPR we want
    6795              :              to take advantage of the optimization below.  But not if
    6796              :              the type is TREE_ADDRESSABLE; then C++17 says that the
    6797              :              TARGET_EXPR needs to be a temporary.  */
    6798      1031476 :             if (tree t
    6799       515738 :                 = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0)))
    6800              :               {
    6801       120575 :                 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
    6802       120575 :                 if (TREE_THIS_VOLATILE (t) != volatile_p)
    6803              :                   {
    6804            5 :                     if (DECL_P (t))
    6805            0 :                       t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
    6806              :                                                     build_fold_addr_expr (t));
    6807            5 :                     if (REFERENCE_CLASS_P (t))
    6808            5 :                       TREE_THIS_VOLATILE (t) = volatile_p;
    6809              :                   }
    6810       120575 :                 *from_p = t;
    6811       120575 :                 ret = GS_OK;
    6812       120575 :                 changed = true;
    6813              :               }
    6814              :           break;
    6815              : 
    6816       179178 :         case TARGET_EXPR:
    6817       179178 :           {
    6818              :             /* If we are initializing something from a TARGET_EXPR, strip the
    6819              :                TARGET_EXPR and initialize it directly, if possible.  This can't
    6820              :                be done if the initializer is void, since that implies that the
    6821              :                temporary is set in some non-trivial way.
    6822              : 
    6823              :                ??? What about code that pulls out the temp and uses it
    6824              :                elsewhere? I think that such code never uses the TARGET_EXPR as
    6825              :                an initializer.  If I'm wrong, we'll die because the temp won't
    6826              :                have any RTL.  In that case, I guess we'll need to replace
    6827              :                references somehow.  */
    6828       179178 :             tree init = TARGET_EXPR_INITIAL (*from_p);
    6829              : 
    6830       179178 :             if (init
    6831       178462 :                 && (TREE_CODE (*expr_p) != MODIFY_EXPR
    6832        46690 :                     || !TARGET_EXPR_NO_ELIDE (*from_p))
    6833       357434 :                 && !VOID_TYPE_P (TREE_TYPE (init)))
    6834              :               {
    6835       164586 :                 *from_p = init;
    6836       164586 :                 ret = GS_OK;
    6837       164586 :                 changed = true;
    6838              :               }
    6839              :           }
    6840              :           break;
    6841              : 
    6842       330008 :         case COMPOUND_EXPR:
    6843              :           /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
    6844              :              caught.  */
    6845       330008 :           gimplify_compound_expr (from_p, pre_p, true);
    6846       330008 :           ret = GS_OK;
    6847       330008 :           changed = true;
    6848       330008 :           break;
    6849              : 
    6850      1321732 :         case CONSTRUCTOR:
    6851              :           /* If we already made some changes, let the front end have a
    6852              :              crack at this before we break it down.  */
    6853      1321732 :           if (ret != GS_UNHANDLED)
    6854              :             break;
    6855              : 
    6856              :           /* If we're initializing from a CONSTRUCTOR, break this into
    6857              :              individual MODIFY_EXPRs.  */
    6858      1300357 :           ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
    6859              :                                            false);
    6860      1300357 :           return ret;
    6861              : 
    6862       223266 :         case COND_EXPR:
    6863              :           /* If we're assigning to a non-register type, push the assignment
    6864              :              down into the branches.  This is mandatory for ADDRESSABLE types,
    6865              :              since we cannot generate temporaries for such, but it saves a
    6866              :              copy in other cases as well.
    6867              :              Also avoid an extra temporary and copy when assigning to
    6868              :              a register.  */
    6869       223266 :           if (!is_gimple_reg_type (TREE_TYPE (*from_p))
    6870       223266 :               || (is_gimple_reg (*to_p) && !gimplify_ctxp->allow_rhs_cond_expr))
    6871              :             {
    6872              :               /* This code should mirror the code in gimplify_cond_expr. */
    6873       141567 :               enum tree_code code = TREE_CODE (*expr_p);
    6874       141567 :               tree cond = *from_p;
    6875       141567 :               tree result = *to_p;
    6876              : 
    6877       141567 :               ret = gimplify_expr (&result, pre_p, post_p,
    6878              :                                    is_gimple_lvalue, fb_lvalue);
    6879       141567 :               if (ret != GS_ERROR)
    6880       141567 :                 ret = GS_OK;
    6881              : 
    6882              :               /* If we are going to write RESULT more than once, clear
    6883              :                  TREE_READONLY flag, otherwise we might incorrectly promote
    6884              :                  the variable to static const and initialize it at compile
    6885              :                  time in one of the branches.  */
    6886       141567 :               if (VAR_P (result)
    6887       140537 :                   && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
    6888       273031 :                   && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
    6889       131372 :                 TREE_READONLY (result) = 0;
    6890       141567 :               if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
    6891       132358 :                 TREE_OPERAND (cond, 1)
    6892       264716 :                   = build2 (code, void_type_node, result,
    6893       132358 :                             TREE_OPERAND (cond, 1));
    6894       141567 :               if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
    6895       141475 :                 TREE_OPERAND (cond, 2)
    6896       282950 :                   = build2 (code, void_type_node, unshare_expr (result),
    6897       141475 :                             TREE_OPERAND (cond, 2));
    6898              : 
    6899       141567 :               TREE_TYPE (cond) = void_type_node;
    6900       141567 :               recalculate_side_effects (cond);
    6901              : 
    6902       141567 :               if (want_value)
    6903              :                 {
    6904           68 :                   gimplify_and_add (cond, pre_p);
    6905           68 :                   *expr_p = unshare_expr (result);
    6906              :                 }
    6907              :               else
    6908       141499 :                 *expr_p = cond;
    6909       141567 :               return ret;
    6910              :             }
    6911              :           break;
    6912              : 
    6913      9753467 :         case CALL_EXPR:
    6914              :           /* For calls that return in memory, give *to_p as the CALL_EXPR's
    6915              :              return slot so that we don't generate a temporary.  */
    6916      9753467 :           if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
    6917      9753467 :               && aggregate_value_p (*from_p, *from_p))
    6918              :             {
    6919       248932 :               bool use_target;
    6920              : 
    6921       248932 :               if (!(rhs_predicate_for (*to_p))(*from_p))
    6922              :                 /* If we need a temporary, *to_p isn't accurate.  */
    6923              :                 use_target = false;
    6924              :               /* It's OK to use the return slot directly unless it's an NRV. */
    6925       248160 :               else if (TREE_CODE (*to_p) == RESULT_DECL
    6926         5623 :                        && DECL_NAME (*to_p) == NULL_TREE
    6927       253639 :                        && needs_to_live_in_memory (*to_p))
    6928              :                 use_target = true;
    6929       242681 :               else if (is_gimple_reg_type (TREE_TYPE (*to_p))
    6930       242681 :                        || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
    6931              :                 /* Don't force regs into memory.  */
    6932              :                 use_target = false;
    6933       228371 :               else if (TREE_CODE (*expr_p) == INIT_EXPR)
    6934              :                 /* It's OK to use the target directly if it's being
    6935              :                    initialized. */
    6936              :                 use_target = true;
    6937        14407 :               else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
    6938              :                        != INTEGER_CST)
    6939              :                 /* Always use the target and thus RSO for variable-sized types.
    6940              :                    GIMPLE cannot deal with a variable-sized assignment
    6941              :                    embedded in a call statement.  */
    6942              :                 use_target = true;
    6943        14379 :               else if (TREE_CODE (*to_p) != SSA_NAME
    6944        14379 :                       && (!is_gimple_variable (*to_p)
    6945        11105 :                           || needs_to_live_in_memory (*to_p)))
    6946              :                 /* Don't use the original target if it's already addressable;
    6947              :                    if its address escapes, and the called function uses the
    6948              :                    NRV optimization, a conforming program could see *to_p
    6949              :                    change before the called function returns; see c++/19317.
    6950              :                    When optimizing, the return_slot pass marks more functions
    6951              :                    as safe after we have escape info.  */
    6952              :                 use_target = false;
    6953              :               else
    6954              :                 use_target = true;
    6955              : 
    6956              :               if (use_target)
    6957              :                 {
    6958       221569 :                   CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
    6959       221569 :                   mark_addressable (*to_p);
    6960              :                 }
    6961              :             }
    6962              :           break;
    6963              : 
    6964         1561 :         case WITH_SIZE_EXPR:
    6965              :           /* Likewise for calls that return an aggregate of non-constant size,
    6966              :              since we would not be able to generate a temporary at all.  */
    6967         1561 :           if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
    6968              :             {
    6969          351 :               *from_p = TREE_OPERAND (*from_p, 0);
    6970              :               /* We don't change ret in this case because the
    6971              :                  WITH_SIZE_EXPR might have been added in
    6972              :                  gimplify_modify_expr, so returning GS_OK would lead to an
    6973              :                  infinite loop.  */
    6974          351 :               changed = true;
    6975              :             }
    6976              :           break;
    6977              : 
    6978              :           /* If we're initializing from a container, push the initialization
    6979              :              inside it.  */
    6980         1933 :         case CLEANUP_POINT_EXPR:
    6981         1933 :         case BIND_EXPR:
    6982         1933 :         case STATEMENT_LIST:
    6983         1933 :           {
    6984         1933 :             tree wrap = *from_p;
    6985         1933 :             tree t;
    6986              : 
    6987         1933 :             ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
    6988              :                                  fb_lvalue);
    6989         1933 :             if (ret != GS_ERROR)
    6990         1933 :               ret = GS_OK;
    6991              : 
    6992         1933 :             t = voidify_wrapper_expr (wrap, *expr_p);
    6993         1933 :             gcc_assert (t == *expr_p);
    6994              : 
    6995         1933 :             if (want_value)
    6996              :               {
    6997            6 :                 gimplify_and_add (wrap, pre_p);
    6998            6 :                 *expr_p = unshare_expr (*to_p);
    6999              :               }
    7000              :             else
    7001         1927 :               *expr_p = wrap;
    7002              :             return GS_OK;
    7003              :           }
    7004              : 
    7005      9466146 :         case NOP_EXPR:
    7006              :           /* Pull out compound literal expressions from a NOP_EXPR.
    7007              :              Those are created in the C FE to drop qualifiers during
    7008              :              lvalue conversion.  */
    7009      9466146 :           if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
    7010      9466146 :               && tree_ssa_useless_type_conversion (*from_p))
    7011              :             {
    7012           13 :               *from_p = TREE_OPERAND (*from_p, 0);
    7013           13 :               ret = GS_OK;
    7014           13 :               changed = true;
    7015              :             }
    7016              :           break;
    7017              : 
    7018         4430 :         case COMPOUND_LITERAL_EXPR:
    7019         4430 :           {
    7020         4430 :             tree complit = TREE_OPERAND (*expr_p, 1);
    7021         4430 :             tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
    7022         4430 :             tree decl = DECL_EXPR_DECL (decl_s);
    7023         4430 :             tree init = DECL_INITIAL (decl);
    7024              : 
    7025              :             /* struct T x = (struct T) { 0, 1, 2 } can be optimized
    7026              :                into struct T x = { 0, 1, 2 } if the address of the
    7027              :                compound literal has never been taken.  */
    7028         4430 :             if (!TREE_ADDRESSABLE (complit)
    7029         4430 :                 && !TREE_ADDRESSABLE (decl)
    7030         4430 :                 && init)
    7031              :               {
    7032         4430 :                 *expr_p = copy_node (*expr_p);
    7033         4430 :                 TREE_OPERAND (*expr_p, 1) = init;
    7034         4430 :                 return GS_OK;
    7035              :               }
    7036              :           }
    7037              : 
    7038              :         default:
    7039              :           break;
    7040              :         }
    7041              :     }
    7042              :   while (changed);
    7043              : 
    7044              :   return ret;
    7045              : }
    7046              : 
    7047              : 
    7048              : /* Return true if T looks like a valid GIMPLE statement.  */
    7049              : 
    7050              : static bool
    7051     19030625 : is_gimple_stmt (tree t)
    7052              : {
    7053     19030625 :   const enum tree_code code = TREE_CODE (t);
    7054              : 
    7055     19030625 :   switch (code)
    7056              :     {
    7057      1712112 :     case NOP_EXPR:
    7058              :       /* The only valid NOP_EXPR is the empty statement.  */
    7059      1712112 :       return IS_EMPTY_STMT (t);
    7060              : 
    7061            0 :     case BIND_EXPR:
    7062            0 :     case COND_EXPR:
    7063              :       /* These are only valid if they're void.  */
    7064            0 :       return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
    7065              : 
    7066              :     case SWITCH_EXPR:
    7067              :     case GOTO_EXPR:
    7068              :     case RETURN_EXPR:
    7069              :     case LABEL_EXPR:
    7070              :     case CASE_LABEL_EXPR:
    7071              :     case TRY_CATCH_EXPR:
    7072              :     case TRY_FINALLY_EXPR:
    7073              :     case EH_FILTER_EXPR:
    7074              :     case CATCH_EXPR:
    7075              :     case ASM_EXPR:
    7076              :     case STATEMENT_LIST:
    7077              :     case OACC_PARALLEL:
    7078              :     case OACC_KERNELS:
    7079              :     case OACC_SERIAL:
    7080              :     case OACC_DATA:
    7081              :     case OACC_HOST_DATA:
    7082              :     case OACC_DECLARE:
    7083              :     case OACC_UPDATE:
    7084              :     case OACC_ENTER_DATA:
    7085              :     case OACC_EXIT_DATA:
    7086              :     case OACC_CACHE:
    7087              :     case OMP_PARALLEL:
    7088              :     case OMP_FOR:
    7089              :     case OMP_SIMD:
    7090              :     case OMP_DISTRIBUTE:
    7091              :     case OMP_LOOP:
    7092              :     case OMP_TILE:
    7093              :     case OMP_UNROLL:
    7094              :     case OACC_LOOP:
    7095              :     case OMP_SCAN:
    7096              :     case OMP_SCOPE:
    7097              :     case OMP_DISPATCH:
    7098              :     case OMP_SECTIONS:
    7099              :     case OMP_SECTION:
    7100              :     case OMP_STRUCTURED_BLOCK:
    7101              :     case OMP_SINGLE:
    7102              :     case OMP_MASTER:
    7103              :     case OMP_MASKED:
    7104              :     case OMP_TASKGROUP:
    7105              :     case OMP_ORDERED:
    7106              :     case OMP_CRITICAL:
    7107              :     case OMP_METADIRECTIVE:
    7108              :     case OMP_TASK:
    7109              :     case OMP_TARGET:
    7110              :     case OMP_TARGET_DATA:
    7111              :     case OMP_TARGET_UPDATE:
    7112              :     case OMP_TARGET_ENTER_DATA:
    7113              :     case OMP_TARGET_EXIT_DATA:
    7114              :     case OMP_TASKLOOP:
    7115              :     case OMP_TEAMS:
    7116              :       /* These are always void.  */
    7117              :       return true;
    7118              : 
    7119              :     case CALL_EXPR:
    7120              :     case MODIFY_EXPR:
    7121              :     case PREDICT_EXPR:
    7122              :       /* These are valid regardless of their type.  */
    7123              :       return true;
    7124              : 
    7125              :     default:
    7126              :       return false;
    7127              :     }
    7128              : }
    7129              : 
    7130              : 
    7131              : /* Promote partial stores to COMPLEX variables to total stores.  *EXPR_P is
    7132              :    a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
    7133              : 
    7134              :    IMPORTANT NOTE: This promotion is performed by introducing a load of the
    7135              :    other, unmodified part of the complex object just before the total store.
    7136              :    As a consequence, if the object is still uninitialized, an undefined value
    7137              :    will be loaded into a register, which may result in a spurious exception
    7138              :    if the register is floating-point and the value happens to be a signaling
    7139              :    NaN for example.  Then the fully-fledged complex operations lowering pass
    7140              :    followed by a DCE pass are necessary in order to fix things up.  */
    7141              : 
    7142              : static enum gimplify_status
    7143         1942 : gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
    7144              :                                    bool want_value)
    7145              : {
    7146         1942 :   enum tree_code code, ocode;
    7147         1942 :   tree lhs, rhs, new_rhs, other, realpart, imagpart;
    7148              : 
    7149         1942 :   lhs = TREE_OPERAND (*expr_p, 0);
    7150         1942 :   rhs = TREE_OPERAND (*expr_p, 1);
    7151         1942 :   code = TREE_CODE (lhs);
    7152         1942 :   lhs = TREE_OPERAND (lhs, 0);
    7153              : 
    7154         1942 :   ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
    7155         1942 :   other = build1 (ocode, TREE_TYPE (rhs), lhs);
    7156         1942 :   suppress_warning (other);
    7157         1942 :   other = get_formal_tmp_var (other, pre_p);
    7158              : 
    7159         1942 :   realpart = code == REALPART_EXPR ? rhs : other;
    7160          957 :   imagpart = code == REALPART_EXPR ? other : rhs;
    7161              : 
    7162         1942 :   if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
    7163            0 :     new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
    7164              :   else
    7165         1942 :     new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
    7166              : 
    7167         1942 :   gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
    7168         1942 :   *expr_p = (want_value) ? rhs : NULL_TREE;
    7169              : 
    7170         1942 :   return GS_ALL_DONE;
    7171              : }
    7172              : 
    7173              : /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
    7174              : 
    7175              :       modify_expr
    7176              :               : varname '=' rhs
    7177              :               | '*' ID '=' rhs
    7178              : 
    7179              :     PRE_P points to the list where side effects that must happen before
    7180              :         *EXPR_P should be stored.
    7181              : 
    7182              :     POST_P points to the list where side effects that must happen after
    7183              :         *EXPR_P should be stored.
    7184              : 
    7185              :     WANT_VALUE is nonzero iff we want to use the value of this expression
    7186              :         in another expression.  */
    7187              : 
    7188              : static enum gimplify_status
    7189     49865939 : gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
    7190              :                       bool want_value)
    7191              : {
    7192     49865939 :   tree *from_p = &TREE_OPERAND (*expr_p, 1);
    7193     49865939 :   tree *to_p = &TREE_OPERAND (*expr_p, 0);
    7194     49865939 :   enum gimplify_status ret = GS_UNHANDLED;
    7195     49865939 :   gimple *assign;
    7196     49865939 :   location_t loc = EXPR_LOCATION (*expr_p);
    7197     49865939 :   gimple_stmt_iterator gsi;
    7198              : 
    7199     49865939 :   if (error_operand_p (*from_p) || error_operand_p (*to_p))
    7200              :     return GS_ERROR;
    7201              : 
    7202     49865911 :   gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
    7203              :               || TREE_CODE (*expr_p) == INIT_EXPR);
    7204              : 
    7205              :   /* Trying to simplify a clobber using normal logic doesn't work,
    7206              :      so handle it here.  */
    7207     49865911 :   if (TREE_CLOBBER_P (*from_p))
    7208              :     {
    7209       559637 :       ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
    7210       559637 :       if (ret == GS_ERROR)
    7211              :         return ret;
    7212       559637 :       gcc_assert (!want_value);
    7213       559637 :       if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
    7214              :         {
    7215          201 :           tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
    7216              :                                                pre_p, post_p);
    7217          201 :           *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
    7218              :         }
    7219       559637 :       gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
    7220       559637 :       *expr_p = NULL;
    7221       559637 :       return GS_ALL_DONE;
    7222              :     }
    7223              : 
    7224              :   /* Convert initialization from an empty variable-size CONSTRUCTOR to
    7225              :      memset.  */
    7226     49306274 :   if (TREE_TYPE (*from_p) != error_mark_node
    7227     49306274 :       && TYPE_SIZE_UNIT (TREE_TYPE (*from_p))
    7228     49306274 :       && !poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (*from_p)))
    7229         1594 :       && TREE_CODE (*from_p) == CONSTRUCTOR
    7230     49306378 :       && CONSTRUCTOR_NELTS (*from_p) == 0)
    7231              :     {
    7232           84 :       maybe_with_size_expr (from_p);
    7233           84 :       gcc_assert (TREE_CODE (*from_p) == WITH_SIZE_EXPR);
    7234           84 :       return gimplify_modify_expr_to_memset (expr_p,
    7235           84 :                                              TREE_OPERAND (*from_p, 1),
    7236           84 :                                              want_value, pre_p);
    7237              :     }
    7238              : 
    7239              :   /* Insert pointer conversions required by the middle-end that are not
    7240              :      required by the frontend.  This fixes middle-end type checking for
    7241              :      for example gcc.dg/redecl-6.c.  */
    7242     49306190 :   if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
    7243              :     {
    7244     13317864 :       STRIP_USELESS_TYPE_CONVERSION (*from_p);
    7245     13317864 :       if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
    7246          754 :         *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
    7247              :     }
    7248              : 
    7249              :   /* See if any simplifications can be done based on what the RHS is.  */
    7250     49306190 :   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
    7251              :                                   want_value);
    7252     49306190 :   if (ret != GS_UNHANDLED)
    7253              :     return ret;
    7254              : 
    7255              :   /* For empty types only gimplify the left hand side and right hand
    7256              :      side as statements and throw away the assignment.  Do this after
    7257              :      gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
    7258              :      types properly.  */
    7259     47303580 :   if (is_empty_type (TREE_TYPE (*from_p))
    7260        13289 :       && !want_value
    7261              :       /* Don't do this for calls that return addressable types, expand_call
    7262              :          relies on those having a lhs.  */
    7263     47316862 :       && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
    7264        11178 :            && TREE_CODE (*from_p) == CALL_EXPR))
    7265              :     {
    7266         2104 :       suppress_warning (*from_p, OPT_Wunused_result);
    7267         2104 :       gimplify_stmt (from_p, pre_p);
    7268         2104 :       gimplify_stmt (to_p, pre_p);
    7269         2104 :       *expr_p = NULL_TREE;
    7270         2104 :       return GS_ALL_DONE;
    7271              :     }
    7272              : 
    7273              :   /* If the value being copied is of variable width, compute the length
    7274              :      of the copy into a WITH_SIZE_EXPR.   Note that we need to do this
    7275              :      before gimplifying any of the operands so that we can resolve any
    7276              :      PLACEHOLDER_EXPRs in the size.  Also note that the RTL expander uses
    7277              :      the size of the expression to be copied, not of the destination, so
    7278              :      that is what we must do here.  */
    7279     47301476 :   maybe_with_size_expr (from_p);
    7280              : 
    7281              :   /* As a special case, we have to temporarily allow for assignments
    7282              :      with a CALL_EXPR on the RHS.  Since in GIMPLE a function call is
    7283              :      a toplevel statement, when gimplifying the GENERIC expression
    7284              :      MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
    7285              :      GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
    7286              : 
    7287              :      Instead, we need to create the tuple GIMPLE_CALL <a, foo>.  To
    7288              :      prevent gimplify_expr from trying to create a new temporary for
    7289              :      foo's LHS, we tell it that it should only gimplify until it
    7290              :      reaches the CALL_EXPR.  On return from gimplify_expr, the newly
    7291              :      created GIMPLE_CALL <foo> will be the last statement in *PRE_P
    7292              :      and all we need to do here is set 'a' to be its LHS.  */
    7293              : 
    7294              :   /* Gimplify the RHS first for C++17 and bug 71104.  */
    7295     47301476 :   gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
    7296     47301476 :   ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
    7297     47301476 :   if (ret == GS_ERROR)
    7298              :     return ret;
    7299              : 
    7300              :   /* Then gimplify the LHS.  */
    7301              :   /* If we gimplified the RHS to a CALL_EXPR and that call may return
    7302              :      twice we have to make sure to gimplify into non-SSA as otherwise
    7303              :      the abnormal edge added later will make those defs not dominate
    7304              :      their uses.
    7305              :      ???  Technically this applies only to the registers used in the
    7306              :      resulting non-register *TO_P.  */
    7307     47301314 :   bool saved_into_ssa = gimplify_ctxp->into_ssa;
    7308     47301314 :   if (saved_into_ssa
    7309     44940527 :       && TREE_CODE (*from_p) == CALL_EXPR
    7310     52260643 :       && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
    7311         1530 :     gimplify_ctxp->into_ssa = false;
    7312     47301314 :   ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
    7313     47301314 :   gimplify_ctxp->into_ssa = saved_into_ssa;
    7314     47301314 :   if (ret == GS_ERROR)
    7315              :     return ret;
    7316              : 
    7317              :   /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
    7318              :      guess for the predicate was wrong.  */
    7319     47301239 :   gimple_predicate final_pred = rhs_predicate_for (*to_p);
    7320     47301239 :   if (final_pred != initial_pred)
    7321              :     {
    7322      8084260 :       ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
    7323      8084260 :       if (ret == GS_ERROR)
    7324              :         return ret;
    7325              :     }
    7326              : 
    7327              :   /* In case of va_arg internal fn wrapped in a WITH_SIZE_EXPR, add the type
    7328              :      size as argument to the call.  */
    7329     47301239 :   if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
    7330              :     {
    7331         1458 :       tree call = TREE_OPERAND (*from_p, 0);
    7332         1458 :       tree vlasize = TREE_OPERAND (*from_p, 1);
    7333              : 
    7334         1458 :       if (TREE_CODE (call) == CALL_EXPR
    7335         1458 :           && CALL_EXPR_IFN (call) == IFN_VA_ARG)
    7336              :         {
    7337           95 :           int nargs = call_expr_nargs (call);
    7338           95 :           tree type = TREE_TYPE (call);
    7339           95 :           tree ap = CALL_EXPR_ARG (call, 0);
    7340           95 :           tree tag = CALL_EXPR_ARG (call, 1);
    7341           95 :           tree aptag = CALL_EXPR_ARG (call, 2);
    7342           95 :           tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
    7343              :                                                        IFN_VA_ARG, type,
    7344              :                                                        nargs + 1, ap, tag,
    7345              :                                                        aptag, vlasize);
    7346           95 :           TREE_OPERAND (*from_p, 0) = newcall;
    7347              :         }
    7348              :     }
    7349              : 
    7350              :   /* Now see if the above changed *from_p to something we handle specially.  */
    7351     47301239 :   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
    7352              :                                   want_value);
    7353     47301239 :   if (ret != GS_UNHANDLED)
    7354              :     return ret;
    7355              : 
    7356              :   /* If we've got a variable sized assignment between two lvalues (i.e. does
    7357              :      not involve a call), then we can make things a bit more straightforward
    7358              :      by converting the assignment to memcpy or memset.  */
    7359     47300276 :   if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
    7360              :     {
    7361         1107 :       tree from = TREE_OPERAND (*from_p, 0);
    7362         1107 :       tree size = TREE_OPERAND (*from_p, 1);
    7363              : 
    7364         1107 :       if (TREE_CODE (from) == CONSTRUCTOR)
    7365            0 :         return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
    7366         1107 :       else if (is_gimple_addressable (from)
    7367         1107 :                && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (*to_p)))
    7368         2213 :                && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from))))
    7369              :         {
    7370         1106 :           *from_p = from;
    7371         1106 :           return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
    7372         1106 :                                                  pre_p);
    7373              :         }
    7374              :     }
    7375              : 
    7376              :   /* Transform partial stores to non-addressable complex variables into
    7377              :      total stores.  This allows us to use real instead of virtual operands
    7378              :      for these variables, which improves optimization.  */
    7379     47299170 :   if ((TREE_CODE (*to_p) == REALPART_EXPR
    7380     47299170 :        || TREE_CODE (*to_p) == IMAGPART_EXPR)
    7381     47299170 :       && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
    7382         1942 :     return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
    7383              : 
    7384              :   /* Try to alleviate the effects of the gimplification creating artificial
    7385              :      temporaries (see for example is_gimple_reg_rhs) on the debug info, but
    7386              :      make sure not to create DECL_DEBUG_EXPR links across functions.  */
    7387     47297228 :   if (!gimplify_ctxp->into_ssa
    7388      2359861 :       && VAR_P (*from_p)
    7389       471098 :       && DECL_IGNORED_P (*from_p)
    7390       350285 :       && DECL_P (*to_p)
    7391       138206 :       && !DECL_IGNORED_P (*to_p)
    7392        38111 :       && decl_function_context (*to_p) == current_function_decl
    7393     47329779 :       && decl_function_context (*from_p) == current_function_decl)
    7394              :     {
    7395        32546 :       if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
    7396        27294 :         DECL_NAME (*from_p)
    7397        54588 :           = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
    7398        32546 :       DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
    7399        32546 :       SET_DECL_DEBUG_EXPR (*from_p, *to_p);
    7400              :    }
    7401              : 
    7402     47297228 :   if (want_value && TREE_THIS_VOLATILE (*to_p))
    7403          526 :     *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
    7404              : 
    7405     47297228 :   if (TREE_CODE (*from_p) == CALL_EXPR)
    7406              :     {
    7407              :       /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
    7408              :          instead of a GIMPLE_ASSIGN.  */
    7409      4668134 :       gcall *call_stmt;
    7410      4668134 :       if (CALL_EXPR_FN (*from_p) == NULL_TREE)
    7411              :         {
    7412              :           /* Gimplify internal functions created in the FEs.  */
    7413       307161 :           int nargs = call_expr_nargs (*from_p), i;
    7414       307161 :           enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
    7415       307161 :           auto_vec<tree> vargs (nargs);
    7416              : 
    7417      1548592 :           for (i = 0; i < nargs; i++)
    7418              :             {
    7419       934270 :               gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
    7420       934270 :                             EXPR_LOCATION (*from_p));
    7421       934270 :               vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
    7422              :             }
    7423       307161 :           call_stmt = gimple_build_call_internal_vec (ifn, vargs);
    7424       307161 :           gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
    7425       614322 :           gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
    7426       307161 :         }
    7427              :       else
    7428              :         {
    7429      4360973 :           tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
    7430      4360973 :           CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
    7431      4360973 :           STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
    7432      4360973 :           tree fndecl = get_callee_fndecl (*from_p);
    7433      4360973 :           if (fndecl
    7434      4246544 :               && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
    7435      4494669 :               && call_expr_nargs (*from_p) == 3)
    7436        66558 :             call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
    7437        66558 :                                                     CALL_EXPR_ARG (*from_p, 0),
    7438        66558 :                                                     CALL_EXPR_ARG (*from_p, 1),
    7439        66558 :                                                     CALL_EXPR_ARG (*from_p, 2));
    7440              :           else
    7441              :             {
    7442      4294415 :               call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
    7443              :             }
    7444              :         }
    7445      4668134 :       notice_special_calls (call_stmt);
    7446      4668134 :       if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
    7447      4667953 :         gimple_call_set_lhs (call_stmt, *to_p);
    7448          181 :       else if (TREE_CODE (*to_p) == SSA_NAME)
    7449              :         /* The above is somewhat premature, avoid ICEing later for a
    7450              :            SSA name w/o a definition.  We may have uses in the GIMPLE IL.
    7451              :            ???  This doesn't make it a default-def.  */
    7452           86 :         SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
    7453              : 
    7454              :       assign = call_stmt;
    7455              :     }
    7456              :   else
    7457              :     {
    7458     42629094 :       assign = gimple_build_assign (*to_p, *from_p);
    7459     42629094 :       gimple_set_location (assign, EXPR_LOCATION (*expr_p));
    7460     42629094 :       if (COMPARISON_CLASS_P (*from_p))
    7461      1219260 :         copy_warning (assign, *from_p);
    7462              :     }
    7463              : 
    7464     47297228 :   if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
    7465              :     {
    7466              :       /* We should have got an SSA name from the start.  */
    7467     34976788 :       gcc_assert (TREE_CODE (*to_p) == SSA_NAME
    7468              :                   || ! gimple_in_ssa_p (cfun));
    7469              :     }
    7470              : 
    7471     47297228 :   gimplify_seq_add_stmt (pre_p, assign);
    7472     47297228 :   gsi = gsi_last (*pre_p);
    7473     47297228 :   maybe_fold_stmt (&gsi);
    7474              : 
    7475     47297228 :   if (want_value)
    7476              :     {
    7477       661706 :       *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
    7478       661706 :       return GS_OK;
    7479              :     }
    7480              :   else
    7481     46635522 :     *expr_p = NULL;
    7482              : 
    7483     46635522 :   return GS_ALL_DONE;
    7484              : }
    7485              : 
    7486              : /* Gimplify a comparison between two variable-sized objects.  Do this
    7487              :    with a call to BUILT_IN_MEMCMP.  */
    7488              : 
    7489              : static enum gimplify_status
    7490            0 : gimplify_variable_sized_compare (tree *expr_p)
    7491              : {
    7492            0 :   location_t loc = EXPR_LOCATION (*expr_p);
    7493            0 :   tree op0 = TREE_OPERAND (*expr_p, 0);
    7494            0 :   tree op1 = TREE_OPERAND (*expr_p, 1);
    7495            0 :   tree t, arg, dest, src, expr;
    7496              : 
    7497            0 :   arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
    7498            0 :   arg = unshare_expr (arg);
    7499            0 :   arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
    7500            0 :   src = build_fold_addr_expr_loc (loc, op1);
    7501            0 :   dest = build_fold_addr_expr_loc (loc, op0);
    7502            0 :   t = builtin_decl_implicit (BUILT_IN_MEMCMP);
    7503            0 :   t = build_call_expr_loc (loc, t, 3, dest, src, arg);
    7504              : 
    7505            0 :   expr
    7506            0 :     = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
    7507            0 :   SET_EXPR_LOCATION (expr, loc);
    7508            0 :   *expr_p = expr;
    7509              : 
    7510            0 :   return GS_OK;
    7511              : }
    7512              : 
    7513              : /* Gimplify a comparison between two aggregate objects of integral scalar
    7514              :    mode as a comparison between the bitwise equivalent scalar values.  */
    7515              : 
    7516              : static enum gimplify_status
    7517           16 : gimplify_scalar_mode_aggregate_compare (tree *expr_p)
    7518              : {
    7519           16 :   const location_t loc = EXPR_LOCATION (*expr_p);
    7520           16 :   const enum tree_code code = TREE_CODE (*expr_p);
    7521           16 :   tree op0 = TREE_OPERAND (*expr_p, 0);
    7522           16 :   tree op1 = TREE_OPERAND (*expr_p, 1);
    7523           16 :   tree type = TREE_TYPE (op0);
    7524           16 :   tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
    7525              : 
    7526           16 :   op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
    7527           16 :   op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
    7528              : 
    7529              :   /* We need to perform ordering comparisons in memory order like memcmp and,
    7530              :      therefore, may need to byte-swap operands for little-endian targets.  */
    7531           16 :   if (code != EQ_EXPR && code != NE_EXPR)
    7532              :     {
    7533            0 :       gcc_assert (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN);
    7534            0 :       gcc_assert (TREE_CODE (scalar_type) == INTEGER_TYPE);
    7535            0 :       tree fndecl;
    7536              : 
    7537            0 :       if (BYTES_BIG_ENDIAN)
    7538              :         fndecl = NULL_TREE;
    7539              :       else
    7540            0 :         switch (int_size_in_bytes (scalar_type))
    7541              :           {
    7542              :           case 1:
    7543              :             fndecl = NULL_TREE;
    7544              :             break;
    7545            0 :           case 2:
    7546            0 :             fndecl = builtin_decl_implicit (BUILT_IN_BSWAP16);
    7547            0 :             break;
    7548            0 :           case 4:
    7549            0 :             fndecl = builtin_decl_implicit (BUILT_IN_BSWAP32);
    7550            0 :             break;
    7551            0 :           case 8:
    7552            0 :             fndecl = builtin_decl_implicit (BUILT_IN_BSWAP64);
    7553            0 :             break;
    7554            0 :           case 16:
    7555            0 :             fndecl = builtin_decl_implicit (BUILT_IN_BSWAP128);
    7556            0 :             break;
    7557            0 :           default:
    7558            0 :             gcc_unreachable ();
    7559              :           }
    7560              : 
    7561            0 :       if (fndecl)
    7562              :         {
    7563            0 :           op0 = build_call_expr_loc (loc, fndecl, 1, op0);
    7564            0 :           op1 = build_call_expr_loc (loc, fndecl, 1, op1);
    7565              :         }
    7566              :     }
    7567              : 
    7568           16 :   *expr_p = fold_build2_loc (loc, code, TREE_TYPE (*expr_p), op0, op1);
    7569              : 
    7570           16 :   return GS_OK;
    7571              : }
    7572              : 
    7573              : /* Gimplify an expression sequence.  This function gimplifies each
    7574              :    expression and rewrites the original expression with the last
    7575              :    expression of the sequence in GIMPLE form.
    7576              : 
    7577              :    PRE_P points to the list where the side effects for all the
    7578              :        expressions in the sequence will be emitted.
    7579              : 
    7580              :    WANT_VALUE is true when the result of the last COMPOUND_EXPR is used.  */
    7581              : 
    7582              : static enum gimplify_status
    7583      1093896 : gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
    7584              : {
    7585      1093896 :   tree t = *expr_p;
    7586              : 
    7587      1180115 :   do
    7588              :     {
    7589      1180115 :       tree *sub_p = &TREE_OPERAND (t, 0);
    7590              : 
    7591      1180115 :       if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
    7592       204156 :         gimplify_compound_expr (sub_p, pre_p, false);
    7593              :       else
    7594       975959 :         gimplify_stmt (sub_p, pre_p);
    7595              : 
    7596      1180115 :       t = TREE_OPERAND (t, 1);
    7597              :     }
    7598      1180115 :   while (TREE_CODE (t) == COMPOUND_EXPR);
    7599              : 
    7600      1093896 :   *expr_p = t;
    7601      1093896 :   if (want_value)
    7602              :     return GS_OK;
    7603              :   else
    7604              :     {
    7605       598152 :       gimplify_stmt (expr_p, pre_p);
    7606       598152 :       return GS_ALL_DONE;
    7607              :     }
    7608              : }
    7609              : 
    7610              : /* Gimplify a SAVE_EXPR node.  EXPR_P points to the expression to
    7611              :    gimplify.  After gimplification, EXPR_P will point to a new temporary
    7612              :    that holds the original value of the SAVE_EXPR node.
    7613              : 
    7614              :    PRE_P points to the list where side effects that must happen before
    7615              :    *EXPR_P should be stored.  */
    7616              : 
    7617              : static enum gimplify_status
    7618       439345 : gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
    7619              : {
    7620       439345 :   enum gimplify_status ret = GS_ALL_DONE;
    7621       439345 :   tree val;
    7622              : 
    7623       439345 :   gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
    7624       439345 :   val = TREE_OPERAND (*expr_p, 0);
    7625              : 
    7626       439345 :   if (val && TREE_TYPE (val) == error_mark_node)
    7627              :     return GS_ERROR;
    7628              : 
    7629              :   /* If the SAVE_EXPR has not been resolved, then evaluate it once.  */
    7630       439343 :   if (!SAVE_EXPR_RESOLVED_P (*expr_p))
    7631              :     {
    7632              :       /* The operand may be a void-valued expression.  It is
    7633              :          being executed only for its side-effects.  */
    7634       168402 :       if (TREE_TYPE (val) == void_type_node)
    7635              :         {
    7636          750 :           ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
    7637              :                                is_gimple_stmt, fb_none);
    7638          750 :           val = NULL;
    7639              :         }
    7640              :       else
    7641              :         /* The temporary may not be an SSA name as later abnormal and EH
    7642              :            control flow may invalidate use/def domination.  When in SSA
    7643              :            form then assume there are no such issues and SAVE_EXPRs only
    7644              :            appear via GENERIC foldings.  */
    7645       335304 :         val = get_initialized_tmp_var (val, pre_p, post_p,
    7646       335304 :                                        gimple_in_ssa_p (cfun));
    7647              : 
    7648       168402 :       TREE_OPERAND (*expr_p, 0) = val;
    7649       168402 :       SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
    7650              :     }
    7651              : 
    7652       439343 :   *expr_p = val;
    7653              : 
    7654       439343 :   return ret;
    7655              : }
    7656              : 
    7657              : /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
    7658              : 
    7659              :       unary_expr
    7660              :               : ...
    7661              :               | '&' varname
    7662              :               ...
    7663              : 
    7664              :     PRE_P points to the list where side effects that must happen before
    7665              :         *EXPR_P should be stored.
    7666              : 
    7667              :     POST_P points to the list where side effects that must happen after
    7668              :         *EXPR_P should be stored.  */
    7669              : 
    7670              : static enum gimplify_status
    7671     32518792 : gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
    7672              : {
    7673     32518792 :   tree expr = *expr_p;
    7674     32518792 :   tree op0 = TREE_OPERAND (expr, 0);
    7675     32518792 :   enum gimplify_status ret;
    7676     32518792 :   location_t loc = EXPR_LOCATION (*expr_p);
    7677              : 
    7678     32518792 :   switch (TREE_CODE (op0))
    7679              :     {
    7680        94325 :     case INDIRECT_REF:
    7681        94325 :     do_indirect_ref:
    7682              :       /* Check if we are dealing with an expression of the form '&*ptr'.
    7683              :          While the front end folds away '&*ptr' into 'ptr', these
    7684              :          expressions may be generated internally by the compiler (e.g.,
    7685              :          builtins like __builtin_va_end).  */
    7686              :       /* Caution: the silent array decomposition semantics we allow for
    7687              :          ADDR_EXPR means we can't always discard the pair.  */
    7688              :       /* Gimplification of the ADDR_EXPR operand may drop
    7689              :          cv-qualification conversions, so make sure we add them if
    7690              :          needed.  */
    7691        94325 :       {
    7692        94325 :         tree op00 = TREE_OPERAND (op0, 0);
    7693        94325 :         tree t_expr = TREE_TYPE (expr);
    7694        94325 :         tree t_op00 = TREE_TYPE (op00);
    7695              : 
    7696        94325 :         if (!useless_type_conversion_p (t_expr, t_op00))
    7697            0 :           op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
    7698        94325 :         *expr_p = op00;
    7699        94325 :         ret = GS_OK;
    7700              :       }
    7701        94325 :       break;
    7702              : 
    7703            0 :     case VIEW_CONVERT_EXPR:
    7704              :       /* Take the address of our operand and then convert it to the type of
    7705              :          this ADDR_EXPR.
    7706              : 
    7707              :          ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
    7708              :          all clear.  The impact of this transformation is even less clear.  */
    7709              : 
    7710              :       /* If the operand is a useless conversion, look through it.  Doing so
    7711              :          guarantees that the ADDR_EXPR and its operand will remain of the
    7712              :          same type.  */
    7713            0 :       if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
    7714            0 :         op0 = TREE_OPERAND (op0, 0);
    7715              : 
    7716            0 :       *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
    7717              :                                   build_fold_addr_expr_loc (loc,
    7718            0 :                                                         TREE_OPERAND (op0, 0)));
    7719            0 :       ret = GS_OK;
    7720            0 :       break;
    7721              : 
    7722        64924 :     case MEM_REF:
    7723        64924 :       if (integer_zerop (TREE_OPERAND (op0, 1)))
    7724        36547 :         goto do_indirect_ref;
    7725              : 
    7726              :       /* fall through */
    7727              : 
    7728     32441698 :     default:
    7729              :       /* If we see a call to a declared builtin or see its address
    7730              :          being taken (we can unify those cases here) then we can mark
    7731              :          the builtin for implicit generation by GCC.  */
    7732     32441698 :       if (TREE_CODE (op0) == FUNCTION_DECL
    7733     16224741 :           && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
    7734     36385025 :           && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
    7735      1280918 :         set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
    7736              : 
    7737              :       /* We use fb_either here because the C frontend sometimes takes
    7738              :          the address of a call that returns a struct; see
    7739              :          gcc.dg/c99-array-lval-1.c.  The gimplifier will correctly make
    7740              :          the implied temporary explicit.  */
    7741              : 
    7742              :       /* Make the operand addressable.  */
    7743     32441698 :       ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
    7744              :                            is_gimple_addressable, fb_either);
    7745     32441698 :       if (ret == GS_ERROR)
    7746              :         break;
    7747              : 
    7748              :       /* Then mark it.  Beware that it may not be possible to do so directly
    7749              :          if a temporary has been created by the gimplification.  */
    7750     32441696 :       prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
    7751              : 
    7752     32441696 :       op0 = TREE_OPERAND (expr, 0);
    7753              : 
    7754              :       /* For various reasons, the gimplification of the expression
    7755              :          may have made a new INDIRECT_REF.  */
    7756     32441696 :       if (INDIRECT_REF_P (op0)
    7757     32441696 :           || (TREE_CODE (op0) == MEM_REF
    7758        45608 :               && integer_zerop (TREE_OPERAND (op0, 1))))
    7759        17231 :         goto do_indirect_ref;
    7760              : 
    7761     32424465 :       mark_addressable (TREE_OPERAND (expr, 0));
    7762              : 
    7763              :       /* The FEs may end up building ADDR_EXPRs early on a decl with
    7764              :          an incomplete type.  Re-build ADDR_EXPRs in canonical form
    7765              :          here.  */
    7766     32424465 :       if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
    7767       145257 :         *expr_p = build_fold_addr_expr (op0);
    7768              : 
    7769              :       /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly.  */
    7770     32424465 :       if (TREE_CODE (*expr_p) == ADDR_EXPR)
    7771     32424464 :         recompute_tree_invariant_for_addr_expr (*expr_p);
    7772              : 
    7773              :       /* If we re-built the ADDR_EXPR add a conversion to the original type
    7774              :          if required.  */
    7775     32424465 :       if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
    7776            0 :         *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
    7777              : 
    7778              :       break;
    7779              :     }
    7780              : 
    7781     32518792 :   return ret;
    7782              : }
    7783              : 
    7784              : /* Return the number of times character C occurs in string S.  */
    7785              : 
    7786              : static int
    7787        94307 : num_occurrences (int c, const char *s)
    7788              : {
    7789        94307 :   int n = 0;
    7790       255985 :   while (*s)
    7791       161678 :     n += (*s++ == c);
    7792        94307 :   return n;
    7793              : }
    7794              : 
    7795              : /* A subroutine of gimplify_asm_expr.  Check that all operands have
    7796              :    the same number of alternatives.  Return -1 if this is violated.  Otherwise
    7797              :    return the number of alternatives.  */
    7798              : 
    7799              : static int
    7800       196414 : num_alternatives (const_tree link)
    7801              : {
    7802       196414 :   if (link == nullptr)
    7803              :     return 0;
    7804              : 
    7805        48488 :   const char *constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    7806        48488 :   int num = num_occurrences (',', constraint);
    7807              : 
    7808        48488 :   if (num + 1 > MAX_RECOG_ALTERNATIVES)
    7809              :     return -1;
    7810              : 
    7811        94307 :   for (link = TREE_CHAIN (link); link; link = TREE_CHAIN (link))
    7812              :     {
    7813        45819 :       constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    7814        91638 :       if (num_occurrences (',', constraint) != num)
    7815              :         return -1;
    7816              :     }
    7817        48488 :   return num + 1;
    7818              : }
    7819              : 
    7820              : /* Gimplify the operands of an ASM_EXPR.  Input operands should be a gimple
    7821              :    value; output operands should be a gimple lvalue.  */
    7822              : 
    7823              : static enum gimplify_status
    7824        98207 : gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
    7825              : {
    7826        98207 :   tree expr;
    7827        98207 :   int noutputs;
    7828        98207 :   const char **oconstraints;
    7829        98207 :   int i;
    7830        98207 :   tree link;
    7831        98207 :   const char *constraint;
    7832        98207 :   bool allows_mem, allows_reg, is_inout;
    7833        98207 :   enum gimplify_status ret, tret;
    7834        98207 :   gasm *stmt;
    7835        98207 :   vec<tree, va_gc> *inputs;
    7836        98207 :   vec<tree, va_gc> *outputs;
    7837        98207 :   vec<tree, va_gc> *clobbers;
    7838        98207 :   vec<tree, va_gc> *labels;
    7839        98207 :   tree link_next;
    7840              : 
    7841        98207 :   expr = *expr_p;
    7842        98207 :   noutputs = list_length (ASM_OUTPUTS (expr));
    7843        98207 :   oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
    7844              : 
    7845        98207 :   inputs = NULL;
    7846        98207 :   outputs = NULL;
    7847        98207 :   clobbers = NULL;
    7848        98207 :   labels = NULL;
    7849              : 
    7850        98207 :   int num_alternatives_out = num_alternatives (ASM_OUTPUTS (expr));
    7851        98207 :   int num_alternatives_in = num_alternatives (ASM_INPUTS (expr));
    7852        98207 :   if (num_alternatives_out == -1 || num_alternatives_in == -1
    7853        98207 :       || (num_alternatives_out > 0 && num_alternatives_in > 0
    7854        17156 :           && num_alternatives_out != num_alternatives_in))
    7855              :     {
    7856            0 :       error ("operand constraints for %<asm%> differ "
    7857              :              "in number of alternatives");
    7858            0 :       return GS_ERROR;
    7859              :     }
    7860        98207 :   int num_alternatives = MAX (num_alternatives_out, num_alternatives_in);
    7861              : 
    7862        98207 :   gimplify_reg_info reg_info (num_alternatives, noutputs);
    7863              : 
    7864        98207 :   link_next = NULL_TREE;
    7865       193670 :   for (link = ASM_CLOBBERS (expr); link; link = link_next)
    7866              :     {
    7867              :       /* The clobber entry could also be an error marker.  */
    7868        95463 :       if (TREE_CODE (TREE_VALUE (link)) == STRING_CST)
    7869              :         {
    7870        95440 :           const char *regname= TREE_STRING_POINTER (TREE_VALUE (link));
    7871        95440 :           int regno = decode_reg_name (regname);
    7872        95440 :           if (regno >= 0)
    7873        41262 :             reg_info.set_clobbered (regno);
    7874              :         }
    7875        95463 :       link_next = TREE_CHAIN (link);
    7876        95463 :       TREE_CHAIN (link) = NULL_TREE;
    7877        95463 :       vec_safe_push (clobbers, link);
    7878              :     }
    7879              : 
    7880        98207 :   ret = GS_ALL_DONE;
    7881        98207 :   link_next = NULL_TREE;
    7882       159258 :   for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
    7883              :     {
    7884        61084 :       bool ok;
    7885        61084 :       size_t constraint_len;
    7886              : 
    7887        61084 :       if (error_operand_p (TREE_VALUE (link)))
    7888              :         return GS_ERROR;
    7889        61063 :       link_next = TREE_CHAIN (link);
    7890              : 
    7891       122126 :       oconstraints[i]
    7892        61063 :         = constraint
    7893        61063 :         = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    7894        61063 :       constraint_len = strlen (constraint);
    7895        61063 :       if (constraint_len == 0)
    7896            0 :         continue;
    7897              : 
    7898        61063 :       reg_info.operand = TREE_VALUE (link);
    7899        61063 :       ok = parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
    7900              :                                     &allows_reg, &is_inout, &reg_info);
    7901        61063 :       if (!ok)
    7902              :         {
    7903           11 :           ret = GS_ERROR;
    7904           11 :           is_inout = false;
    7905              :         }
    7906              : 
    7907              :       /* If we can't make copies, we can only accept memory.
    7908              :          Similarly for VLAs.  */
    7909        61063 :       tree outtype = TREE_TYPE (TREE_VALUE (link));
    7910        61063 :       if (TREE_ADDRESSABLE (outtype)
    7911        61048 :           || !COMPLETE_TYPE_P (outtype)
    7912       122086 :           || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype)))
    7913              :         {
    7914          303 :           if (allows_mem)
    7915          291 :             allows_reg = 0;
    7916              :           else
    7917              :             {
    7918           12 :               error ("impossible constraint in %<asm%>");
    7919           12 :               error ("non-memory output %d must stay in memory", i);
    7920           12 :               return GS_ERROR;
    7921              :             }
    7922              :         }
    7923              : 
    7924        61051 :       if (!allows_reg && allows_mem)
    7925         1807 :         mark_addressable (TREE_VALUE (link));
    7926              : 
    7927        61051 :       tree orig = TREE_VALUE (link);
    7928       113434 :       tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
    7929              :                             is_inout ? is_gimple_min_lval : is_gimple_lvalue,
    7930              :                             fb_lvalue | fb_mayfail);
    7931        61051 :       if (tret == GS_ERROR)
    7932              :         {
    7933            0 :           if (orig != error_mark_node)
    7934            0 :             error ("invalid lvalue in %<asm%> output %d", i);
    7935              :           ret = tret;
    7936              :         }
    7937              : 
    7938              :       /* If the gimplified operand is a register we do not allow memory.  */
    7939        61051 :       if (allows_reg
    7940        59241 :           && allows_mem
    7941        66977 :           && (is_gimple_reg (TREE_VALUE (link))
    7942          267 :               || (handled_component_p (TREE_VALUE (link))
    7943           36 :                   && is_gimple_reg (TREE_OPERAND (TREE_VALUE (link), 0)))))
    7944         5660 :         allows_mem = 0;
    7945              : 
    7946              :       /* If the constraint does not allow memory make sure we gimplify
    7947              :          it to a register if it is not already but its base is.  This
    7948              :          happens for complex and vector components.  */
    7949        61051 :       if (!allows_mem)
    7950              :         {
    7951        58978 :           tree op = TREE_VALUE (link);
    7952        58978 :           if (! is_gimple_val (op)
    7953        21654 :               && is_gimple_reg_type (TREE_TYPE (op))
    7954        80631 :               && is_gimple_reg (get_base_address (op)))
    7955              :             {
    7956           19 :               tree tem = create_tmp_reg (TREE_TYPE (op));
    7957           19 :               tree ass;
    7958           19 :               if (is_inout)
    7959              :                 {
    7960            7 :                   ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
    7961              :                                 tem, unshare_expr (op));
    7962            7 :                   gimplify_and_add (ass, pre_p);
    7963              :                 }
    7964           19 :               ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
    7965           19 :               gimplify_and_add (ass, post_p);
    7966              : 
    7967           19 :               TREE_VALUE (link) = tem;
    7968           19 :               tret = GS_OK;
    7969              :             }
    7970              :         }
    7971              : 
    7972        61051 :       vec_safe_push (outputs, link);
    7973        61051 :       TREE_CHAIN (link) = NULL_TREE;
    7974              : 
    7975        61051 :       if (is_inout)
    7976              :         {
    7977              :           /* An input/output operand.  To give the optimizers more
    7978              :              flexibility, split it into separate input and output
    7979              :              operands.  */
    7980         8668 :           tree input;
    7981              :           /* Buffer big enough to format a 32-bit UINT_MAX into.  */
    7982         8668 :           char buf[11];
    7983              : 
    7984              :           /* Turn the in/out constraint into an output constraint.  */
    7985         8668 :           char *p = xstrdup (constraint);
    7986         8668 :           p[0] = '=';
    7987         8668 :           TREE_PURPOSE (link) = unshare_expr (TREE_PURPOSE (link));
    7988         8668 :           TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
    7989              : 
    7990              :           /* And add a matching input constraint.  */
    7991         8668 :           if (allows_reg)
    7992              :             {
    7993         8167 :               sprintf (buf, "%u", i);
    7994              : 
    7995              :               /* If there are multiple alternatives in the constraint,
    7996              :                  handle each of them individually.  Those that allow register
    7997              :                  will be replaced with operand number, the others will stay
    7998              :                  unchanged.  */
    7999         8167 :               if (strchr (p, ',') != NULL)
    8000              :                 {
    8001          100 :                   size_t len = 0, buflen = strlen (buf);
    8002          100 :                   char *beg, *end, *str, *dst;
    8003              : 
    8004          100 :                   for (beg = p + 1;;)
    8005              :                     {
    8006          200 :                       end = strchr (beg, ',');
    8007          200 :                       if (end == NULL)
    8008          100 :                         end = strchr (beg, '\0');
    8009          200 :                       if ((size_t) (end - beg) < buflen)
    8010           28 :                         len += buflen + 1;
    8011              :                       else
    8012          172 :                         len += end - beg + 1;
    8013          200 :                       if (*end)
    8014          100 :                         beg = end + 1;
    8015              :                       else
    8016              :                         break;
    8017              :                     }
    8018              : 
    8019          100 :                   str = (char *) alloca (len);
    8020          100 :                   for (beg = p + 1, dst = str;;)
    8021              :                     {
    8022          200 :                       const char *tem;
    8023          200 :                       bool mem_p, reg_p, inout_p;
    8024              : 
    8025          200 :                       end = strchr (beg, ',');
    8026          200 :                       if (end)
    8027          100 :                         *end = '\0';
    8028          200 :                       beg[-1] = '=';
    8029          200 :                       tem = beg - 1;
    8030          200 :                       parse_output_constraint (&tem, i, 0, 0, &mem_p, &reg_p,
    8031              :                                                &inout_p, nullptr);
    8032          200 :                       if (dst != str)
    8033          100 :                         *dst++ = ',';
    8034          200 :                       if (reg_p)
    8035              :                         {
    8036          115 :                           memcpy (dst, buf, buflen);
    8037          115 :                           dst += buflen;
    8038              :                         }
    8039              :                       else
    8040              :                         {
    8041           85 :                           if (end)
    8042            0 :                             len = end - beg;
    8043              :                           else
    8044           85 :                             len = strlen (beg);
    8045           85 :                           memcpy (dst, beg, len);
    8046           85 :                           dst += len;
    8047              :                         }
    8048          200 :                       if (end)
    8049          100 :                         beg = end + 1;
    8050              :                       else
    8051              :                         break;
    8052          100 :                     }
    8053          100 :                   *dst = '\0';
    8054          100 :                   input = build_string (dst - str, str);
    8055              :                 }
    8056              :               else
    8057         8067 :                 input = build_string (strlen (buf), buf);
    8058              :             }
    8059              :           else
    8060          501 :             input = build_string (constraint_len - 1, constraint + 1);
    8061              : 
    8062         8668 :           free (p);
    8063              : 
    8064         8668 :           input = build_tree_list (build_tree_list (NULL_TREE, input),
    8065         8668 :                                    unshare_expr (TREE_VALUE (link)));
    8066         8668 :           ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
    8067              :         }
    8068              :     }
    8069              : 
    8070              :   /* After all output operands have been gimplified, verify that each output
    8071              :      operand is used at most once in case of hard register constraints.  Thus,
    8072              :      error out in cases like
    8073              :        asm ("" : "={0}" (x), "={1}" (x));
    8074              :      or even for
    8075              :        asm ("" : "=r" (x), "={1}" (x));
    8076              : 
    8077              :      FIXME: Ideally we would also error out for cases like
    8078              :        int x;
    8079              :        asm ("" : "=r" (x), "=r" (x));
    8080              :      However, since code like that was previously accepted, erroring out now might
    8081              :      break existing code.  On the other hand, we already error out for register
    8082              :      asm like
    8083              :        register int x asm ("0");
    8084              :        asm ("" : "=r" (x), "=r" (x));
    8085              :      Thus, maybe it wouldn't be too bad to also error out in the former
    8086              :      non-register-asm case.
    8087              :   */
    8088       159221 :   for (unsigned i = 0; i < vec_safe_length (outputs); ++i)
    8089              :     {
    8090        61049 :       tree link = (*outputs)[i];
    8091        61049 :       tree op1 = TREE_VALUE (link);
    8092        61049 :       const char *constraint
    8093        61049 :         = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    8094        61049 :       if (strchr (constraint, '{') != nullptr)
    8095          236 :         for (unsigned j = 0; j < vec_safe_length (outputs); ++j)
    8096              :           {
    8097          142 :             if (i == j)
    8098           95 :               continue;
    8099           47 :             tree link2 = (*outputs)[j];
    8100           47 :             tree op2 = TREE_VALUE (link2);
    8101           47 :             if (op1 == op2)
    8102              :               {
    8103            2 :                 error ("multiple outputs to lvalue %qE", op2);
    8104            2 :                 return GS_ERROR;
    8105              :               }
    8106              :           }
    8107              :     }
    8108              : 
    8109        98172 :   link_next = NULL_TREE;
    8110        98172 :   int input_num = 0;
    8111       140001 :   for (link = ASM_INPUTS (expr); link; ++input_num, ++i, link = link_next)
    8112              :     {
    8113        41887 :       if (error_operand_p (TREE_VALUE (link)))
    8114              :         return GS_ERROR;
    8115        41838 :       link_next = TREE_CHAIN (link);
    8116        41838 :       constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    8117        41838 :       reg_info.operand = TREE_VALUE (link);
    8118        41838 :       bool ok = parse_input_constraint (&constraint, input_num, 0, noutputs, 0,
    8119              :                                         oconstraints, &allows_mem, &allows_reg,
    8120              :                                         &reg_info);
    8121        41838 :       if (!ok)
    8122              :         {
    8123           30 :           ret = GS_ERROR;
    8124           30 :           is_inout = false;
    8125              :         }
    8126              : 
    8127              :       /* If we can't make copies, we can only accept memory.  */
    8128        41838 :       tree intype = TREE_TYPE (TREE_VALUE (link));
    8129        41838 :       if (TREE_ADDRESSABLE (intype)
    8130        41820 :           || !COMPLETE_TYPE_P (intype)
    8131        83619 :           || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype)))
    8132              :         {
    8133          312 :           if (allows_mem)
    8134          303 :             allows_reg = 0;
    8135              :           else
    8136              :             {
    8137            9 :               error ("impossible constraint in %<asm%>");
    8138            9 :               error ("non-memory input %d must stay in memory", i);
    8139            9 :               return GS_ERROR;
    8140              :             }
    8141              :         }
    8142              : 
    8143              :       /* If the operand is a memory input, it should be an lvalue.  */
    8144        41829 :       if (!allows_reg && allows_mem)
    8145              :         {
    8146         2165 :           tree inputv = TREE_VALUE (link);
    8147         2165 :           STRIP_NOPS (inputv);
    8148         2165 :           if (TREE_CODE (inputv) == PREDECREMENT_EXPR
    8149              :               || TREE_CODE (inputv) == PREINCREMENT_EXPR
    8150              :               || TREE_CODE (inputv) == POSTDECREMENT_EXPR
    8151         2165 :               || TREE_CODE (inputv) == POSTINCREMENT_EXPR
    8152         2153 :               || TREE_CODE (inputv) == MODIFY_EXPR
    8153         4316 :               || VOID_TYPE_P (TREE_TYPE (inputv)))
    8154           38 :             TREE_VALUE (link) = error_mark_node;
    8155         2165 :           tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
    8156              :                                 is_gimple_lvalue, fb_lvalue | fb_mayfail);
    8157         2165 :           if (tret != GS_ERROR)
    8158              :             {
    8159              :               /* Unlike output operands, memory inputs are not guaranteed
    8160              :                  to be lvalues by the FE, and while the expressions are
    8161              :                  marked addressable there, if it is e.g. a statement
    8162              :                  expression, temporaries in it might not end up being
    8163              :                  addressable.  They might be already used in the IL and thus
    8164              :                  it is too late to make them addressable now though.  */
    8165         2119 :               tree x = TREE_VALUE (link);
    8166         2261 :               while (handled_component_p (x))
    8167          142 :                 x = TREE_OPERAND (x, 0);
    8168         2119 :               if (TREE_CODE (x) == MEM_REF
    8169         2119 :                   && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
    8170            0 :                 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
    8171         2119 :               if ((VAR_P (x)
    8172              :                    || TREE_CODE (x) == PARM_DECL
    8173              :                    || TREE_CODE (x) == RESULT_DECL)
    8174         1530 :                   && !TREE_ADDRESSABLE (x)
    8175           23 :                   && is_gimple_reg (x))
    8176              :                 {
    8177           17 :                   warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
    8178           17 :                                                input_location), 0,
    8179              :                               "memory input %d is not directly addressable",
    8180              :                               i);
    8181           17 :                   prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
    8182              :                 }
    8183              :             }
    8184         2165 :           mark_addressable (TREE_VALUE (link));
    8185         2165 :           if (tret == GS_ERROR)
    8186              :             {
    8187           46 :               if (inputv != error_mark_node)
    8188           46 :                 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
    8189              :                           "memory input %d is not directly addressable", i);
    8190              :               ret = tret;
    8191              :             }
    8192              :         }
    8193              :       else
    8194              :         {
    8195        39664 :           tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
    8196              :                                 is_gimple_asm_val, fb_rvalue);
    8197        39664 :           if (tret == GS_ERROR)
    8198           46 :             ret = tret;
    8199              :         }
    8200              : 
    8201        41829 :       TREE_CHAIN (link) = NULL_TREE;
    8202        41829 :       vec_safe_push (inputs, link);
    8203              :     }
    8204              : 
    8205        98114 :   link_next = NULL_TREE;
    8206        99011 :   for (link = ASM_LABELS (expr); link; link = link_next)
    8207              :     {
    8208          897 :       link_next = TREE_CHAIN (link);
    8209          897 :       TREE_CHAIN (link) = NULL_TREE;
    8210          897 :       vec_safe_push (labels, link);
    8211              :     }
    8212              : 
    8213              :   /* Do not add ASMs with errors to the gimple IL stream.  */
    8214        98114 :   if (ret != GS_ERROR)
    8215              :     {
    8216        98031 :       stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
    8217              :                                    inputs, outputs, clobbers, labels);
    8218              : 
    8219              :       /* asm is volatile if it was marked by the user as volatile or
    8220              :          there are no outputs or this is an asm goto.  */
    8221       196062 :       gimple_asm_set_volatile (stmt,
    8222        98031 :                                ASM_VOLATILE_P (expr)
    8223         7541 :                                || noutputs == 0
    8224       105558 :                                || labels);
    8225        98031 :       gimple_asm_set_basic (stmt, ASM_BASIC_P (expr));
    8226        98031 :       gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
    8227              : 
    8228        98031 :       gimplify_seq_add_stmt (pre_p, stmt);
    8229              :     }
    8230              : 
    8231              :   return ret;
    8232        98207 : }
    8233              : 
    8234              : /* Gimplify a CLEANUP_POINT_EXPR.  Currently this works by adding
    8235              :    GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
    8236              :    gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
    8237              :    return to this function.
    8238              : 
    8239              :    FIXME should we complexify the prequeue handling instead?  Or use flags
    8240              :    for all the cleanups and let the optimizer tighten them up?  The current
    8241              :    code seems pretty fragile; it will break on a cleanup within any
    8242              :    non-conditional nesting.  But any such nesting would be broken, anyway;
    8243              :    we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
    8244              :    and continues out of it.  We can do that at the RTL level, though, so
    8245              :    having an optimizer to tighten up try/finally regions would be a Good
    8246              :    Thing.  */
    8247              : 
    8248              : static enum gimplify_status
    8249      5105785 : gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
    8250              : {
    8251      5105785 :   gimple_stmt_iterator iter;
    8252      5105785 :   gimple_seq body_sequence = NULL;
    8253              : 
    8254      5105785 :   tree temp = voidify_wrapper_expr (*expr_p, NULL);
    8255              : 
    8256              :   /* We only care about the number of conditions between the innermost
    8257              :      CLEANUP_POINT_EXPR and the cleanup.  So save and reset the count and
    8258              :      any cleanups collected outside the CLEANUP_POINT_EXPR.  */
    8259      5105785 :   int old_conds = gimplify_ctxp->conditions;
    8260      5105785 :   gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
    8261      5105785 :   bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
    8262      5105785 :   gimplify_ctxp->conditions = 0;
    8263      5105785 :   gimplify_ctxp->conditional_cleanups = NULL;
    8264      5105785 :   gimplify_ctxp->in_cleanup_point_expr = true;
    8265              : 
    8266      5105785 :   gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
    8267              : 
    8268      5105785 :   gimplify_ctxp->conditions = old_conds;
    8269      5105785 :   gimplify_ctxp->conditional_cleanups = old_cleanups;
    8270      5105785 :   gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
    8271              : 
    8272     26546039 :   for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
    8273              :     {
    8274     16374378 :       gimple *wce = gsi_stmt (iter);
    8275              : 
    8276     16374378 :       if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
    8277              :         {
    8278       584849 :           if (gsi_one_before_end_p (iter))
    8279              :             {
    8280              :               /* Note that gsi_insert_seq_before and gsi_remove do not
    8281              :                  scan operands, unlike some other sequence mutators.  */
    8282         3029 :               if (!gimple_wce_cleanup_eh_only (wce))
    8283         3029 :                 gsi_insert_seq_before_without_update (&iter,
    8284              :                                                       gimple_wce_cleanup (wce),
    8285              :                                                       GSI_SAME_STMT);
    8286         3029 :               gsi_remove (&iter, true);
    8287         3029 :               break;
    8288              :             }
    8289              :           else
    8290              :             {
    8291       581820 :               gtry *gtry;
    8292       581820 :               gimple_seq seq;
    8293       581820 :               enum gimple_try_flags kind;
    8294              : 
    8295       581820 :               if (gimple_wce_cleanup_eh_only (wce))
    8296              :                 kind = GIMPLE_TRY_CATCH;
    8297              :               else
    8298       568131 :                 kind = GIMPLE_TRY_FINALLY;
    8299       581820 :               seq = gsi_split_seq_after (iter);
    8300              : 
    8301       581820 :               gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
    8302              :               /* Do not use gsi_replace here, as it may scan operands.
    8303              :                  We want to do a simple structural modification only.  */
    8304       581820 :               gsi_set_stmt (&iter, gtry);
    8305      1163640 :               iter = gsi_start (gtry->eval);
    8306              :             }
    8307              :         }
    8308              :       else
    8309     15789529 :         gsi_next (&iter);
    8310              :     }
    8311              : 
    8312      5105785 :   gimplify_seq_add_seq (pre_p, body_sequence);
    8313      5105785 :   if (temp)
    8314              :     {
    8315       341241 :       *expr_p = temp;
    8316       341241 :       return GS_OK;
    8317              :     }
    8318              :   else
    8319              :     {
    8320      4764544 :       *expr_p = NULL;
    8321      4764544 :       return GS_ALL_DONE;
    8322              :     }
    8323              : }
    8324              : 
    8325              : /* Insert a cleanup marker for gimplify_cleanup_point_expr.  CLEANUP
    8326              :    is the cleanup action required.  EH_ONLY is true if the cleanup should
    8327              :    only be executed if an exception is thrown, not on normal exit.
    8328              :    If FORCE_UNCOND is true perform the cleanup unconditionally;  this is
    8329              :    only valid for clobbers.  */
    8330              : 
    8331              : static void
    8332       589696 : gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
    8333              :                      bool force_uncond = false)
    8334              : {
    8335       589696 :   gimple *wce;
    8336       589696 :   gimple_seq cleanup_stmts = NULL;
    8337              : 
    8338              :   /* Errors can result in improperly nested cleanups.  Which results in
    8339              :      confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR.  */
    8340       589696 :   if (seen_error ())
    8341         4847 :     return;
    8342              : 
    8343       584849 :   if (gimple_conditional_context ())
    8344              :     {
    8345              :       /* If we're in a conditional context, this is more complex.  We only
    8346              :          want to run the cleanup if we actually ran the initialization that
    8347              :          necessitates it, but we want to run it after the end of the
    8348              :          conditional context.  So we wrap the try/finally around the
    8349              :          condition and use a flag to determine whether or not to actually
    8350              :          run the destructor.  Thus
    8351              : 
    8352              :            test ? f(A()) : 0
    8353              : 
    8354              :          becomes (approximately)
    8355              : 
    8356              :            flag = 0;
    8357              :            try {
    8358              :              if (test) { A::A(temp); flag = 1; val = f(temp); }
    8359              :              else { val = 0; }
    8360              :            } finally {
    8361              :              if (flag) A::~A(temp);
    8362              :            }
    8363              :            val
    8364              :       */
    8365        14223 :       if (force_uncond)
    8366              :         {
    8367        13337 :           gimplify_stmt (&cleanup, &cleanup_stmts);
    8368        13337 :           wce = gimple_build_wce (cleanup_stmts);
    8369        13337 :           gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
    8370              :         }
    8371              :       else
    8372              :         {
    8373          886 :           tree flag = create_tmp_var (boolean_type_node, "cleanup");
    8374          886 :           gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
    8375          886 :           gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
    8376              : 
    8377          886 :           cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
    8378          886 :           gimplify_stmt (&cleanup, &cleanup_stmts);
    8379          886 :           wce = gimple_build_wce (cleanup_stmts);
    8380          886 :           gimple_wce_set_cleanup_eh_only (wce, eh_only);
    8381              : 
    8382          886 :           gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
    8383          886 :           gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
    8384          886 :           gimplify_seq_add_stmt (pre_p, ftrue);
    8385              : 
    8386              :           /* Because of this manipulation, and the EH edges that jump
    8387              :              threading cannot redirect, the temporary (VAR) will appear
    8388              :              to be used uninitialized.  Don't warn.  */
    8389          886 :           suppress_warning (var, OPT_Wuninitialized);
    8390              :         }
    8391              :     }
    8392              :   else
    8393              :     {
    8394       570626 :       gimplify_stmt (&cleanup, &cleanup_stmts);
    8395       570626 :       wce = gimple_build_wce (cleanup_stmts);
    8396       570626 :       gimple_wce_set_cleanup_eh_only (wce, eh_only);
    8397       570626 :       gimplify_seq_add_stmt (pre_p, wce);
    8398              :     }
    8399              : }
    8400              : 
    8401              : /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR.  */
    8402              : 
    8403              : static enum gimplify_status
    8404       790742 : gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
    8405              : {
    8406       790742 :   tree targ = *expr_p;
    8407       790742 :   tree temp = TARGET_EXPR_SLOT (targ);
    8408       790742 :   tree init = TARGET_EXPR_INITIAL (targ);
    8409       790742 :   enum gimplify_status ret;
    8410              : 
    8411       790742 :   bool unpoison_empty_seq = false;
    8412       790742 :   gimple_stmt_iterator unpoison_it;
    8413              : 
    8414       790742 :   if (init)
    8415              :     {
    8416       756655 :       gimple_seq init_pre_p = NULL;
    8417       756655 :       bool is_vla = false;
    8418              : 
    8419              :       /* TARGET_EXPR temps aren't part of the enclosing block, so add it
    8420              :          to the temps list.  Handle also variable length TARGET_EXPRs.  */
    8421       756655 :       if (!poly_int_tree_p (DECL_SIZE (temp)))
    8422              :         {
    8423           44 :           if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
    8424            1 :             gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p);
    8425              :           /* FIXME: this is correct only when the size of the type does
    8426              :              not depend on expressions evaluated in init.  */
    8427           44 :           gimplify_vla_decl (temp, &init_pre_p);
    8428           44 :           is_vla = true;
    8429              :         }
    8430              :       else
    8431              :         {
    8432              :           /* Save location where we need to place unpoisoning.  It's possible
    8433              :              that a variable will be converted to needs_to_live_in_memory.  */
    8434       756611 :           unpoison_it = gsi_last (*pre_p);
    8435       756611 :           unpoison_empty_seq = gsi_end_p (unpoison_it);
    8436              : 
    8437       756611 :           gimple_add_tmp_var (temp);
    8438              :         }
    8439              : 
    8440       756655 :       if (var_needs_auto_init_p (temp) && VOID_TYPE_P (TREE_TYPE (init)))
    8441              :         {
    8442        47871 :           gimple_add_init_for_auto_var (temp, flag_auto_var_init, &init_pre_p);
    8443        47871 :           if (flag_auto_var_init == AUTO_INIT_PATTERN
    8444            0 :               && !is_gimple_reg (temp)
    8445        47871 :               && clear_padding_type_may_have_padding_p (TREE_TYPE (temp)))
    8446            0 :             gimple_add_padding_init_for_auto_var (temp, is_vla, &init_pre_p);
    8447              :         }
    8448              : 
    8449              :       /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
    8450              :          expression is supposed to initialize the slot.  */
    8451       756655 :       if (VOID_TYPE_P (TREE_TYPE (init)))
    8452       272578 :         ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
    8453              :                              fb_none);
    8454              :       else
    8455              :         {
    8456       484077 :           tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
    8457       484077 :           init = init_expr;
    8458       484077 :           ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
    8459              :                                fb_none);
    8460       484077 :           init = NULL;
    8461       484077 :           ggc_free (init_expr);
    8462              :         }
    8463       756655 :       if (ret == GS_ERROR)
    8464              :         {
    8465              :           /* PR c++/28266 Make sure this is expanded only once. */
    8466           10 :           TARGET_EXPR_INITIAL (targ) = NULL_TREE;
    8467           10 :           return GS_ERROR;
    8468              :         }
    8469              : 
    8470       756645 :       if (init)
    8471            0 :         gimplify_and_add (init, &init_pre_p);
    8472              : 
    8473              :       /* Add a clobber for the temporary going out of scope, like
    8474              :          gimplify_bind_expr.  But only if we did not promote the
    8475              :          temporary to static storage.  */
    8476       756645 :       if (gimplify_ctxp->in_cleanup_point_expr
    8477       611378 :           && !TREE_STATIC (temp)
    8478      1366620 :           && needs_to_live_in_memory (temp))
    8479              :         {
    8480       451232 :           if (flag_stack_reuse == SR_ALL)
    8481              :             {
    8482       450746 :               tree clobber = build_clobber (TREE_TYPE (temp),
    8483              :                                             CLOBBER_STORAGE_END);
    8484       450746 :               clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
    8485       450746 :               gimple_push_cleanup (temp, clobber, false, pre_p, true);
    8486              :             }
    8487       451232 :           if (asan_poisoned_variables
    8488          486 :               && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
    8489          486 :               && !TREE_STATIC (temp)
    8490          486 :               && dbg_cnt (asan_use_after_scope)
    8491       451718 :               && !gimplify_omp_ctxp)
    8492              :             {
    8493          478 :               tree asan_cleanup = build_asan_poison_call_expr (temp);
    8494          478 :               if (asan_cleanup)
    8495              :                 {
    8496          478 :                   if (unpoison_empty_seq)
    8497          223 :                     unpoison_it = gsi_start (*pre_p);
    8498              : 
    8499          478 :                   asan_poison_variable (temp, false, &unpoison_it,
    8500              :                                         unpoison_empty_seq);
    8501          478 :                   gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
    8502              :                 }
    8503              :             }
    8504              :         }
    8505              : 
    8506       756645 :       gimple_seq_add_seq (pre_p, init_pre_p);
    8507              : 
    8508              :       /* If needed, push the cleanup for the temp.  */
    8509       756645 :       if (TARGET_EXPR_CLEANUP (targ))
    8510       138472 :         gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
    8511       138472 :                              CLEANUP_EH_ONLY (targ), pre_p);
    8512              : 
    8513              :       /* Only expand this once.  */
    8514       756645 :       TREE_OPERAND (targ, 3) = init;
    8515       756645 :       TARGET_EXPR_INITIAL (targ) = NULL_TREE;
    8516              :     }
    8517              :   else
    8518              :     /* We should have expanded this before.  */
    8519        34087 :     gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
    8520              : 
    8521       790732 :   *expr_p = temp;
    8522       790732 :   return GS_OK;
    8523              : }
    8524              : 
    8525              : /* Gimplification of expression trees.  */
    8526              : 
    8527              : /* Gimplify an expression which appears at statement context.  The
    8528              :    corresponding GIMPLE statements are added to *SEQ_P.  If *SEQ_P is
    8529              :    NULL, a new sequence is allocated.
    8530              : 
    8531              :    Return true if we actually added a statement to the queue.  */
    8532              : 
    8533              : bool
    8534    101498366 : gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
    8535              : {
    8536    101498366 :   gimple_seq_node last;
    8537              : 
    8538    101498366 :   last = gimple_seq_last (*seq_p);
    8539    101498366 :   gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
    8540    101498366 :   return last != gimple_seq_last (*seq_p);
    8541              : }
    8542              : 
    8543              : /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
    8544              :    to CTX.  If entries already exist, force them to be some flavor of private.
    8545              :    If there is no enclosing parallel, do nothing.  */
    8546              : 
    8547              : void
    8548       123596 : omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
    8549              : {
    8550       123596 :   splay_tree_node n;
    8551              : 
    8552       123596 :   if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
    8553              :     return;
    8554              : 
    8555        36976 :   do
    8556              :     {
    8557        36976 :       n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
    8558        36976 :       if (n != NULL)
    8559              :         {
    8560         4298 :           if (n->value & GOVD_SHARED)
    8561          183 :             n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
    8562         4115 :           else if (n->value & GOVD_MAP)
    8563           58 :             n->value |= GOVD_MAP_TO_ONLY;
    8564              :           else
    8565              :             return;
    8566              :         }
    8567        32678 :       else if ((ctx->region_type & ORT_TARGET) != 0)
    8568              :         {
    8569         7020 :           if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
    8570         4261 :             omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
    8571              :           else
    8572         2759 :             omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
    8573              :         }
    8574        25658 :       else if (ctx->region_type != ORT_WORKSHARE
    8575              :                && ctx->region_type != ORT_TASKGROUP
    8576        23829 :                && ctx->region_type != ORT_SIMD
    8577        23205 :                && ctx->region_type != ORT_ACC
    8578        23088 :                && !(ctx->region_type & ORT_TARGET_DATA))
    8579        14507 :         omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
    8580              : 
    8581        32919 :       ctx = ctx->outer_context;
    8582              :     }
    8583        32919 :   while (ctx);
    8584              : }
    8585              : 
    8586              : /* Similarly for each of the type sizes of TYPE.  */
    8587              : 
    8588              : static void
    8589        39972 : omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
    8590              : {
    8591        39972 :   if (type == NULL || type == error_mark_node)
    8592              :     return;
    8593        39968 :   type = TYPE_MAIN_VARIANT (type);
    8594              : 
    8595        39968 :   if (ctx->privatized_types->add (type))
    8596              :     return;
    8597              : 
    8598        30581 :   switch (TREE_CODE (type))
    8599              :     {
    8600        13016 :     case INTEGER_TYPE:
    8601        13016 :     case ENUMERAL_TYPE:
    8602        13016 :     case BOOLEAN_TYPE:
    8603        13016 :     case REAL_TYPE:
    8604        13016 :     case FIXED_POINT_TYPE:
    8605        13016 :       omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
    8606        13016 :       omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
    8607        13016 :       break;
    8608              : 
    8609         5390 :     case ARRAY_TYPE:
    8610         5390 :       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
    8611         5390 :       omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
    8612         5390 :       break;
    8613              : 
    8614         2502 :     case RECORD_TYPE:
    8615         2502 :     case UNION_TYPE:
    8616         2502 :     case QUAL_UNION_TYPE:
    8617         2502 :       {
    8618         2502 :         tree field;
    8619        26645 :         for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    8620        24143 :           if (TREE_CODE (field) == FIELD_DECL)
    8621              :             {
    8622         8997 :               omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
    8623         8997 :               omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
    8624              :             }
    8625              :       }
    8626              :       break;
    8627              : 
    8628         9023 :     case POINTER_TYPE:
    8629         9023 :     case REFERENCE_TYPE:
    8630         9023 :       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
    8631         9023 :       break;
    8632              : 
    8633              :     default:
    8634              :       break;
    8635              :     }
    8636              : 
    8637        30581 :   omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
    8638        30581 :   omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
    8639        30581 :   lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
    8640              : }
    8641              : 
    8642              : /* Add an entry for DECL in the OMP context CTX with FLAGS.  */
    8643              : 
    8644              : static void
    8645       716217 : omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
    8646              : {
    8647       716217 :   splay_tree_node n;
    8648       716217 :   unsigned int nflags;
    8649       716217 :   tree t;
    8650              : 
    8651       716217 :   if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
    8652              :     return;
    8653              : 
    8654              :   /* Never elide decls whose type has TREE_ADDRESSABLE set.  This means
    8655              :      there are constructors involved somewhere.  Exception is a shared clause,
    8656              :      there is nothing privatized in that case.  */
    8657       716072 :   if ((flags & GOVD_SHARED) == 0
    8658       716072 :       && (TREE_ADDRESSABLE (TREE_TYPE (decl))
    8659       655681 :           || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
    8660         7766 :     flags |= GOVD_SEEN;
    8661              : 
    8662       716072 :   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
    8663       716072 :   if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
    8664              :     {
    8665              :       /* We shouldn't be re-adding the decl with the same data
    8666              :          sharing class.  */
    8667          824 :       gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
    8668          824 :       nflags = n->value | flags;
    8669              :       /* The only combination of data sharing classes we should see is
    8670              :          FIRSTPRIVATE and LASTPRIVATE.  However, OpenACC permits
    8671              :          reduction variables to be used in data sharing clauses.  */
    8672          824 :       gcc_assert ((ctx->region_type & ORT_ACC) != 0
    8673              :                   || ((nflags & GOVD_DATA_SHARE_CLASS)
    8674              :                       == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
    8675              :                   || (flags & GOVD_DATA_SHARE_CLASS) == 0);
    8676          824 :       n->value = nflags;
    8677          824 :       return;
    8678              :     }
    8679              : 
    8680              :   /* When adding a variable-sized variable, we have to handle all sorts
    8681              :      of additional bits of data: the pointer replacement variable, and
    8682              :      the parameters of the type.  */
    8683       715248 :   if (DECL_SIZE (decl) && !poly_int_tree_p (DECL_SIZE (decl)))
    8684              :     {
    8685              :       /* Add the pointer replacement variable as PRIVATE if the variable
    8686              :          replacement is private, else FIRSTPRIVATE since we'll need the
    8687              :          address of the original variable either for SHARED, or for the
    8688              :          copy into or out of the context.  */
    8689         1330 :       if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
    8690              :         {
    8691         1238 :           if (flags & GOVD_MAP)
    8692              :             nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
    8693          531 :           else if (flags & GOVD_PRIVATE)
    8694              :             nflags = GOVD_PRIVATE;
    8695          441 :           else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
    8696           50 :                     && (flags & GOVD_FIRSTPRIVATE))
    8697          431 :                    || (ctx->region_type == ORT_TARGET_DATA
    8698            6 :                        && (flags & GOVD_DATA_SHARE_CLASS) == 0))
    8699              :             nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
    8700              :           else
    8701         1238 :             nflags = GOVD_FIRSTPRIVATE;
    8702         1238 :           nflags |= flags & GOVD_SEEN;
    8703         1238 :           t = DECL_VALUE_EXPR (decl);
    8704         1238 :           gcc_assert (INDIRECT_REF_P (t));
    8705         1238 :           t = TREE_OPERAND (t, 0);
    8706         1238 :           gcc_assert (DECL_P (t));
    8707         1238 :           omp_add_variable (ctx, t, nflags);
    8708              :         }
    8709              : 
    8710              :       /* Add all of the variable and type parameters (which should have
    8711              :          been gimplified to a formal temporary) as FIRSTPRIVATE.  */
    8712         1330 :       omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
    8713         1330 :       omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
    8714         1330 :       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
    8715              : 
    8716              :       /* The variable-sized variable itself is never SHARED, only some form
    8717              :          of PRIVATE.  The sharing would take place via the pointer variable
    8718              :          which we remapped above.  */
    8719         1330 :       if (flags & GOVD_SHARED)
    8720          284 :         flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
    8721          284 :                 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
    8722              : 
    8723              :       /* We're going to make use of the TYPE_SIZE_UNIT at least in the
    8724              :          alloca statement we generate for the variable, so make sure it
    8725              :          is available.  This isn't automatically needed for the SHARED
    8726              :          case, since we won't be allocating local storage then.
    8727              :          For local variables TYPE_SIZE_UNIT might not be gimplified yet,
    8728              :          in this case omp_notice_variable will be called later
    8729              :          on when it is gimplified.  */
    8730         1046 :       else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
    8731         1046 :                && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
    8732          275 :         omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
    8733              :     }
    8734       713918 :   else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
    8735       713918 :            && omp_privatize_by_reference (decl))
    8736              :     {
    8737         9842 :       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
    8738              : 
    8739              :       /* Similar to the direct variable sized case above, we'll need the
    8740              :          size of references being privatized.  */
    8741         9842 :       if ((flags & GOVD_SHARED) == 0)
    8742              :         {
    8743         6157 :           t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
    8744         6157 :           if (t && DECL_P (t))
    8745         1397 :             omp_notice_variable (ctx, t, true);
    8746              :         }
    8747              :     }
    8748              : 
    8749       715248 :   if (n != NULL)
    8750         1868 :     n->value |= flags;
    8751              :   else
    8752       713380 :     splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
    8753              : 
    8754              :   /* For reductions clauses in OpenACC loop directives, by default create a
    8755              :      copy clause on the enclosing parallel construct for carrying back the
    8756              :      results.  */
    8757       715248 :   if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
    8758              :     {
    8759         4716 :       struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
    8760         6454 :       while (outer_ctx)
    8761              :         {
    8762         5788 :           n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
    8763         5788 :           if (n != NULL)
    8764              :             {
    8765              :               /* Ignore local variables and explicitly declared clauses.  */
    8766         3990 :               if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
    8767              :                 break;
    8768          443 :               else if (outer_ctx->region_type == ORT_ACC_KERNELS)
    8769              :                 {
    8770              :                   /* According to the OpenACC spec, such a reduction variable
    8771              :                      should already have a copy map on a kernels construct,
    8772              :                      verify that here.  */
    8773          143 :                   gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
    8774              :                               && (n->value & GOVD_MAP));
    8775              :                 }
    8776          300 :               else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
    8777              :                 {
    8778              :                   /* Remove firstprivate and make it a copy map.  */
    8779          150 :                   n->value &= ~GOVD_FIRSTPRIVATE;
    8780          150 :                   n->value |= GOVD_MAP;
    8781              :                 }
    8782              :             }
    8783         1798 :           else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
    8784              :             {
    8785          503 :               splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
    8786              :                                  GOVD_MAP | GOVD_SEEN);
    8787          503 :               break;
    8788              :             }
    8789         1738 :           outer_ctx = outer_ctx->outer_context;
    8790              :         }
    8791              :     }
    8792              : }
    8793              : 
    8794              : /* Notice a threadprivate variable DECL used in OMP context CTX.
    8795              :    This just prints out diagnostics about threadprivate variable uses
    8796              :    in untied tasks.  If DECL2 is non-NULL, prevent this warning
    8797              :    on that variable.  */
    8798              : 
    8799              : static bool
    8800        14183 : omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
    8801              :                                    tree decl2)
    8802              : {
    8803        14183 :   splay_tree_node n;
    8804        14183 :   struct gimplify_omp_ctx *octx;
    8805              : 
    8806        28798 :   for (octx = ctx; octx; octx = octx->outer_context)
    8807        14615 :     if ((octx->region_type & ORT_TARGET) != 0
    8808        14615 :         || octx->order_concurrent)
    8809              :       {
    8810          112 :         n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
    8811          112 :         if (n == NULL)
    8812              :           {
    8813           20 :             if (octx->order_concurrent)
    8814              :               {
    8815           20 :                 error ("threadprivate variable %qE used in a region with"
    8816           20 :                        " %<order(concurrent)%> clause", DECL_NAME (decl));
    8817           20 :                 inform (octx->location, "enclosing region");
    8818              :               }
    8819              :             else
    8820              :               {
    8821            0 :                 error ("threadprivate variable %qE used in target region",
    8822            0 :                        DECL_NAME (decl));
    8823            0 :                 inform (octx->location, "enclosing target region");
    8824              :               }
    8825           20 :             splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
    8826              :           }
    8827          112 :         if (decl2)
    8828            0 :           splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
    8829              :       }
    8830              : 
    8831        14183 :   if (ctx->region_type != ORT_UNTIED_TASK)
    8832              :     return false;
    8833           37 :   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
    8834           37 :   if (n == NULL)
    8835              :     {
    8836            6 :       error ("threadprivate variable %qE used in untied task",
    8837            6 :              DECL_NAME (decl));
    8838            6 :       inform (ctx->location, "enclosing task");
    8839            6 :       splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
    8840              :     }
    8841           37 :   if (decl2)
    8842            4 :     splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
    8843              :   return false;
    8844              : }
    8845              : 
    8846              : /* Return true if global var DECL is device resident.  */
    8847              : 
    8848              : static bool
    8849          642 : device_resident_p (tree decl)
    8850              : {
    8851          642 :   tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
    8852              : 
    8853          642 :   if (!attr)
    8854              :     return false;
    8855              : 
    8856            0 :   for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
    8857              :     {
    8858            0 :       tree c = TREE_VALUE (t);
    8859            0 :       if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
    8860              :         return true;
    8861              :     }
    8862              : 
    8863              :   return false;
    8864              : }
    8865              : 
    8866              : /* Return true if DECL has an ACC DECLARE attribute.  */
    8867              : 
    8868              : static bool
    8869         9101 : is_oacc_declared (tree decl)
    8870              : {
    8871         9101 :   tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
    8872         9101 :   tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
    8873         9101 :   return declared != NULL_TREE;
    8874              : }
    8875              : 
    8876              : /* Determine outer default flags for DECL mentioned in an OMP region
    8877              :    but not declared in an enclosing clause.
    8878              : 
    8879              :    ??? Some compiler-generated variables (like SAVE_EXPRs) could be
    8880              :    remapped firstprivate instead of shared.  To some extent this is
    8881              :    addressed in omp_firstprivatize_type_sizes, but not
    8882              :    effectively.  */
    8883              : 
    8884              : static unsigned
    8885        47882 : omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
    8886              :                     bool in_code, unsigned flags)
    8887              : {
    8888        47882 :   enum omp_clause_default_kind default_kind = ctx->default_kind;
    8889        47882 :   enum omp_clause_default_kind kind;
    8890              : 
    8891        47882 :   kind = lang_hooks.decls.omp_predetermined_sharing (decl);
    8892        47882 :   if (ctx->region_type & ORT_TASK)
    8893              :     {
    8894         3971 :       tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
    8895              : 
    8896              :       /* The event-handle specified by a detach clause should always be firstprivate,
    8897              :          regardless of the current default.  */
    8898         4183 :       if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
    8899              :         kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
    8900              :     }
    8901        47882 :   if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
    8902              :     default_kind = kind;
    8903        45068 :   else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
    8904              :     default_kind = OMP_CLAUSE_DEFAULT_SHARED;
    8905              :   /* For C/C++ default({,first}private), variables with static storage duration
    8906              :      declared in a namespace or global scope and referenced in construct
    8907              :      must be explicitly specified, i.e. acts as default(none).  */
    8908        45067 :   else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
    8909        45067 :             || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
    8910          368 :            && VAR_P (decl)
    8911          321 :            && is_global_var (decl)
    8912          184 :            && (DECL_FILE_SCOPE_P (decl)
    8913          104 :                || (DECL_CONTEXT (decl)
    8914          104 :                    && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
    8915        45195 :            && !lang_GNU_Fortran ())
    8916              :     default_kind = OMP_CLAUSE_DEFAULT_NONE;
    8917              : 
    8918        47753 :   switch (default_kind)
    8919              :     {
    8920          267 :     case OMP_CLAUSE_DEFAULT_NONE:
    8921          267 :       {
    8922          267 :         const char *rtype;
    8923              : 
    8924          267 :         if (ctx->region_type & ORT_PARALLEL)
    8925              :           rtype = "parallel";
    8926          108 :         else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
    8927              :           rtype = "taskloop";
    8928           72 :         else if (ctx->region_type & ORT_TASK)
    8929              :           rtype = "task";
    8930           36 :         else if (ctx->region_type & ORT_TEAMS)
    8931              :           rtype = "teams";
    8932              :         else
    8933            0 :           gcc_unreachable ();
    8934              : 
    8935          267 :         error ("%qE not specified in enclosing %qs",
    8936          267 :                DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
    8937          267 :         inform (ctx->location, "enclosing %qs", rtype);
    8938              :       }
    8939              :       /* FALLTHRU */
    8940        44249 :     case OMP_CLAUSE_DEFAULT_SHARED:
    8941        44249 :       flags |= GOVD_SHARED;
    8942        44249 :       break;
    8943          155 :     case OMP_CLAUSE_DEFAULT_PRIVATE:
    8944          155 :       flags |= GOVD_PRIVATE;
    8945          155 :       break;
    8946          277 :     case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
    8947          277 :       flags |= GOVD_FIRSTPRIVATE;
    8948          277 :       break;
    8949         3201 :     case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
    8950              :       /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED.  */
    8951         3201 :       gcc_assert ((ctx->region_type & ORT_TASK) != 0);
    8952         3201 :       if (struct gimplify_omp_ctx *octx = ctx->outer_context)
    8953              :         {
    8954         2164 :           omp_notice_variable (octx, decl, in_code);
    8955         2994 :           for (; octx; octx = octx->outer_context)
    8956              :             {
    8957         2938 :               splay_tree_node n2;
    8958              : 
    8959         2938 :               n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
    8960         2938 :               if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
    8961            5 :                   && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
    8962            5 :                 continue;
    8963         2933 :               if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
    8964              :                 {
    8965          898 :                   flags |= GOVD_FIRSTPRIVATE;
    8966          898 :                   goto found_outer;
    8967              :                 }
    8968         2035 :               if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
    8969              :                 {
    8970         1210 :                   flags |= GOVD_SHARED;
    8971         1210 :                   goto found_outer;
    8972              :                 }
    8973              :             }
    8974              :         }
    8975              : 
    8976         1093 :       if (TREE_CODE (decl) == PARM_DECL
    8977         1093 :           || (!is_global_var (decl)
    8978          288 :               && DECL_CONTEXT (decl) == current_function_decl))
    8979          713 :         flags |= GOVD_FIRSTPRIVATE;
    8980              :       else
    8981          380 :         flags |= GOVD_SHARED;
    8982        47882 :     found_outer:
    8983              :       break;
    8984              : 
    8985            0 :     default:
    8986            0 :       gcc_unreachable ();
    8987              :     }
    8988              : 
    8989        47882 :   return flags;
    8990              : }
    8991              : 
    8992              : /* Return string name for types of OpenACC constructs from ORT_* values.  */
    8993              : 
    8994              : static const char *
    8995          570 : oacc_region_type_name (enum omp_region_type region_type)
    8996              : {
    8997          570 :   switch (region_type)
    8998              :     {
    8999              :     case ORT_ACC_DATA:
    9000              :       return "data";
    9001          140 :     case ORT_ACC_PARALLEL:
    9002          140 :       return "parallel";
    9003          140 :     case ORT_ACC_KERNELS:
    9004          140 :       return "kernels";
    9005          140 :     case ORT_ACC_SERIAL:
    9006          140 :       return "serial";
    9007            0 :     default:
    9008            0 :       gcc_unreachable ();
    9009              :     }
    9010              : }
    9011              : 
    9012              : /* Determine outer default flags for DECL mentioned in an OACC region
    9013              :    but not declared in an enclosing clause.  */
    9014              : 
    9015              : static unsigned
    9016         8839 : oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
    9017              : {
    9018         8839 :   struct gimplify_omp_ctx *ctx_default = ctx;
    9019              :   /* If no 'default' clause appears on this compute construct...  */
    9020         8839 :   if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED)
    9021              :     {
    9022              :       /* ..., see if one appears on a lexically containing 'data'
    9023              :          construct.  */
    9024         9618 :       while ((ctx_default = ctx_default->outer_context))
    9025              :         {
    9026         1534 :           if (ctx_default->region_type == ORT_ACC_DATA
    9027         1534 :               && ctx_default->default_kind != OMP_CLAUSE_DEFAULT_SHARED)
    9028              :             break;
    9029              :         }
    9030              :       /* If not, reset.  */
    9031         8260 :       if (!ctx_default)
    9032         8663 :         ctx_default = ctx;
    9033              :     }
    9034              : 
    9035         8839 :   bool on_device = false;
    9036         8839 :   bool is_private = false;
    9037         8839 :   bool declared = is_oacc_declared (decl);
    9038         8839 :   tree type = TREE_TYPE (decl);
    9039              : 
    9040         8839 :   if (omp_privatize_by_reference (decl))
    9041          338 :     type = TREE_TYPE (type);
    9042              : 
    9043              :   /* For Fortran COMMON blocks, only used variables in those blocks are
    9044              :      transferred and remapped.  The block itself will have a private clause to
    9045              :      avoid transferring the data twice.
    9046              :      The hook evaluates to false by default.  For a variable in Fortran's COMMON
    9047              :      or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
    9048              :      the variables in such a COMMON/EQUIVALENCE block shall be privatized not
    9049              :      the whole block.  For C++ and Fortran, it can also be true under certain
    9050              :      other conditions, if DECL_HAS_VALUE_EXPR.  */
    9051         8839 :   if (RECORD_OR_UNION_TYPE_P (type))
    9052          983 :     is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
    9053              : 
    9054         8839 :   if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
    9055         8839 :       && is_global_var (decl)
    9056          642 :       && device_resident_p (decl)
    9057         8839 :       && !is_private)
    9058              :     {
    9059            0 :       on_device = true;
    9060            0 :       flags |= GOVD_MAP_TO_ONLY;
    9061              :     }
    9062              : 
    9063         8839 :   switch (ctx->region_type)
    9064              :     {
    9065         1460 :     case ORT_ACC_KERNELS:
    9066         1460 :       if (is_private)
    9067            0 :         flags |= GOVD_FIRSTPRIVATE;
    9068         1460 :       else if (AGGREGATE_TYPE_P (type))
    9069              :         {
    9070              :           /* Aggregates default to 'present_or_copy', or 'present'.  */
    9071          415 :           if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
    9072          397 :             flags |= GOVD_MAP;
    9073              :           else
    9074           18 :             flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
    9075              :         }
    9076              :       else
    9077              :         /* Scalars default to 'copy'.  */
    9078         1045 :         flags |= GOVD_MAP | GOVD_MAP_FORCE;
    9079              : 
    9080              :       break;
    9081              : 
    9082         7379 :     case ORT_ACC_PARALLEL:
    9083         7379 :     case ORT_ACC_SERIAL:
    9084         7379 :       if (is_private)
    9085            0 :         flags |= GOVD_FIRSTPRIVATE;
    9086         7379 :       else if (on_device || declared)
    9087           17 :         flags |= GOVD_MAP;
    9088         7362 :       else if (AGGREGATE_TYPE_P (type))
    9089              :         {
    9090              :           /* Aggregates default to 'present_or_copy', or 'present'.  */
    9091         3697 :           if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
    9092         3431 :             flags |= GOVD_MAP;
    9093              :           else
    9094          266 :             flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
    9095              :         }
    9096              :       else
    9097              :         /* Scalars default to 'firstprivate'.  */
    9098         3665 :         flags |= GOVD_FIRSTPRIVATE;
    9099              : 
    9100              :       break;
    9101              : 
    9102            0 :     default:
    9103            0 :       gcc_unreachable ();
    9104              :     }
    9105              : 
    9106         8839 :   if (DECL_ARTIFICIAL (decl))
    9107              :     ; /* We can get compiler-generated decls, and should not complain
    9108              :          about them.  */
    9109         8528 :   else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_NONE)
    9110              :     {
    9111          420 :       error ("%qE not specified in enclosing OpenACC %qs construct",
    9112          210 :              DECL_NAME (lang_hooks.decls.omp_report_decl (decl)),
    9113              :              oacc_region_type_name (ctx->region_type));
    9114          210 :       if (ctx_default != ctx)
    9115          150 :         inform (ctx->location, "enclosing OpenACC %qs construct and",
    9116              :                 oacc_region_type_name (ctx->region_type));
    9117          210 :       inform (ctx_default->location,
    9118              :               "enclosing OpenACC %qs construct with %qs clause",
    9119              :               oacc_region_type_name (ctx_default->region_type),
    9120              :               "default(none)");
    9121              :     }
    9122         8318 :   else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
    9123              :     ; /* Handled above.  */
    9124              :   else
    9125         7785 :     gcc_checking_assert (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
    9126              : 
    9127         8839 :   return flags;
    9128              : }
    9129              : 
    9130              : /* Record the fact that DECL was used within the OMP context CTX.
    9131              :    IN_CODE is true when real code uses DECL, and false when we should
    9132              :    merely emit default(none) errors.  Return true if DECL is going to
    9133              :    be remapped and thus DECL shouldn't be gimplified into its
    9134              :    DECL_VALUE_EXPR (if any).  */
    9135              : 
    9136              : static bool
    9137      3910584 : omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
    9138              : {
    9139      3910584 :   splay_tree_node n;
    9140      3910584 :   unsigned flags = in_code ? GOVD_SEEN : 0;
    9141      3910584 :   bool ret = false, shared;
    9142              : 
    9143      3910584 :   if (error_operand_p (decl))
    9144              :     return false;
    9145              : 
    9146      3910584 :   if (DECL_ARTIFICIAL (decl))
    9147              :     {
    9148      2233835 :       tree attr = lookup_attribute ("omp allocate var", DECL_ATTRIBUTES (decl));
    9149      2233835 :       if (attr)
    9150          543 :         decl = TREE_VALUE (TREE_VALUE (attr));
    9151              :     }
    9152              : 
    9153      3910584 :   if (ctx->region_type == ORT_NONE)
    9154          248 :     return lang_hooks.decls.omp_disregard_value_expr (decl, false);
    9155              : 
    9156      3910336 :   if (is_global_var (decl))
    9157              :     {
    9158              :       /* Threadprivate variables are predetermined.  */
    9159       501812 :       if (DECL_THREAD_LOCAL_P (decl))
    9160        13565 :         return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
    9161              : 
    9162       488247 :       if (DECL_HAS_VALUE_EXPR_P (decl))
    9163              :         {
    9164         4380 :           if (ctx->region_type & ORT_ACC)
    9165              :             /* For OpenACC, defer expansion of value to avoid transferring
    9166              :                privatized common block data instead of im-/explicitly
    9167              :                transferred variables which are in common blocks.  */
    9168              :             ;
    9169              :           else
    9170              :             {
    9171         2104 :               tree value = get_base_address (DECL_VALUE_EXPR (decl));
    9172              : 
    9173         2104 :               if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
    9174          618 :                 return omp_notice_threadprivate_variable (ctx, decl, value);
    9175              :             }
    9176              :         }
    9177              : 
    9178       487629 :       if (gimplify_omp_ctxp->outer_context == NULL
    9179       113735 :           && VAR_P (decl)
    9180       601364 :           && oacc_get_fn_attrib (current_function_decl))
    9181              :         {
    9182          765 :           location_t loc = DECL_SOURCE_LOCATION (decl);
    9183              : 
    9184          765 :           if (lookup_attribute ("omp declare target link",
    9185          765 :                                 DECL_ATTRIBUTES (decl)))
    9186              :             {
    9187           48 :               error_at (loc,
    9188              :                         "%qE with %<link%> clause used in %<routine%> function",
    9189           24 :                         DECL_NAME (decl));
    9190           24 :               return false;
    9191              :             }
    9192          741 :           else if (!lookup_attribute ("omp declare target",
    9193          741 :                                       DECL_ATTRIBUTES (decl)))
    9194              :             {
    9195          132 :               error_at (loc,
    9196              :                         "%qE requires a %<declare%> directive for use "
    9197           66 :                         "in a %<routine%> function", DECL_NAME (decl));
    9198           66 :               return false;
    9199              :             }
    9200              :         }
    9201              :     }
    9202              : 
    9203      3896063 :   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
    9204      3896063 :   if ((ctx->region_type & ORT_TARGET) != 0)
    9205              :     {
    9206       850824 :       if (n == NULL)
    9207              :         {
    9208        45055 :           unsigned nflags = flags;
    9209        45055 :           if ((ctx->region_type & ORT_ACC) == 0)
    9210              :             {
    9211        34101 :               bool is_declare_target = false;
    9212        34101 :               if (is_global_var (decl)
    9213        34101 :                   && varpool_node::get_create (decl)->offloadable)
    9214              :                 {
    9215         7002 :                   struct gimplify_omp_ctx *octx;
    9216         7002 :                   for (octx = ctx->outer_context;
    9217         7010 :                        octx; octx = octx->outer_context)
    9218              :                     {
    9219            9 :                       n = splay_tree_lookup (octx->variables,
    9220              :                                              (splay_tree_key)decl);
    9221            9 :                       if (n
    9222            9 :                           && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
    9223            9 :                           && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
    9224              :                         break;
    9225              :                     }
    9226         7002 :                   is_declare_target = octx == NULL;
    9227              :                 }
    9228         7002 :               if (!is_declare_target)
    9229              :                 {
    9230        27100 :                   int gdmk;
    9231        27100 :                   enum omp_clause_defaultmap_kind kind;
    9232        27100 :                   if (lang_hooks.decls.omp_allocatable_p (decl))
    9233              :                     gdmk = GDMK_ALLOCATABLE;
    9234        26753 :                   else if (lang_hooks.decls.omp_scalar_target_p (decl))
    9235              :                     gdmk = GDMK_SCALAR_TARGET;
    9236        26678 :                   else if (lang_hooks.decls.omp_scalar_p (decl, false))
    9237              :                     gdmk = GDMK_SCALAR;
    9238        11164 :                   else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
    9239        11164 :                            || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
    9240         3102 :                                && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
    9241              :                                    == POINTER_TYPE)))
    9242              :                     gdmk = GDMK_POINTER;
    9243              :                   else
    9244              :                     gdmk = GDMK_AGGREGATE;
    9245        27100 :                   kind = lang_hooks.decls.omp_predetermined_mapping (decl);
    9246        27100 :                   if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
    9247              :                     {
    9248         1096 :                       if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
    9249          101 :                         nflags |= GOVD_FIRSTPRIVATE;
    9250          995 :                       else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
    9251          995 :                         nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
    9252              :                       else
    9253            0 :                         gcc_unreachable ();
    9254              :                     }
    9255        26004 :                   else if (ctx->defaultmap[gdmk] == 0)
    9256              :                     {
    9257           77 :                       tree d = lang_hooks.decls.omp_report_decl (decl);
    9258           77 :                       error ("%qE not specified in enclosing %<target%>",
    9259           77 :                              DECL_NAME (d));
    9260           77 :                       inform (ctx->location, "enclosing %<target%>");
    9261              :                     }
    9262        25927 :                   else if (ctx->defaultmap[gdmk]
    9263        25927 :                            & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
    9264         9125 :                     nflags |= ctx->defaultmap[gdmk];
    9265        16802 :                   else if (ctx->defaultmap[gdmk] & GOVD_MAP_FORCE_PRESENT)
    9266              :                     {
    9267           42 :                       gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
    9268           42 :                       nflags |= ctx->defaultmap[gdmk] | GOVD_MAP_ALLOC_ONLY;
    9269              :                     }
    9270              :                   else
    9271              :                     {
    9272        16760 :                       gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
    9273        16760 :                       nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
    9274              :                     }
    9275              :                 }
    9276              :             }
    9277              : 
    9278        45055 :           struct gimplify_omp_ctx *octx = ctx->outer_context;
    9279        45055 :           if ((ctx->region_type & ORT_ACC) && octx)
    9280              :             {
    9281              :               /* Look in outer OpenACC contexts, to see if there's a
    9282              :                  data attribute for this variable.  */
    9283         3535 :               omp_notice_variable (octx, decl, in_code);
    9284              : 
    9285         5307 :               for (; octx; octx = octx->outer_context)
    9286              :                 {
    9287         3883 :                   if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
    9288              :                     break;
    9289         3883 :                   splay_tree_node n2
    9290         3883 :                     = splay_tree_lookup (octx->variables,
    9291              :                                          (splay_tree_key) decl);
    9292         3883 :                   if (n2)
    9293              :                     {
    9294         2111 :                       if (octx->region_type == ORT_ACC_HOST_DATA)
    9295            4 :                         error ("variable %qE declared in enclosing "
    9296            4 :                                "%<host_data%> region", DECL_NAME (decl));
    9297         2111 :                       nflags |= GOVD_MAP;
    9298         2111 :                       if (octx->region_type == ORT_ACC_DATA
    9299         2107 :                           && (n2->value & GOVD_MAP_0LEN_ARRAY))
    9300          288 :                         nflags |= GOVD_MAP_0LEN_ARRAY;
    9301         2111 :                       goto found_outer;
    9302              :                     }
    9303              :                 }
    9304              :             }
    9305              : 
    9306        42944 :           if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
    9307              :                           | GOVD_MAP_ALLOC_ONLY)) == flags)
    9308              :             {
    9309        32681 :               tree type = TREE_TYPE (decl);
    9310        32681 :               location_t loc = DECL_SOURCE_LOCATION (decl);
    9311              : 
    9312        32681 :               if (gimplify_omp_ctxp->target_firstprivatize_array_bases
    9313        32681 :                   && omp_privatize_by_reference (decl))
    9314           28 :                 type = TREE_TYPE (type);
    9315              : 
    9316        32681 :               if (!verify_type_context (loc, TCTX_OMP_MAP_IMP_REF, type))
    9317              :                 /* Check if TYPE can appear in a target region.
    9318              :                    verify_type_context has already issued an error if it
    9319              :                    can't.  */
    9320            0 :                 nflags |= GOVD_MAP | GOVD_EXPLICIT;
    9321        32681 :               else if (!omp_mappable_type (type))
    9322              :                 {
    9323            8 :                   error ("%qD referenced in target region does not have "
    9324              :                          "a mappable type", decl);
    9325            8 :                   nflags |= GOVD_MAP | GOVD_EXPLICIT;
    9326              :                 }
    9327              :               else
    9328              :                 {
    9329        32673 :                   if ((ctx->region_type & ORT_ACC) != 0)
    9330         8839 :                     nflags = oacc_default_clause (ctx, decl, flags);
    9331              :                   else
    9332        23834 :                     nflags |= GOVD_MAP;
    9333              :                 }
    9334              :             }
    9335        10263 :         found_outer:
    9336        45055 :           omp_add_variable (ctx, decl, nflags);
    9337        45055 :           if (ctx->region_type & ORT_ACC)
    9338              :             /* For OpenACC, as remarked above, defer expansion.  */
    9339              :             shared = false;
    9340              :           else
    9341        34101 :             shared = (nflags & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0;
    9342        45055 :           ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
    9343              :         }
    9344              :       else
    9345              :         {
    9346       805769 :           if (ctx->region_type & ORT_ACC)
    9347              :             /* For OpenACC, as remarked above, defer expansion.  */
    9348              :             shared = false;
    9349              :           else
    9350       509344 :             shared = ((n->value | flags)
    9351       509344 :                       & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0;
    9352       805769 :           ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
    9353              :           /* If nothing changed, there's nothing left to do.  */
    9354       805769 :           if ((n->value & flags) == flags)
    9355              :             return ret;
    9356        16549 :           flags |= n->value;
    9357        16549 :           n->value = flags;
    9358              :         }
    9359        61604 :       goto do_outer;
    9360              :     }
    9361              : 
    9362      3045239 :   if (n == NULL)
    9363              :     {
    9364      1181884 :       if (ctx->region_type == ORT_WORKSHARE
    9365              :           || ctx->region_type == ORT_TASKGROUP
    9366       560831 :           || ctx->region_type == ORT_SIMD
    9367       288788 :           || ctx->region_type == ORT_ACC
    9368        92535 :           || (ctx->region_type & ORT_TARGET_DATA) != 0)
    9369      1134002 :         goto do_outer;
    9370              : 
    9371        47882 :       flags = omp_default_clause (ctx, decl, in_code, flags);
    9372              : 
    9373        47882 :       if ((flags & GOVD_PRIVATE)
    9374        47882 :           && lang_hooks.decls.omp_private_outer_ref (decl))
    9375            6 :         flags |= GOVD_PRIVATE_OUTER_REF;
    9376              : 
    9377        47882 :       omp_add_variable (ctx, decl, flags);
    9378              : 
    9379        47882 :       shared = (flags & GOVD_SHARED) != 0;
    9380        47882 :       ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
    9381        47882 :       goto do_outer;
    9382              :     }
    9383              : 
    9384              :   /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
    9385              :      lb, b or incr expressions, those shouldn't be turned into simd arrays.  */
    9386      1863355 :   if (ctx->region_type == ORT_SIMD
    9387       151155 :       && ctx->in_for_exprs
    9388           70 :       && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
    9389              :           == GOVD_PRIVATE))
    9390      1863355 :     flags &= ~GOVD_SEEN;
    9391              : 
    9392      1863355 :   if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
    9393        31870 :       && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
    9394      1895186 :       && DECL_SIZE (decl))
    9395              :     {
    9396        31830 :       tree size;
    9397        31830 :       if (!poly_int_tree_p (DECL_SIZE (decl)))
    9398              :         {
    9399          148 :           splay_tree_node n2;
    9400          148 :           tree t = DECL_VALUE_EXPR (decl);
    9401          148 :           gcc_assert (INDIRECT_REF_P (t));
    9402          148 :           t = TREE_OPERAND (t, 0);
    9403          148 :           gcc_assert (DECL_P (t));
    9404          148 :           n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
    9405          148 :           n2->value |= GOVD_SEEN;
    9406              :         }
    9407        31682 :       else if (omp_privatize_by_reference (decl)
    9408         4193 :                && (size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
    9409        35838 :                && !poly_int_tree_p (size))
    9410              :         {
    9411         1337 :           splay_tree_node n2;
    9412         1337 :           gcc_assert (DECL_P (size));
    9413         1337 :           n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) size);
    9414         1337 :           if (n2)
    9415          629 :             omp_notice_variable (ctx, size, true);
    9416              :         }
    9417              :     }
    9418              : 
    9419      1863355 :   if (ctx->region_type & ORT_ACC)
    9420              :     /* For OpenACC, as remarked above, defer expansion.  */
    9421              :     shared = false;
    9422              :   else
    9423      1681420 :     shared = ((flags | n->value) & GOVD_SHARED) != 0;
    9424      1863355 :   ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
    9425              : 
    9426              :   /* If nothing changed, there's nothing left to do.  */
    9427      1863355 :   if ((n->value & flags) == flags)
    9428              :     return ret;
    9429        31831 :   flags |= n->value;
    9430        31831 :   n->value = flags;
    9431              : 
    9432      1275319 :  do_outer:
    9433              :   /* If the variable is private in the current context, then we don't
    9434              :      need to propagate anything to an outer context.  */
    9435      1275319 :   if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
    9436              :     return ret;
    9437      1264933 :   if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
    9438              :       == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
    9439              :     return ret;
    9440      1264873 :   if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
    9441              :                 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
    9442              :       == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
    9443              :     return ret;
    9444      1264873 :   if (ctx->outer_context
    9445      1264873 :       && omp_notice_variable (ctx->outer_context, decl, in_code))
    9446              :     return true;
    9447              :   return ret;
    9448              : }
    9449              : 
    9450              : /* Verify that DECL is private within CTX.  If there's specific information
    9451              :    to the contrary in the innermost scope, generate an error.  */
    9452              : 
    9453              : static bool
    9454        50137 : omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
    9455              : {
    9456        95834 :   splay_tree_node n;
    9457              : 
    9458        95834 :   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
    9459        95834 :   if (n != NULL)
    9460              :     {
    9461        17960 :       if (n->value & GOVD_SHARED)
    9462              :         {
    9463          407 :           if (ctx == gimplify_omp_ctxp)
    9464              :             {
    9465            0 :               if (simd)
    9466            0 :                 error ("iteration variable %qE is predetermined linear",
    9467            0 :                        DECL_NAME (decl));
    9468              :               else
    9469            0 :                 error ("iteration variable %qE should be private",
    9470            0 :                        DECL_NAME (decl));
    9471            0 :               n->value = GOVD_PRIVATE;
    9472            0 :               return true;
    9473              :             }
    9474              :           else
    9475              :             return false;
    9476              :         }
    9477        17553 :       else if ((n->value & GOVD_EXPLICIT) != 0
    9478         9711 :                && (ctx == gimplify_omp_ctxp
    9479          340 :                    || (ctx->region_type == ORT_COMBINED_PARALLEL
    9480          220 :                        && gimplify_omp_ctxp->outer_context == ctx)))
    9481              :         {
    9482         9591 :           if ((n->value & GOVD_FIRSTPRIVATE) != 0)
    9483            4 :             error ("iteration variable %qE should not be firstprivate",
    9484            4 :                    DECL_NAME (decl));
    9485         9587 :           else if ((n->value & GOVD_REDUCTION) != 0)
    9486            8 :             error ("iteration variable %qE should not be reduction",
    9487            8 :                    DECL_NAME (decl));
    9488         9579 :           else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
    9489           58 :             error ("iteration variable %qE should not be linear",
    9490           58 :                    DECL_NAME (decl));
    9491              :         }
    9492        17553 :       return (ctx == gimplify_omp_ctxp
    9493        17553 :               || (ctx->region_type == ORT_COMBINED_PARALLEL
    9494        19435 :                   && gimplify_omp_ctxp->outer_context == ctx));
    9495              :     }
    9496              : 
    9497        77874 :   if (ctx->region_type != ORT_WORKSHARE
    9498              :       && ctx->region_type != ORT_TASKGROUP
    9499        49422 :       && ctx->region_type != ORT_SIMD
    9500        36157 :       && ctx->region_type != ORT_ACC)
    9501              :     return false;
    9502        53890 :   else if (ctx->outer_context)
    9503              :     return omp_is_private (ctx->outer_context, decl, simd);
    9504              :   return false;
    9505              : }
    9506              : 
    9507              : /* Return true if DECL is private within a parallel region
    9508              :    that binds to the current construct's context or in parallel
    9509              :    region's REDUCTION clause.  */
    9510              : 
    9511              : static bool
    9512        11547 : omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
    9513              : {
    9514        11619 :   splay_tree_node n;
    9515              : 
    9516        11619 :   do
    9517              :     {
    9518        11619 :       ctx = ctx->outer_context;
    9519        11619 :       if (ctx == NULL)
    9520              :         {
    9521         2764 :           if (is_global_var (decl))
    9522              :             return false;
    9523              : 
    9524              :           /* References might be private, but might be shared too,
    9525              :              when checking for copyprivate, assume they might be
    9526              :              private, otherwise assume they might be shared.  */
    9527         1290 :           if (copyprivate)
    9528              :             return true;
    9529              : 
    9530         1244 :           if (omp_privatize_by_reference (decl))
    9531              :             return false;
    9532              : 
    9533              :           /* Treat C++ privatized non-static data members outside
    9534              :              of the privatization the same.  */
    9535         1198 :           if (omp_member_access_dummy_var (decl))
    9536              :             return false;
    9537              : 
    9538              :           return true;
    9539              :         }
    9540              : 
    9541         8855 :       n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
    9542              : 
    9543         8855 :       if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
    9544         1291 :           && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
    9545              :         {
    9546          242 :           if ((ctx->region_type & ORT_TARGET_DATA) != 0
    9547          238 :               || n == NULL
    9548          230 :               || (n->value & GOVD_MAP) == 0)
    9549           12 :             continue;
    9550              :           return false;
    9551              :         }
    9552              : 
    9553         7564 :       if (n != NULL)
    9554              :         {
    9555         5360 :           if ((n->value & GOVD_LOCAL) != 0
    9556         5360 :               && omp_member_access_dummy_var (decl))
    9557              :             return false;
    9558         5321 :           return (n->value & GOVD_SHARED) == 0;
    9559              :         }
    9560              : 
    9561         3253 :       if (ctx->region_type == ORT_WORKSHARE
    9562              :           || ctx->region_type == ORT_TASKGROUP
    9563         3197 :           || ctx->region_type == ORT_SIMD
    9564         3193 :           || ctx->region_type == ORT_ACC)
    9565           60 :         continue;
    9566              : 
    9567              :       break;
    9568              :     }
    9569              :   while (1);
    9570              :   return false;
    9571              : }
    9572              : 
    9573              : /* Callback for walk_tree to find a DECL_EXPR for the given DECL.  */
    9574              : 
    9575              : static tree
    9576         3148 : find_decl_expr (tree *tp, int *walk_subtrees, void *data)
    9577              : {
    9578         3148 :   tree t = *tp;
    9579              : 
    9580              :   /* If this node has been visited, unmark it and keep looking.  */
    9581         3148 :   if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
    9582              :     return t;
    9583              : 
    9584         2724 :   if (IS_TYPE_OR_DECL_P (t))
    9585          452 :     *walk_subtrees = 0;
    9586              :   return NULL_TREE;
    9587              : }
    9588              : 
    9589              : 
    9590              : /* Gimplify the affinity clause but effectively ignore it.
    9591              :    Generate:
    9592              :      var = begin;
    9593              :      if ((step > 1) ? var <= end : var > end)
    9594              :        locatator_var_expr;  */
    9595              : 
    9596              : static void
    9597          374 : gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
    9598              : {
    9599          374 :   tree last_iter = NULL_TREE;
    9600          374 :   tree last_bind = NULL_TREE;
    9601          374 :   tree label = NULL_TREE;
    9602          374 :   tree *last_body = NULL;
    9603         1011 :   for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
    9604          637 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
    9605              :       {
    9606          637 :         tree t = OMP_CLAUSE_DECL (c);
    9607          637 :         if (OMP_ITERATOR_DECL_P (t))
    9608              :           {
    9609          389 :             if (TREE_VALUE (t) == null_pointer_node)
    9610          201 :               continue;
    9611          188 :             if (TREE_PURPOSE (t) != last_iter)
    9612              :               {
    9613          127 :                 if (last_bind)
    9614              :                   {
    9615            9 :                     append_to_statement_list (label, last_body);
    9616            9 :                     gimplify_and_add (last_bind, pre_p);
    9617            9 :                     last_bind = NULL_TREE;
    9618              :                   }
    9619          274 :                 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
    9620              :                   {
    9621          147 :                     if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
    9622              :                                        is_gimple_val, fb_rvalue) == GS_ERROR
    9623          147 :                         || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
    9624              :                                           is_gimple_val, fb_rvalue) == GS_ERROR
    9625          147 :                         || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
    9626              :                                           is_gimple_val, fb_rvalue) == GS_ERROR
    9627          294 :                         || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
    9628              :                                            is_gimple_val, fb_rvalue)
    9629              :                             == GS_ERROR))
    9630            0 :                       return;
    9631              :                   }
    9632          127 :             last_iter = TREE_PURPOSE (t);
    9633          127 :             tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
    9634          127 :             last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
    9635              :                                 NULL, block);
    9636          127 :             last_body = &BIND_EXPR_BODY (last_bind);
    9637          127 :             tree cond = NULL_TREE;
    9638          127 :             location_t loc = OMP_CLAUSE_LOCATION (c);
    9639          274 :             for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
    9640              :               {
    9641          147 :                 tree var = TREE_VEC_ELT (it, 0);
    9642          147 :                 tree begin = TREE_VEC_ELT (it, 1);
    9643          147 :                 tree end = TREE_VEC_ELT (it, 2);
    9644          147 :                 tree step = TREE_VEC_ELT (it, 3);
    9645          147 :                 loc = DECL_SOURCE_LOCATION (var);
    9646          147 :                 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
    9647              :                                        var, begin);
    9648          147 :                 append_to_statement_list_force (tem, last_body);
    9649              : 
    9650          147 :                 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
    9651          147 :                                step, build_zero_cst (TREE_TYPE (step)));
    9652          147 :                 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
    9653              :                                               var, end);
    9654          147 :                 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
    9655              :                                               var, end);
    9656          147 :                 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
    9657              :                                          cond1, cond2, cond3);
    9658          147 :                 if (cond)
    9659           20 :                   cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
    9660              :                                           boolean_type_node, cond, cond1);
    9661              :                 else
    9662              :                   cond = cond1;
    9663              :               }
    9664          127 :             tree cont_label = create_artificial_label (loc);
    9665          127 :             label = build1 (LABEL_EXPR, void_type_node, cont_label);
    9666          127 :             tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
    9667              :                                         void_node,
    9668              :                                         build_and_jump (&cont_label));
    9669          127 :             append_to_statement_list_force (tem, last_body);
    9670              :               }
    9671          188 :             if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
    9672              :               {
    9673            0 :                 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
    9674              :                                           last_body);
    9675            0 :                 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
    9676              :               }
    9677          188 :             if (error_operand_p (TREE_VALUE (t)))
    9678              :               return;
    9679          188 :             append_to_statement_list_force (TREE_VALUE (t), last_body);
    9680          188 :             TREE_VALUE (t) = null_pointer_node;
    9681              :           }
    9682              :         else
    9683              :           {
    9684          248 :             if (last_bind)
    9685              :               {
    9686            9 :                 append_to_statement_list (label, last_body);
    9687            9 :                 gimplify_and_add (last_bind, pre_p);
    9688            9 :                 last_bind = NULL_TREE;
    9689              :               }
    9690          248 :             if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
    9691              :               {
    9692            0 :                 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
    9693              :                                NULL, is_gimple_val, fb_rvalue);
    9694            0 :                 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
    9695              :               }
    9696          248 :             if (error_operand_p (OMP_CLAUSE_DECL (c)))
    9697              :               return;
    9698          248 :             if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
    9699              :                                is_gimple_lvalue, fb_lvalue) == GS_ERROR)
    9700              :               return;
    9701          248 :             gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
    9702              :           }
    9703              :       }
    9704          374 :   if (last_bind)
    9705              :     {
    9706          109 :       append_to_statement_list (label, last_body);
    9707          109 :       gimplify_and_add (last_bind, pre_p);
    9708              :     }
    9709              :   return;
    9710              : }
    9711              : 
    9712              : /* Returns a tree expression containing the total iteration count of the
    9713              :    OpenMP iterator IT.  */
    9714              : 
    9715              : static tree
    9716          379 : compute_omp_iterator_count (tree it, gimple_seq *pre_p)
    9717              : {
    9718          379 :   tree tcnt = size_one_node;
    9719          837 :   for (; it; it = TREE_CHAIN (it))
    9720              :     {
    9721          458 :       if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
    9722              :                          is_gimple_val, fb_rvalue) == GS_ERROR
    9723          458 :           || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
    9724              :                             is_gimple_val, fb_rvalue) == GS_ERROR
    9725          458 :           || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
    9726              :                             is_gimple_val, fb_rvalue) == GS_ERROR
    9727          916 :           || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
    9728              :                              is_gimple_val, fb_rvalue) == GS_ERROR))
    9729            0 :         return NULL_TREE;
    9730          458 :       tree var = TREE_VEC_ELT (it, 0);
    9731          458 :       tree begin = TREE_VEC_ELT (it, 1);
    9732          458 :       tree end = TREE_VEC_ELT (it, 2);
    9733          458 :       tree step = TREE_VEC_ELT (it, 3);
    9734          458 :       tree orig_step = TREE_VEC_ELT (it, 4);
    9735          458 :       tree type = TREE_TYPE (var);
    9736          458 :       tree stype = TREE_TYPE (step);
    9737          458 :       location_t loc = DECL_SOURCE_LOCATION (var);
    9738          458 :       tree endmbegin;
    9739              :       /* Compute count for this iterator as
    9740              :          orig_step > 0
    9741              :          ? (begin < end ? (end - begin + (step - 1)) / step : 0)
    9742              :          : (begin > end ? (end - begin + (step + 1)) / step : 0)
    9743              :          and compute product of those for the entire clause.  */
    9744          458 :       if (POINTER_TYPE_P (type))
    9745           42 :         endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR, stype, end, begin);
    9746              :       else
    9747          416 :         endmbegin = fold_build2_loc (loc, MINUS_EXPR, type, end, begin);
    9748              :       /* Account for iteration stopping on the end value in Fortran rather
    9749              :          than before it.  */
    9750          458 :       tree stepm1 = step;
    9751          458 :       tree stepp1 = step;
    9752          458 :       if (!lang_GNU_Fortran ())
    9753              :         {
    9754          360 :           stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype, step,
    9755              :                                     build_int_cst (stype, 1));
    9756          360 :           stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
    9757              :                                     build_int_cst (stype, 1));
    9758              :         }
    9759          458 :       tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
    9760              :                                   unshare_expr (endmbegin), stepm1);
    9761          458 :       pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype, pos, step);
    9762          458 :       tree neg = fold_build2_loc (loc, PLUS_EXPR, stype, endmbegin, stepp1);
    9763          458 :       if (TYPE_UNSIGNED (stype))
    9764              :         {
    9765           31 :           neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
    9766           31 :           step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
    9767              :         }
    9768          458 :       neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype, neg, step);
    9769          458 :       step = NULL_TREE;
    9770          458 :       tree_code cmp_op = lang_GNU_Fortran () ? LE_EXPR : LT_EXPR;
    9771          458 :       tree cond = fold_build2_loc (loc, cmp_op, boolean_type_node, begin, end);
    9772          458 :       pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
    9773              :                              build_int_cst (stype, 0));
    9774          458 :       cond = fold_build2_loc (loc, cmp_op, boolean_type_node, end, begin);
    9775          458 :       neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
    9776              :                              build_int_cst (stype, 0));
    9777          458 :       tree osteptype = TREE_TYPE (orig_step);
    9778          458 :       cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, orig_step,
    9779              :                               build_int_cst (osteptype, 0));
    9780          458 :       tree cnt = fold_build3_loc (loc, COND_EXPR, stype, cond, pos, neg);
    9781          458 :       cnt = fold_convert_loc (loc, sizetype, cnt);
    9782          458 :       if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
    9783              :                          fb_rvalue) == GS_ERROR)
    9784              :         return NULL_TREE;
    9785          458 :       tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
    9786              :     }
    9787          379 :   if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
    9788              :     return NULL_TREE;
    9789              : 
    9790          379 :   return tcnt;
    9791              : }
    9792              : 
    9793              : /* Build loops iterating over the space defined by the OpenMP iterator IT.
    9794              :    Returns a pointer to the BIND_EXPR_BODY in the innermost loop body.
    9795              :    LAST_BIND is set to point to the BIND_EXPR containing the whole loop.  */
    9796              : 
    9797              : static tree *
    9798          379 : build_omp_iterator_loop (tree it, gimple_seq *pre_p, tree *last_bind)
    9799              : {
    9800          379 :   if (*last_bind)
    9801           31 :     gimplify_and_add (*last_bind, pre_p);
    9802          379 :   tree block = TREE_VEC_ELT (it, 5);
    9803          464 :   tree block_stmts = lang_GNU_Fortran () ? BLOCK_SUBBLOCKS (block) : NULL_TREE;
    9804          379 :   *last_bind = build3 (BIND_EXPR, void_type_node,
    9805          379 :                        BLOCK_VARS (block), NULL, block);
    9806          379 :   TREE_SIDE_EFFECTS (*last_bind) = 1;
    9807          379 :   tree *p = &BIND_EXPR_BODY (*last_bind);
    9808          837 :   for (; it; it = TREE_CHAIN (it))
    9809              :     {
    9810          458 :       tree var = TREE_VEC_ELT (it, 0);
    9811          458 :       tree begin = TREE_VEC_ELT (it, 1);
    9812          458 :       tree end = TREE_VEC_ELT (it, 2);
    9813          458 :       tree step = TREE_VEC_ELT (it, 3);
    9814          458 :       tree orig_step = TREE_VEC_ELT (it, 4);
    9815          458 :       block = TREE_VEC_ELT (it, 5);
    9816          458 :       tree type = TREE_TYPE (var);
    9817          458 :       location_t loc = DECL_SOURCE_LOCATION (var);
    9818              :       /* Emit:
    9819              :          var = begin;
    9820              :          goto cond_label;
    9821              :          beg_label:
    9822              :          ...
    9823              :          var = var + step;
    9824              :          cond_label:
    9825              :          if (orig_step > 0) {
    9826              :            if (var < end) goto beg_label;  // <= for Fortran
    9827              :          } else {
    9828              :            if (var > end) goto beg_label;  // >= for Fortran
    9829              :          }
    9830              :          for each iterator, with inner iterators added to
    9831              :          the ... above.  */
    9832          458 :       tree beg_label = create_artificial_label (loc);
    9833          458 :       tree cond_label = NULL_TREE;
    9834          458 :       tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node, var, begin);
    9835          458 :       append_to_statement_list_force (tem, p);
    9836          458 :       tem = build_and_jump (&cond_label);
    9837          458 :       append_to_statement_list_force (tem, p);
    9838          458 :       tem = build1 (LABEL_EXPR, void_type_node, beg_label);
    9839          458 :       append_to_statement_list (tem, p);
    9840          458 :       tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
    9841              :                           NULL_TREE, NULL_TREE);
    9842          458 :       TREE_SIDE_EFFECTS (bind) = 1;
    9843          458 :       SET_EXPR_LOCATION (bind, loc);
    9844          458 :       append_to_statement_list_force (bind, p);
    9845          458 :       if (POINTER_TYPE_P (type))
    9846           42 :         tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
    9847              :                           var, fold_convert_loc (loc, sizetype, step));
    9848              :       else
    9849          416 :         tem = build2_loc (loc, PLUS_EXPR, type, var, step);
    9850          458 :       tem = build2_loc (loc, MODIFY_EXPR, void_type_node, var, tem);
    9851          458 :       append_to_statement_list_force (tem, p);
    9852          458 :       tem = build1 (LABEL_EXPR, void_type_node, cond_label);
    9853          458 :       append_to_statement_list (tem, p);
    9854          818 :       tree cond = fold_build2_loc (loc, lang_GNU_Fortran () ? LE_EXPR : LT_EXPR,
    9855              :                                    boolean_type_node, var, end);
    9856          458 :       tree pos = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
    9857              :                                   build_and_jump (&beg_label), void_node);
    9858          818 :       cond = fold_build2_loc (loc, lang_GNU_Fortran () ? GE_EXPR : GT_EXPR,
    9859              :                               boolean_type_node, var, end);
    9860          458 :       tree neg = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
    9861              :                                   build_and_jump (&beg_label), void_node);
    9862          458 :       tree osteptype = TREE_TYPE (orig_step);
    9863          458 :       cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, orig_step,
    9864              :                               build_int_cst (osteptype, 0));
    9865          458 :       tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond, pos, neg);
    9866          458 :       append_to_statement_list_force (tem, p);
    9867          458 :       p = &BIND_EXPR_BODY (bind);
    9868              :       /* The Fortran front-end stashes statements into the BLOCK_SUBBLOCKS
    9869              :          of the last element of the first iterator.  These should go into the
    9870              :          body of the innermost loop.  */
    9871          458 :       if (!TREE_CHAIN (it))
    9872          379 :         append_to_statement_list_force (block_stmts, p);
    9873              :     }
    9874              : 
    9875          379 :   return p;
    9876              : }
    9877              : 
    9878              : 
    9879              : /* Callback for walk_tree to find a VAR_DECL (stored in DATA) in the
    9880              :    tree TP.  */
    9881              : 
    9882              : static tree
    9883         3813 : find_var_decl (tree *tp, int *, void *data)
    9884              : {
    9885         3813 :   if (*tp == (tree) data)
    9886          357 :     return *tp;
    9887              : 
    9888              :   return NULL_TREE;
    9889              : }
    9890              : 
    9891              : /* Returns an element-by-element copy of OMP iterator tree IT.  */
    9892              : 
    9893              : static tree
    9894          337 : copy_omp_iterator (tree it, int elem_count = -1)
    9895              : {
    9896          337 :   if (elem_count < 0)
    9897           74 :     elem_count = TREE_VEC_LENGTH (it);
    9898          337 :   tree new_it = make_tree_vec (elem_count);
    9899         2359 :   for (int i = 0; i < TREE_VEC_LENGTH (it); i++)
    9900         2022 :     TREE_VEC_ELT (new_it, i) = TREE_VEC_ELT (it, i);
    9901              : 
    9902          337 :   return new_it;
    9903              : }
    9904              : 
    9905              : /* Helper function for walk_tree in remap_omp_iterator_var.  */
    9906              : 
    9907              : static tree
    9908         1063 : remap_omp_iterator_var_1 (tree *tp, int *, void *data)
    9909              : {
    9910         1063 :   tree old_var = ((tree *) data)[0];
    9911         1063 :   tree new_var = ((tree *) data)[1];
    9912              : 
    9913         1063 :   if (*tp == old_var)
    9914          106 :     *tp = new_var;
    9915         1063 :   return NULL_TREE;
    9916              : }
    9917              : 
    9918              : /* Replace instances of OLD_VAR in TP with NEW_VAR.  */
    9919              : 
    9920              : static void
    9921          212 : remap_omp_iterator_var (tree *tp, tree old_var, tree new_var)
    9922              : {
    9923          212 :   tree vars[2] = { old_var, new_var };
    9924          212 :   walk_tree (tp, remap_omp_iterator_var_1, vars, NULL);
    9925          212 : }
    9926              : 
    9927              : /* Scan through all clauses using OpenMP iterators in LIST_P.  If any
    9928              :    clauses have iterators with variables that are not used by the clause
    9929              :    decl or size, issue a warning and replace the iterator with a copy with
    9930              :    the unused variables removed.  */
    9931              : 
    9932              : static void
    9933        27661 : remove_unused_omp_iterator_vars (tree *list_p)
    9934              : {
    9935        27661 :   auto_vec< vec<tree> > iter_vars;
    9936        27661 :   auto_vec<tree> new_iterators;
    9937              : 
    9938        80586 :   for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
    9939              :     {
    9940        52925 :       if (!OMP_CLAUSE_HAS_ITERATORS (c))
    9941        52861 :         continue;
    9942          276 :       auto_vec<tree> vars;
    9943          276 :       bool need_new_iterators = false;
    9944          710 :       for (tree it = OMP_CLAUSE_ITERATORS (c); it; it = TREE_CHAIN (it))
    9945              :         {
    9946          434 :           tree var = TREE_VEC_ELT (it, 0);
    9947          434 :           tree t = walk_tree (&OMP_CLAUSE_DECL (c), find_var_decl, var, NULL);
    9948          434 :           if (t == NULL_TREE)
    9949          143 :             t = walk_tree (&OMP_CLAUSE_SIZE (c), find_var_decl, var, NULL);
    9950          143 :           if (t == NULL_TREE)
    9951              :             need_new_iterators = true;
    9952              :           else
    9953          357 :             vars.safe_push (var);
    9954              :         }
    9955          276 :       if (!need_new_iterators)
    9956          199 :         continue;
    9957           77 :       if (vars.is_empty ())
    9958              :         {
    9959              :           /* No iteration variables are used in the clause - remove the
    9960              :              iterator from the clause.  */
    9961           13 :           OMP_CLAUSE_ITERATORS (c) = NULL_TREE;
    9962           13 :           continue;
    9963              :         }
    9964              : 
    9965              :       /* If a new iterator has been created for the current set of used
    9966              :          iterator variables, then use that as the iterator.  Otherwise,
    9967              :          create a new iterator for the current iterator variable set. */
    9968              :       unsigned i;
    9969          106 :       for (i = 0; i < iter_vars.length (); i++)
    9970              :         {
    9971          124 :           if (vars.length () != iter_vars[i].length ())
    9972            0 :             continue;
    9973              :           bool identical_p = true;
    9974          150 :           for (unsigned j = 0; j < vars.length () && identical_p; j++)
    9975           88 :             identical_p = vars[j] == iter_vars[i][j];
    9976              : 
    9977           62 :           if (identical_p)
    9978              :             break;
    9979              :         }
    9980           64 :       if (i < iter_vars.length ())
    9981           20 :         OMP_CLAUSE_ITERATORS (c) = new_iterators[i];
    9982              :       else
    9983              :         {
    9984           44 :           tree new_iters = NULL_TREE;
    9985           44 :           tree *new_iters_p = &new_iters;
    9986           44 :           tree new_vars = NULL_TREE;
    9987           44 :           tree *new_vars_p = &new_vars;
    9988           44 :           i = 0;
    9989          140 :           for (tree it = OMP_CLAUSE_ITERATORS (c); it && i < vars.length();
    9990           96 :                it = TREE_CHAIN (it))
    9991              :             {
    9992           96 :               tree var = TREE_VEC_ELT (it, 0);
    9993           96 :               if (var == vars[i])
    9994              :                 {
    9995           74 :                   *new_iters_p = copy_omp_iterator (it);
    9996           74 :                   *new_vars_p = build_decl (OMP_CLAUSE_LOCATION (c), VAR_DECL,
    9997           74 :                                             DECL_NAME (var), TREE_TYPE (var));
    9998           74 :                   DECL_ARTIFICIAL (*new_vars_p) = 1;
    9999           74 :                   DECL_CONTEXT (*new_vars_p) = DECL_CONTEXT (var);
   10000           74 :                   TREE_VEC_ELT (*new_iters_p, 0) = *new_vars_p;
   10001           74 :                   new_iters_p = &TREE_CHAIN (*new_iters_p);
   10002           74 :                   new_vars_p = &DECL_CHAIN (*new_vars_p);
   10003           74 :                   i++;
   10004              :                 }
   10005              :             }
   10006           44 :           tree old_block = TREE_VEC_ELT (OMP_CLAUSE_ITERATORS (c), 5);
   10007           44 :           tree new_block = make_node (BLOCK);
   10008           44 :           BLOCK_VARS (new_block) = new_vars;
   10009           44 :           if (BLOCK_SUBBLOCKS (old_block))
   10010              :             {
   10011            4 :               BLOCK_SUBBLOCKS (new_block) = BLOCK_SUBBLOCKS (old_block);
   10012            4 :               BLOCK_SUBBLOCKS (old_block) = NULL_TREE;
   10013              :             }
   10014           44 :           TREE_VEC_ELT (new_iters, 5) = new_block;
   10015           44 :           new_iterators.safe_push (new_iters);
   10016           44 :           iter_vars.safe_push (vars.copy ());
   10017           44 :           OMP_CLAUSE_ITERATORS (c) = new_iters;
   10018              :         }
   10019              : 
   10020              :       /* Remap clause to use the new variables.  */
   10021           64 :       i = 0;
   10022          170 :       for (tree it = OMP_CLAUSE_ITERATORS (c); it; it = TREE_CHAIN (it))
   10023              :         {
   10024          106 :           tree old_var = vars[i++];
   10025          106 :           tree new_var = TREE_VEC_ELT (it, 0);
   10026          106 :           remap_omp_iterator_var (&OMP_CLAUSE_DECL (c), old_var, new_var);
   10027          106 :           remap_omp_iterator_var (&OMP_CLAUSE_SIZE (c), old_var, new_var);
   10028              :         }
   10029          276 :     }
   10030              : 
   10031        27705 :   for (unsigned i = 0; i < iter_vars.length (); i++)
   10032           44 :     iter_vars[i].release ();
   10033        27661 : }
   10034              : 
   10035          248 : struct iterator_loop_info_t
   10036              : {
   10037              :   tree bind;
   10038              :   tree count;
   10039              :   tree index;
   10040              :   tree body_label;
   10041              :   auto_vec<tree> clauses;
   10042              : };
   10043              : 
   10044              : typedef hash_map<tree, iterator_loop_info_t> iterator_loop_info_map_t;
   10045              : 
   10046              : /* Builds a loop to expand any OpenMP iterators in the clauses in LIST_P,
   10047              :    reusing any previously built loops if they use the same set of iterators.
   10048              :    Generated Gimple statements are placed into LOOPS_SEQ_P.  The clause
   10049              :    iterators are updated with information on how and where to insert code into
   10050              :    the loop body.  */
   10051              : 
   10052              : static void
   10053        27661 : build_omp_iterators_loops (tree *list_p, gimple_seq *loops_seq_p)
   10054              : {
   10055        27661 :   iterator_loop_info_map_t loops;
   10056              : 
   10057        80586 :   for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
   10058              :     {
   10059        52925 :       if (!OMP_CLAUSE_HAS_ITERATORS (c))
   10060        52662 :         continue;
   10061              : 
   10062          263 :       bool built_p;
   10063          263 :       iterator_loop_info_t &loop
   10064          263 :         = loops.get_or_insert (OMP_CLAUSE_ITERATORS (c), &built_p);
   10065              : 
   10066          263 :       if (!built_p)
   10067              :         {
   10068          124 :           loop.count = compute_omp_iterator_count (OMP_CLAUSE_ITERATORS (c),
   10069              :                                                    loops_seq_p);
   10070          124 :           if (!loop.count)
   10071            0 :             continue;
   10072          124 :           if (integer_zerop (loop.count))
   10073            8 :             warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
   10074              :                         "iteration count is zero");
   10075              : 
   10076          124 :           loop.bind = NULL_TREE;
   10077          124 :           tree *body = build_omp_iterator_loop (OMP_CLAUSE_ITERATORS (c),
   10078              :                                                 loops_seq_p, &loop.bind);
   10079              : 
   10080          124 :           loop.index = create_tmp_var (sizetype);
   10081          124 :           SET_EXPR_LOCATION (loop.bind, OMP_CLAUSE_LOCATION (c));
   10082              : 
   10083              :           /* BEFORE LOOP:  */
   10084              :           /* idx = -1;  */
   10085              :           /* This should be initialized to before the individual elements,
   10086              :              as idx is pre-incremented in the loop body.  */
   10087          124 :           gimple *assign = gimple_build_assign (loop.index, size_int (-1));
   10088          124 :           gimple_seq_add_stmt (loops_seq_p, assign);
   10089              : 
   10090              :           /* IN LOOP BODY:  */
   10091              :           /* Create a label so we can find this point later.  */
   10092          124 :           loop.body_label = create_artificial_label (OMP_CLAUSE_LOCATION (c));
   10093          124 :           tree tem = build1 (LABEL_EXPR, void_type_node, loop.body_label);
   10094          124 :           append_to_statement_list_force (tem, body);
   10095              : 
   10096              :           /* idx += 2;  */
   10097          124 :           tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10098              :                             void_type_node, loop.index,
   10099              :                             size_binop (PLUS_EXPR, loop.index, size_int (2)));
   10100          124 :           append_to_statement_list_force (tem, body);
   10101              :         }
   10102              : 
   10103              :       /* Create array to hold expanded values.  */
   10104          263 :       tree last_count_2 = size_binop (MULT_EXPR, loop.count, size_int (2));
   10105          263 :       tree arr_length = size_binop (PLUS_EXPR, last_count_2, size_int (1));
   10106          263 :       tree elems = NULL_TREE;
   10107          263 :       if (TREE_CONSTANT (arr_length))
   10108              :         {
   10109          263 :           tree type = build_array_type (ptr_type_node,
   10110              :                                         build_index_type (arr_length));
   10111          263 :           elems = create_tmp_var_raw (type, "omp_iter_data");
   10112          263 :           TREE_ADDRESSABLE (elems) = 1;
   10113          263 :           gimple_add_tmp_var (elems);
   10114              :         }
   10115              :       else
   10116              :         {
   10117              :           /* Handle dynamic sizes.  */
   10118            0 :           sorry ("dynamic iterator sizes not implemented yet");
   10119              :         }
   10120              : 
   10121              :       /* BEFORE LOOP:  */
   10122              :       /* elems[0] = count;  */
   10123          263 :       tree lhs = build4 (ARRAY_REF, ptr_type_node, elems, size_int (0),
   10124              :                          NULL_TREE, NULL_TREE);
   10125          263 :       tree tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10126              :                              void_type_node, lhs, loop.count);
   10127          263 :       gimplify_and_add (tem, loops_seq_p);
   10128              : 
   10129              :       /* Make a copy of the iterator with extra info at the end.  */
   10130          263 :       int elem_count = TREE_VEC_LENGTH (OMP_CLAUSE_ITERATORS (c));
   10131          263 :       tree new_iterator = copy_omp_iterator (OMP_CLAUSE_ITERATORS (c),
   10132              :                                              elem_count + 3);
   10133          263 :       TREE_VEC_ELT (new_iterator, elem_count) = loop.body_label;
   10134          263 :       TREE_VEC_ELT (new_iterator, elem_count + 1) = elems;
   10135          263 :       TREE_VEC_ELT (new_iterator, elem_count + 2) = loop.index;
   10136          263 :       TREE_CHAIN (new_iterator) = TREE_CHAIN (OMP_CLAUSE_ITERATORS (c));
   10137          263 :       OMP_CLAUSE_ITERATORS (c) = new_iterator;
   10138              : 
   10139          263 :       loop.clauses.safe_push (c);
   10140              :     }
   10141              : 
   10142              :   /* Now gimplify and add all the loops that were built.  */
   10143        27785 :   for (hash_map<tree, iterator_loop_info_t>::iterator it = loops.begin ();
   10144        55570 :        it != loops.end (); ++it)
   10145          124 :     gimplify_and_add ((*it).second.bind, loops_seq_p);
   10146        27661 : }
   10147              : 
   10148              : /* Helper function for enter_omp_iterator_loop_context.  */
   10149              : 
   10150              : static gimple_seq *
   10151         2905 : enter_omp_iterator_loop_context_1 (tree iterator, gimple_seq *loops_seq_p)
   10152              : {
   10153              :   /* Drill into the nested bind expressions to get to the loop body.  */
   10154         2905 :   for (gimple_stmt_iterator gsi = gsi_start (*loops_seq_p);
   10155        19171 :        !gsi_end_p (gsi); gsi_next (&gsi))
   10156              :     {
   10157        18612 :       gimple *stmt = gsi_stmt (gsi);
   10158              : 
   10159        18612 :       switch (gimple_code (stmt))
   10160              :         {
   10161         2207 :         case GIMPLE_BIND:
   10162         2207 :           {
   10163         2207 :             gbind *bind_stmt = as_a<gbind *> (stmt);
   10164         2207 :             gimple_push_bind_expr (bind_stmt);
   10165         2207 :             gimple_seq *bind_body_p = gimple_bind_body_ptr (bind_stmt);
   10166         2207 :             gimple_seq *seq =
   10167         2207 :               enter_omp_iterator_loop_context_1 (iterator, bind_body_p);
   10168         2207 :             if (seq)
   10169              :               return seq;
   10170          559 :             gimple_pop_bind_expr ();
   10171              :           }
   10172          559 :           break;
   10173            3 :         case GIMPLE_TRY:
   10174            3 :           {
   10175            3 :             gimple_seq *try_eval_p = gimple_try_eval_ptr (stmt);
   10176            3 :             gimple_seq *seq =
   10177            3 :               enter_omp_iterator_loop_context_1 (iterator, try_eval_p);
   10178            3 :             if (seq)
   10179              :               return seq;
   10180              :           }
   10181              :           break;
   10182         2913 :         case GIMPLE_LABEL:
   10183         2913 :           {
   10184         2913 :             glabel *label_stmt = as_a<glabel *> (stmt);
   10185         2913 :             tree label = gimple_label_label (label_stmt);
   10186         2913 :             if (label == TREE_VEC_ELT (iterator, 6))
   10187              :               return loops_seq_p;
   10188              :           }
   10189              :           break;
   10190              :         default:
   10191              :           break;
   10192              :         }
   10193              :     }
   10194              : 
   10195              :   return NULL;
   10196              : }
   10197              : 
   10198              : /* Enter the Gimplification context in LOOPS_SEQ_P for the iterator loop
   10199              :    associated with OpenMP clause C.  Returns the gimple_seq for the loop body
   10200              :    if C has OpenMP iterators, or ALT_SEQ_P if not.  */
   10201              : 
   10202              : static gimple_seq *
   10203        65003 : enter_omp_iterator_loop_context (tree c, gimple_seq *loops_seq_p,
   10204              :                                  gimple_seq *alt_seq_p)
   10205              : {
   10206        65003 :   if (!OMP_CLAUSE_HAS_ITERATORS (c))
   10207              :     return alt_seq_p;
   10208              : 
   10209          695 :   push_gimplify_context ();
   10210              : 
   10211          695 :   gimple_seq *seq = enter_omp_iterator_loop_context_1 (OMP_CLAUSE_ITERATORS (c),
   10212              :                                                        loops_seq_p);
   10213          695 :   gcc_assert (seq);
   10214              :   return seq;
   10215              : }
   10216              : 
   10217              : /* Enter the Gimplification context in STMT for the iterator loop associated
   10218              :    with OpenMP clause C.  Returns the gimple_seq for the loop body if C has
   10219              :    OpenMP iterators, or ALT_SEQ_P if not.  */
   10220              : 
   10221              : gimple_seq *
   10222          434 : enter_omp_iterator_loop_context (tree c, gomp_target *stmt,
   10223              :                                  gimple_seq *alt_seq_p)
   10224              : {
   10225          434 :   gimple_seq *loops_seq_p = gimple_omp_target_iterator_loops_ptr (stmt);
   10226          434 :   return enter_omp_iterator_loop_context (c, loops_seq_p, alt_seq_p);
   10227              : }
   10228              : 
   10229              : /* Exit the Gimplification context for the OpenMP clause C.  */
   10230              : 
   10231              : void
   10232        65093 : exit_omp_iterator_loop_context (tree c)
   10233              : {
   10234        65093 :   if (!OMP_CLAUSE_HAS_ITERATORS (c))
   10235              :     return;
   10236         2343 :   while (!gimplify_ctxp->bind_expr_stack.is_empty ())
   10237         1648 :     gimple_pop_bind_expr ();
   10238          695 :   pop_gimplify_context (NULL);
   10239              : }
   10240              : 
   10241              : /* If *LIST_P contains any OpenMP depend clauses with iterators,
   10242              :    lower all the depend clauses by populating corresponding depend
   10243              :    array.  Returns 0 if there are no such depend clauses, or
   10244              :    2 if all depend clauses should be removed, 1 otherwise.  */
   10245              : 
   10246              : static int
   10247         1905 : gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
   10248              : {
   10249         1905 :   tree c;
   10250         1905 :   gimple *g;
   10251         1905 :   size_t n[5] = { 0, 0, 0, 0, 0 };
   10252         1905 :   bool unused[5];
   10253         1905 :   tree counts[5] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
   10254         1905 :   tree last_iter = NULL_TREE, last_count = NULL_TREE;
   10255         1905 :   size_t i, j;
   10256         1905 :   location_t first_loc = UNKNOWN_LOCATION;
   10257              : 
   10258         6250 :   for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
   10259         4345 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   10260              :       {
   10261         2207 :         switch (OMP_CLAUSE_DEPEND_KIND (c))
   10262              :           {
   10263              :           case OMP_CLAUSE_DEPEND_IN:
   10264              :             i = 2;
   10265              :             break;
   10266              :           case OMP_CLAUSE_DEPEND_OUT:
   10267              :           case OMP_CLAUSE_DEPEND_INOUT:
   10268              :             i = 0;
   10269              :             break;
   10270              :           case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
   10271              :             i = 1;
   10272              :             break;
   10273              :           case OMP_CLAUSE_DEPEND_DEPOBJ:
   10274              :             i = 3;
   10275              :             break;
   10276              :           case OMP_CLAUSE_DEPEND_INOUTSET:
   10277              :             i = 4;
   10278              :             break;
   10279            0 :           default:
   10280            0 :             gcc_unreachable ();
   10281              :           }
   10282         2207 :         tree t = OMP_CLAUSE_DECL (c);
   10283         2207 :         if (first_loc == UNKNOWN_LOCATION)
   10284         1905 :           first_loc = OMP_CLAUSE_LOCATION (c);
   10285         2207 :         if (OMP_ITERATOR_DECL_P (t))
   10286              :           {
   10287          302 :             if (TREE_PURPOSE (t) != last_iter)
   10288              :               {
   10289          255 :                 tree tcnt = compute_omp_iterator_count (TREE_PURPOSE (t),
   10290              :                                                         pre_p);
   10291          255 :                 if (!tcnt)
   10292              :                   return 2;
   10293          255 :                 last_iter = TREE_PURPOSE (t);
   10294          255 :                 last_count = tcnt;
   10295              :               }
   10296          302 :             if (counts[i] == NULL_TREE)
   10297          248 :               counts[i] = last_count;
   10298              :             else
   10299           54 :               counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
   10300              :                                           PLUS_EXPR, counts[i], last_count);
   10301              :           }
   10302              :         else
   10303         1905 :           n[i]++;
   10304              :       }
   10305        10620 :   for (i = 0; i < 5; i++)
   10306         8925 :     if (counts[i])
   10307              :       break;
   10308         1905 :   if (i == 5)
   10309              :     return 0;
   10310              : 
   10311          210 :   tree total = size_zero_node;
   10312         1260 :   for (i = 0; i < 5; i++)
   10313              :     {
   10314         1050 :       unused[i] = counts[i] == NULL_TREE && n[i] == 0;
   10315         1050 :       if (counts[i] == NULL_TREE)
   10316          802 :         counts[i] = size_zero_node;
   10317         1050 :       if (n[i])
   10318           44 :         counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
   10319         1050 :       if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
   10320              :                          fb_rvalue) == GS_ERROR)
   10321              :         return 2;
   10322         1050 :       total = size_binop (PLUS_EXPR, total, counts[i]);
   10323              :     }
   10324              : 
   10325          210 :   if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
   10326              :       == GS_ERROR)
   10327              :     return 2;
   10328          210 :   bool is_old = unused[1] && unused[3] && unused[4];
   10329          210 :   tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
   10330              :                              size_int (is_old ? 1 : 4));
   10331          210 :   if (!unused[4])
   10332            3 :     totalpx = size_binop (PLUS_EXPR, totalpx,
   10333              :                           size_binop (MULT_EXPR, counts[4], size_int (2)));
   10334          210 :   tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
   10335          210 :   tree array = create_tmp_var_raw (type);
   10336          210 :   TREE_ADDRESSABLE (array) = 1;
   10337          210 :   if (!poly_int_tree_p (totalpx))
   10338              :     {
   10339           83 :       if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
   10340           83 :         gimplify_type_sizes (TREE_TYPE (array), pre_p);
   10341           83 :       if (gimplify_omp_ctxp)
   10342              :         {
   10343              :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   10344              :           while (ctx
   10345           22 :                  && (ctx->region_type == ORT_WORKSHARE
   10346              :                      || ctx->region_type == ORT_TASKGROUP
   10347           22 :                      || ctx->region_type == ORT_SIMD
   10348           22 :                      || ctx->region_type == ORT_ACC))
   10349            0 :             ctx = ctx->outer_context;
   10350           22 :           if (ctx)
   10351           22 :             omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
   10352              :         }
   10353           83 :       gimplify_vla_decl (array, pre_p);
   10354              :     }
   10355              :   else
   10356          127 :     gimple_add_tmp_var (array);
   10357          210 :   tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
   10358              :                    NULL_TREE);
   10359          210 :   tree tem;
   10360          210 :   if (!is_old)
   10361              :     {
   10362           31 :       tem = build2 (MODIFY_EXPR, void_type_node, r,
   10363              :                     build_int_cst (ptr_type_node, 0));
   10364           31 :       gimplify_and_add (tem, pre_p);
   10365           31 :       r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
   10366              :                   NULL_TREE);
   10367              :     }
   10368          210 :   tem = build2 (MODIFY_EXPR, void_type_node, r,
   10369              :                 fold_convert (ptr_type_node, total));
   10370          210 :   gimplify_and_add (tem, pre_p);
   10371          816 :   for (i = 1; i < (is_old ? 2 : 4); i++)
   10372              :     {
   10373          272 :       r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
   10374              :                   NULL_TREE, NULL_TREE);
   10375          272 :       tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
   10376          272 :       gimplify_and_add (tem, pre_p);
   10377              :     }
   10378              : 
   10379              :   tree cnts[6];
   10380          740 :   for (j = 5; j; j--)
   10381          740 :     if (!unused[j - 1])
   10382              :       break;
   10383         1260 :   for (i = 0; i < 5; i++)
   10384              :     {
   10385         1050 :       if (i && (i >= j || unused[i - 1]))
   10386              :         {
   10387          790 :           cnts[i] = cnts[i - 1];
   10388          790 :           continue;
   10389              :         }
   10390          260 :       cnts[i] = create_tmp_var (sizetype);
   10391          260 :       if (i == 0)
   10392          241 :         g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
   10393              :       else
   10394              :         {
   10395           50 :           tree t;
   10396           50 :           if (is_old)
   10397           38 :             t = size_binop (PLUS_EXPR, counts[0], size_int (2));
   10398              :           else
   10399           12 :             t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
   10400           50 :           if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
   10401              :               == GS_ERROR)
   10402            0 :             return 2;
   10403           50 :           g = gimple_build_assign (cnts[i], t);
   10404              :         }
   10405          260 :       gimple_seq_add_stmt (pre_p, g);
   10406              :     }
   10407          210 :   if (unused[4])
   10408          207 :     cnts[5] = NULL_TREE;
   10409              :   else
   10410              :     {
   10411            3 :       tree t = size_binop (PLUS_EXPR, total, size_int (5));
   10412            3 :       cnts[5] = create_tmp_var (sizetype);
   10413            3 :       g = gimple_build_assign (cnts[i], t);
   10414            3 :       gimple_seq_add_stmt (pre_p, g);
   10415              :     }
   10416              : 
   10417          210 :   last_iter = NULL_TREE;
   10418          210 :   tree last_bind = NULL_TREE;
   10419          210 :   tree *last_body = NULL;
   10420          573 :   for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
   10421          363 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   10422              :       {
   10423          348 :         switch (OMP_CLAUSE_DEPEND_KIND (c))
   10424              :           {
   10425              :           case OMP_CLAUSE_DEPEND_IN:
   10426              :             i = 2;
   10427              :             break;
   10428              :           case OMP_CLAUSE_DEPEND_OUT:
   10429              :           case OMP_CLAUSE_DEPEND_INOUT:
   10430              :             i = 0;
   10431              :             break;
   10432              :           case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
   10433              :             i = 1;
   10434              :             break;
   10435              :           case OMP_CLAUSE_DEPEND_DEPOBJ:
   10436              :             i = 3;
   10437              :             break;
   10438              :           case OMP_CLAUSE_DEPEND_INOUTSET:
   10439              :             i = 4;
   10440              :             break;
   10441            0 :           default:
   10442            0 :             gcc_unreachable ();
   10443              :           }
   10444          348 :         tree t = OMP_CLAUSE_DECL (c);
   10445          348 :         if (OMP_ITERATOR_DECL_P (t))
   10446              :           {
   10447          302 :             if (TREE_PURPOSE (t) != last_iter)
   10448              :               {
   10449          255 :                 last_body = build_omp_iterator_loop (TREE_PURPOSE (t), pre_p,
   10450              :                                                      &last_bind);
   10451          255 :                 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
   10452              :               }
   10453          302 :             last_iter = TREE_PURPOSE (t);
   10454          302 :             if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
   10455              :               {
   10456            0 :                 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
   10457              :                                           0), last_body);
   10458            0 :                 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
   10459              :               }
   10460          302 :             if (error_operand_p (TREE_VALUE (t)))
   10461              :               return 2;
   10462          302 :             if (TREE_VALUE (t) != null_pointer_node)
   10463          296 :               TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
   10464          302 :             if (i == 4)
   10465              :               {
   10466            3 :                 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   10467              :                             NULL_TREE, NULL_TREE);
   10468            3 :                 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
   10469              :                                   NULL_TREE, NULL_TREE);
   10470            3 :                 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
   10471            3 :                 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10472              :                                   void_type_node, r, r2);
   10473            3 :                 append_to_statement_list_force (tem, last_body);
   10474            3 :                 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10475              :                                   void_type_node, cnts[i],
   10476              :                                   size_binop (PLUS_EXPR, cnts[i],
   10477              :                                               size_int (1)));
   10478            3 :                 append_to_statement_list_force (tem, last_body);
   10479            3 :                 i = 5;
   10480              :               }
   10481          302 :             r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   10482              :                         NULL_TREE, NULL_TREE);
   10483          604 :             tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10484          302 :                               void_type_node, r, TREE_VALUE (t));
   10485          302 :             append_to_statement_list_force (tem, last_body);
   10486          302 :             if (i == 5)
   10487              :               {
   10488            3 :                 r = build4 (ARRAY_REF, ptr_type_node, array,
   10489              :                             size_binop (PLUS_EXPR, cnts[i], size_int (1)),
   10490              :                             NULL_TREE, NULL_TREE);
   10491            3 :                 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
   10492            3 :                 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10493              :                                   void_type_node, r, tem);
   10494            3 :                 append_to_statement_list_force (tem, last_body);
   10495              :               }
   10496          302 :             tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10497              :                               void_type_node, cnts[i],
   10498          302 :                               size_binop (PLUS_EXPR, cnts[i],
   10499              :                                           size_int (1 + (i == 5))));
   10500          302 :             append_to_statement_list_force (tem, last_body);
   10501          302 :             TREE_VALUE (t) = null_pointer_node;
   10502              :           }
   10503              :         else
   10504              :           {
   10505           46 :             if (last_bind)
   10506              :               {
   10507           18 :                 gimplify_and_add (last_bind, pre_p);
   10508           18 :                 last_bind = NULL_TREE;
   10509              :               }
   10510           46 :             if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
   10511              :               {
   10512            0 :                 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
   10513              :                                NULL, is_gimple_val, fb_rvalue);
   10514            0 :                 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
   10515              :               }
   10516           46 :             if (error_operand_p (OMP_CLAUSE_DECL (c)))
   10517              :               return 2;
   10518           46 :             if (OMP_CLAUSE_DECL (c) != null_pointer_node)
   10519           46 :               OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
   10520           46 :             if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
   10521              :                                is_gimple_val, fb_rvalue) == GS_ERROR)
   10522              :               return 2;
   10523           46 :             if (i == 4)
   10524              :               {
   10525            0 :                 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   10526              :                             NULL_TREE, NULL_TREE);
   10527            0 :                 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
   10528              :                                   NULL_TREE, NULL_TREE);
   10529            0 :                 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
   10530            0 :                 tem = build2 (MODIFY_EXPR, void_type_node, r, r2);
   10531            0 :                 gimplify_and_add (tem, pre_p);
   10532            0 :                 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR,
   10533              :                                                               cnts[i],
   10534              :                                                               size_int (1)));
   10535            0 :                 gimple_seq_add_stmt (pre_p, g);
   10536            0 :                 i = 5;
   10537              :               }
   10538           46 :             r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   10539              :                         NULL_TREE, NULL_TREE);
   10540           46 :             tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
   10541           46 :             gimplify_and_add (tem, pre_p);
   10542           46 :             if (i == 5)
   10543              :               {
   10544            0 :                 r = build4 (ARRAY_REF, ptr_type_node, array,
   10545              :                             size_binop (PLUS_EXPR, cnts[i], size_int (1)),
   10546              :                             NULL_TREE, NULL_TREE);
   10547            0 :                 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
   10548            0 :                 tem = build2 (MODIFY_EXPR, void_type_node, r, tem);
   10549            0 :                 append_to_statement_list_force (tem, last_body);
   10550            0 :                 gimplify_and_add (tem, pre_p);
   10551              :               }
   10552           46 :             g = gimple_build_assign (cnts[i],
   10553           46 :                                      size_binop (PLUS_EXPR, cnts[i],
   10554              :                                                  size_int (1 + (i == 5))));
   10555           46 :             gimple_seq_add_stmt (pre_p, g);
   10556              :           }
   10557              :       }
   10558          210 :   if (last_bind)
   10559          206 :     gimplify_and_add (last_bind, pre_p);
   10560          210 :   tree cond = boolean_false_node;
   10561          210 :   if (is_old)
   10562              :     {
   10563          179 :       if (!unused[0])
   10564           92 :         cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
   10565              :                            size_binop_loc (first_loc, PLUS_EXPR, counts[0],
   10566              :                                            size_int (2)));
   10567          179 :       if (!unused[2])
   10568          125 :         cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
   10569              :                            build2_loc (first_loc, NE_EXPR, boolean_type_node,
   10570              :                                        cnts[2],
   10571              :                                        size_binop_loc (first_loc, PLUS_EXPR,
   10572              :                                                        totalpx,
   10573              :                                                        size_int (1))));
   10574              :     }
   10575              :   else
   10576              :     {
   10577           31 :       tree prev = size_int (5);
   10578          186 :       for (i = 0; i < 5; i++)
   10579              :         {
   10580          155 :           if (unused[i])
   10581          112 :             continue;
   10582           43 :           prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
   10583           43 :           cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
   10584              :                              build2_loc (first_loc, NE_EXPR, boolean_type_node,
   10585              :                                          cnts[i], unshare_expr (prev)));
   10586              :         }
   10587              :     }
   10588          210 :   tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
   10589              :                     build_call_expr_loc (first_loc,
   10590              :                                          builtin_decl_explicit (BUILT_IN_TRAP),
   10591              :                                          0), void_node);
   10592          210 :   gimplify_and_add (tem, pre_p);
   10593          210 :   c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
   10594          210 :   OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
   10595          210 :   OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
   10596          210 :   OMP_CLAUSE_CHAIN (c) = *list_p;
   10597          210 :   *list_p = c;
   10598          210 :   return 1;
   10599              : }
   10600              : 
   10601              : /* True if mapping node C maps, or unmaps, a (Fortran) array descriptor.  */
   10602              : 
   10603              : static bool
   10604       125724 : omp_map_clause_descriptor_p (tree c)
   10605              : {
   10606       125724 :   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
   10607              :     return false;
   10608              : 
   10609       125720 :   if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
   10610              :     return true;
   10611              : 
   10612        82502 :   if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_RELEASE
   10613        74464 :        || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DELETE)
   10614        82984 :       && OMP_CLAUSE_RELEASE_DESCRIPTOR (c))
   10615         6135 :     return true;
   10616              : 
   10617              :   return false;
   10618              : }
   10619              : 
   10620              : /* For a set of mappings describing an array section pointed to by a struct
   10621              :    (or derived type, etc.) component, create an "alloc" or "release" node to
   10622              :    insert into a list following a GOMP_MAP_STRUCT node.  For some types of
   10623              :    mapping (e.g. Fortran arrays with descriptors), an additional mapping may
   10624              :    be created that is inserted into the list of mapping nodes attached to the
   10625              :    directive being processed -- not part of the sorted list of nodes after
   10626              :    GOMP_MAP_STRUCT.
   10627              : 
   10628              :    CODE is the code of the directive being processed.  GRP_START and GRP_END
   10629              :    are the first and last of two or three nodes representing this array section
   10630              :    mapping (e.g. a data movement node like GOMP_MAP_{TO,FROM}, optionally a
   10631              :    GOMP_MAP_TO_PSET, and finally a GOMP_MAP_ALWAYS_POINTER).  EXTRA_NODE is
   10632              :    filled with the additional node described above, if needed.
   10633              : 
   10634              :    This function does not add the new nodes to any lists itself.  It is the
   10635              :    responsibility of the caller to do that.  */
   10636              : 
   10637              : static tree
   10638         1729 : build_omp_struct_comp_nodes (enum tree_code code, tree grp_start, tree grp_end,
   10639              :                              tree *extra_node)
   10640              : {
   10641         1524 :   enum gomp_map_kind mkind
   10642         1729 :     = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
   10643         1729 :       ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
   10644              : 
   10645         1729 :   gcc_assert (grp_start != grp_end);
   10646              : 
   10647         1729 :   tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
   10648         1729 :   OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
   10649         1729 :   OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (grp_end));
   10650         1729 :   OMP_CLAUSE_CHAIN (c2) = NULL_TREE;
   10651         1729 :   tree grp_mid = NULL_TREE;
   10652         1729 :   if (OMP_CLAUSE_CHAIN (grp_start) != grp_end)
   10653          197 :     grp_mid = OMP_CLAUSE_CHAIN (grp_start);
   10654              : 
   10655          197 :   if (grp_mid && omp_map_clause_descriptor_p (grp_mid))
   10656            0 :     OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (grp_mid);
   10657              :   else
   10658         1729 :     OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
   10659              : 
   10660         1729 :   if (grp_mid
   10661          197 :       && OMP_CLAUSE_CODE (grp_mid) == OMP_CLAUSE_MAP
   10662         1926 :       && OMP_CLAUSE_MAP_KIND (grp_mid) == GOMP_MAP_ALWAYS_POINTER)
   10663              :     {
   10664            0 :       tree c3
   10665            0 :         = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
   10666            0 :       OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
   10667            0 :       OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (grp_mid));
   10668            0 :       OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
   10669            0 :       OMP_CLAUSE_CHAIN (c3) = NULL_TREE;
   10670              : 
   10671            0 :       *extra_node = c3;
   10672              :     }
   10673              :   else
   10674         1729 :     *extra_node = NULL_TREE;
   10675              : 
   10676         1729 :   return c2;
   10677              : }
   10678              : 
   10679              : /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
   10680              :    and set *BITPOSP and *POFFSETP to the bit offset of the access.
   10681              :    If BASE_REF is non-NULL and the containing object is a reference, set
   10682              :    *BASE_REF to that reference before dereferencing the object.
   10683              :    If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
   10684              :    has array type, else return NULL.  */
   10685              : 
   10686              : static tree
   10687         7739 : extract_base_bit_offset (tree base, poly_int64 *bitposp,
   10688              :                          poly_offset_int *poffsetp,
   10689              :                          bool *variable_offset,
   10690              :                          tree iterator)
   10691              : {
   10692         7739 :   tree offset;
   10693         7739 :   poly_int64 bitsize, bitpos;
   10694         7739 :   machine_mode mode;
   10695         7739 :   int unsignedp, reversep, volatilep = 0;
   10696         7739 :   poly_offset_int poffset;
   10697              : 
   10698         7739 :   STRIP_NOPS (base);
   10699              : 
   10700         7739 :   if (iterator)
   10701              :     {
   10702              :       /* Replace any iterator variables with the lower bound of the iterator.
   10703              :          This will give us the nominal offset and bit position of the first
   10704              :          element, which is all we should need to lay out the mappings.  The
   10705              :          actual locations of the iterated mappings are elsewhere.  */
   10706              :       tree it;
   10707           72 :       for (it = iterator; it; it = TREE_CHAIN (it))
   10708           39 :         base = simplify_replace_tree (base, TREE_VEC_ELT (it, 0),
   10709           39 :                                       TREE_VEC_ELT (it, 1));
   10710              :     }
   10711              : 
   10712         7739 :   base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
   10713              :                               &unsignedp, &reversep, &volatilep);
   10714              : 
   10715         7739 :   STRIP_NOPS (base);
   10716              : 
   10717         7739 :   if (offset && poly_int_tree_p (offset))
   10718              :     {
   10719            0 :       poffset = wi::to_poly_offset (offset);
   10720            0 :       *variable_offset = false;
   10721              :     }
   10722              :   else
   10723              :     {
   10724         7739 :       poffset = 0;
   10725         7739 :       *variable_offset = (offset != NULL_TREE);
   10726              :     }
   10727              : 
   10728         7739 :   if (maybe_ne (bitpos, 0))
   10729         5627 :     poffset += bits_to_bytes_round_down (bitpos);
   10730              : 
   10731         7739 :   *bitposp = bitpos;
   10732         7739 :   *poffsetp = poffset;
   10733              : 
   10734         7739 :   return base;
   10735              : }
   10736              : 
   10737              : /* Used for topological sorting of mapping groups.  UNVISITED means we haven't
   10738              :    started processing the group yet.  The TEMPORARY mark is used when we first
   10739              :    encounter a group on a depth-first traversal, and the PERMANENT mark is used
   10740              :    when we have processed all the group's children (i.e. all the base pointers
   10741              :    referred to by the group's mapping nodes, recursively).  */
   10742              : 
   10743              : enum omp_tsort_mark {
   10744              :   UNVISITED,
   10745              :   TEMPORARY,
   10746              :   PERMANENT
   10747              : };
   10748              : 
   10749              : /* Hash for trees based on operand_equal_p.  Like tree_operand_hash
   10750              :    but ignores side effects in the equality comparisons.  */
   10751              : 
   10752              : struct tree_operand_hash_no_se : tree_operand_hash
   10753              : {
   10754              :   static inline bool equal (const value_type &,
   10755              :                             const compare_type &);
   10756              : };
   10757              : 
   10758              : inline bool
   10759       405714 : tree_operand_hash_no_se::equal (const value_type &t1,
   10760              :                                 const compare_type &t2)
   10761              : {
   10762       405714 :   return operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS);
   10763              : }
   10764              : 
   10765              : /* A group of OMP_CLAUSE_MAP nodes that correspond to a single "map"
   10766              :    clause.  */
   10767              : 
   10768              : struct omp_mapping_group {
   10769              :   tree *grp_start;
   10770              :   tree grp_end;
   10771              :   omp_tsort_mark mark;
   10772              :   /* If we've removed the group but need to reindex, mark the group as
   10773              :      deleted.  */
   10774              :   bool deleted;
   10775              :   /* The group points to an already-created "GOMP_MAP_STRUCT
   10776              :      GOMP_MAP_ATTACH_DETACH" pair.  */
   10777              :   bool reprocess_struct;
   10778              :   /* The group should use "zero-length" allocations for pointers that are not
   10779              :      mapped "to" on the same directive.  */
   10780              :   bool fragile;
   10781              :   struct omp_mapping_group *sibling;
   10782              :   struct omp_mapping_group *next;
   10783              : };
   10784              : 
   10785              : DEBUG_FUNCTION void
   10786            0 : debug_mapping_group (omp_mapping_group *grp)
   10787              : {
   10788            0 :   tree tmp = OMP_CLAUSE_CHAIN (grp->grp_end);
   10789            0 :   OMP_CLAUSE_CHAIN (grp->grp_end) = NULL;
   10790            0 :   debug_generic_expr (*grp->grp_start);
   10791            0 :   OMP_CLAUSE_CHAIN (grp->grp_end) = tmp;
   10792            0 : }
   10793              : 
   10794              : /* Return the OpenMP "base pointer" of an expression EXPR, or NULL if there
   10795              :    isn't one.  */
   10796              : 
   10797              : static tree
   10798        36320 : omp_get_base_pointer (tree expr)
   10799              : {
   10800        36320 :   while (TREE_CODE (expr) == ARRAY_REF
   10801        43559 :          || TREE_CODE (expr) == COMPONENT_REF)
   10802         7239 :     expr = TREE_OPERAND (expr, 0);
   10803              : 
   10804        36320 :   if (INDIRECT_REF_P (expr)
   10805        36320 :       || (TREE_CODE (expr) == MEM_REF
   10806            1 :           && integer_zerop (TREE_OPERAND (expr, 1))))
   10807              :     {
   10808        10582 :       expr = TREE_OPERAND (expr, 0);
   10809        10619 :       while (TREE_CODE (expr) == COMPOUND_EXPR)
   10810           37 :         expr = TREE_OPERAND (expr, 1);
   10811        10582 :       if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
   10812          841 :         expr = TREE_OPERAND (expr, 0);
   10813        10582 :       if (TREE_CODE (expr) == SAVE_EXPR)
   10814           31 :         expr = TREE_OPERAND (expr, 0);
   10815        10582 :       STRIP_NOPS (expr);
   10816        10582 :       return expr;
   10817              :     }
   10818              : 
   10819              :   return NULL_TREE;
   10820              : }
   10821              : 
   10822              : /* An attach or detach operation depends directly on the address being
   10823              :    attached/detached.  Return that address, or none if there are no
   10824              :    attachments/detachments.  */
   10825              : 
   10826              : static tree
   10827        16811 : omp_get_attachment (omp_mapping_group *grp)
   10828              : {
   10829        16811 :   tree node = *grp->grp_start;
   10830              : 
   10831        16811 :   switch (OMP_CLAUSE_MAP_KIND (node))
   10832              :     {
   10833        13857 :     case GOMP_MAP_TO:
   10834        13857 :     case GOMP_MAP_FROM:
   10835        13857 :     case GOMP_MAP_TOFROM:
   10836        13857 :     case GOMP_MAP_ALWAYS_FROM:
   10837        13857 :     case GOMP_MAP_ALWAYS_TO:
   10838        13857 :     case GOMP_MAP_ALWAYS_TOFROM:
   10839        13857 :     case GOMP_MAP_FORCE_FROM:
   10840        13857 :     case GOMP_MAP_FORCE_TO:
   10841        13857 :     case GOMP_MAP_FORCE_TOFROM:
   10842        13857 :     case GOMP_MAP_FORCE_PRESENT:
   10843        13857 :     case GOMP_MAP_PRESENT_ALLOC:
   10844        13857 :     case GOMP_MAP_PRESENT_FROM:
   10845        13857 :     case GOMP_MAP_PRESENT_TO:
   10846        13857 :     case GOMP_MAP_PRESENT_TOFROM:
   10847        13857 :     case GOMP_MAP_ALWAYS_PRESENT_FROM:
   10848        13857 :     case GOMP_MAP_ALWAYS_PRESENT_TO:
   10849        13857 :     case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   10850        13857 :     case GOMP_MAP_ALLOC:
   10851        13857 :     case GOMP_MAP_RELEASE:
   10852        13857 :     case GOMP_MAP_DELETE:
   10853        13857 :     case GOMP_MAP_FORCE_ALLOC:
   10854        13857 :       if (node == grp->grp_end)
   10855              :         return NULL_TREE;
   10856              : 
   10857         6613 :       node = OMP_CLAUSE_CHAIN (node);
   10858         6613 :       if (node && omp_map_clause_descriptor_p (node))
   10859              :         {
   10860         1038 :           gcc_assert (node != grp->grp_end);
   10861         1038 :           node = OMP_CLAUSE_CHAIN (node);
   10862              :         }
   10863         6613 :       if (node)
   10864         6613 :         switch (OMP_CLAUSE_MAP_KIND (node))
   10865              :           {
   10866              :           case GOMP_MAP_POINTER:
   10867              :           case GOMP_MAP_ALWAYS_POINTER:
   10868              :           case GOMP_MAP_FIRSTPRIVATE_POINTER:
   10869              :           case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   10870              :           case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   10871              :             return NULL_TREE;
   10872              : 
   10873         2554 :           case GOMP_MAP_ATTACH_DETACH:
   10874         2554 :           case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   10875         2554 :           case GOMP_MAP_DETACH:
   10876         2554 :             return OMP_CLAUSE_DECL (node);
   10877              : 
   10878            0 :           default:
   10879            0 :             internal_error ("unexpected mapping node");
   10880              :           }
   10881            0 :       return error_mark_node;
   10882              : 
   10883            0 :     case GOMP_MAP_TO_PSET:
   10884            0 :       gcc_assert (node != grp->grp_end);
   10885            0 :       node = OMP_CLAUSE_CHAIN (node);
   10886            0 :       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH
   10887            0 :           || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH)
   10888            0 :         return OMP_CLAUSE_DECL (node);
   10889              :       else
   10890            0 :         internal_error ("unexpected mapping node");
   10891              :       return error_mark_node;
   10892              : 
   10893          537 :     case GOMP_MAP_ATTACH:
   10894          537 :     case GOMP_MAP_DETACH:
   10895          537 :       node = OMP_CLAUSE_CHAIN (node);
   10896          537 :       if (!node || *grp->grp_start == grp->grp_end)
   10897          537 :         return OMP_CLAUSE_DECL (*grp->grp_start);
   10898            0 :       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
   10899            0 :           || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   10900            0 :         return OMP_CLAUSE_DECL (*grp->grp_start);
   10901              :       else
   10902            0 :         internal_error ("unexpected mapping node");
   10903              :       return error_mark_node;
   10904              : 
   10905              :     case GOMP_MAP_STRUCT:
   10906              :     case GOMP_MAP_STRUCT_UNORD:
   10907              :     case GOMP_MAP_FORCE_DEVICEPTR:
   10908              :     case GOMP_MAP_DEVICE_RESIDENT:
   10909              :     case GOMP_MAP_LINK:
   10910              :     case GOMP_MAP_IF_PRESENT:
   10911              :     case GOMP_MAP_FIRSTPRIVATE:
   10912              :     case GOMP_MAP_FIRSTPRIVATE_INT:
   10913              :     case GOMP_MAP_USE_DEVICE_PTR:
   10914              :     case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   10915              :       return NULL_TREE;
   10916              : 
   10917            0 :     default:
   10918            0 :       internal_error ("unexpected mapping node");
   10919              :     }
   10920              : 
   10921              :   return error_mark_node;
   10922              : }
   10923              : 
   10924              : /* Given a pointer START_P to the start of a group of related (e.g. pointer)
   10925              :    mappings, return the chain pointer to the end of that group in the list.  */
   10926              : 
   10927              : static tree *
   10928       111132 : omp_group_last (tree *start_p)
   10929              : {
   10930       111132 :   tree c = *start_p, nc, *grp_last_p = start_p;
   10931              : 
   10932       111132 :   gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP);
   10933              : 
   10934       111132 :   nc = OMP_CLAUSE_CHAIN (c);
   10935              : 
   10936       193958 :   if (!nc || OMP_CLAUSE_CODE (nc) != OMP_CLAUSE_MAP)
   10937              :     return grp_last_p;
   10938              : 
   10939        70617 :   switch (OMP_CLAUSE_MAP_KIND (c))
   10940              :     {
   10941              :     default:
   10942              :       while (nc
   10943       113532 :              && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
   10944       238448 :              && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   10945       106354 :                  || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER
   10946        95765 :                  || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH
   10947        82958 :                  || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
   10948        56874 :                  || (OMP_CLAUSE_MAP_KIND (nc)
   10949              :                      == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
   10950        56858 :                  || (OMP_CLAUSE_MAP_KIND (nc)
   10951              :                      == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)
   10952        56491 :                  || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH
   10953        56436 :                  || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ALWAYS_POINTER
   10954        54524 :                  || omp_map_clause_descriptor_p (nc)))
   10955              :         {
   10956        66931 :           tree nc2 = OMP_CLAUSE_CHAIN (nc);
   10957        66931 :           if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH)
   10958              :             {
   10959              :               /* In the specific case we're doing "exit data" on an array
   10960              :                  slice of a reference-to-pointer struct component, we will see
   10961              :                  DETACH followed by ATTACH_DETACH here.  We want to treat that
   10962              :                  as a single group. In other cases DETACH might represent a
   10963              :                  stand-alone "detach" clause, so we don't want to consider
   10964              :                  that part of the group.  */
   10965           55 :               if (nc2
   10966           16 :                   && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP
   10967           71 :                   && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH_DETACH)
   10968            0 :                 goto consume_two_nodes;
   10969              :               else
   10970              :                 break;
   10971              :             }
   10972        66876 :           if (nc2
   10973        48983 :               && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP
   10974        42470 :               && (OMP_CLAUSE_MAP_KIND (nc)
   10975              :                   == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
   10976        66892 :               && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH)
   10977              :             {
   10978           16 :             consume_two_nodes:
   10979           16 :               grp_last_p = &OMP_CLAUSE_CHAIN (nc);
   10980           16 :               c = nc2;
   10981           16 :               nc = OMP_CLAUSE_CHAIN (nc2);
   10982              :             }
   10983              :           else
   10984              :             {
   10985        66860 :               grp_last_p = &OMP_CLAUSE_CHAIN (c);
   10986        66860 :               c = nc;
   10987        66860 :               nc = nc2;
   10988              :             }
   10989              :         }
   10990              :       break;
   10991              : 
   10992          302 :     case GOMP_MAP_ATTACH:
   10993          302 :     case GOMP_MAP_DETACH:
   10994              :       /* This is a weird artifact of how directives are parsed: bare attach or
   10995              :          detach clauses get a subsequent (meaningless) FIRSTPRIVATE_POINTER or
   10996              :          FIRSTPRIVATE_REFERENCE node.  FIXME.  */
   10997          302 :       if (nc
   10998          302 :           && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
   10999          302 :           && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   11000          302 :               || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER))
   11001            0 :         grp_last_p = &OMP_CLAUSE_CHAIN (c);
   11002              :       break;
   11003              : 
   11004           39 :     case GOMP_MAP_TO_PSET:
   11005           39 :       if (OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
   11006           39 :           && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH
   11007           12 :               || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH))
   11008           39 :         grp_last_p = &OMP_CLAUSE_CHAIN (c);
   11009              :       break;
   11010              : 
   11011         5723 :     case GOMP_MAP_STRUCT:
   11012         5723 :     case GOMP_MAP_STRUCT_UNORD:
   11013         5723 :       {
   11014         5723 :         unsigned HOST_WIDE_INT num_mappings
   11015         5723 :           = tree_to_uhwi (OMP_CLAUSE_SIZE (c));
   11016         5723 :         if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER
   11017         5385 :             || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   11018        10626 :             || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH)
   11019         1134 :           grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p);
   11020        14389 :         for (unsigned i = 0; i < num_mappings; i++)
   11021         8666 :           grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p);
   11022              :       }
   11023              :       break;
   11024              :     }
   11025              : 
   11026              :   return grp_last_p;
   11027              : }
   11028              : 
   11029              : /* Walk through LIST_P, and return a list of groups of mappings found (e.g.
   11030              :    OMP_CLAUSE_MAP with GOMP_MAP_{TO/FROM/TOFROM} followed by one or two
   11031              :    associated GOMP_MAP_POINTER mappings).  Return a vector of omp_mapping_group
   11032              :    if we have more than one such group, else return NULL.  */
   11033              : 
   11034              : static void
   11035        89638 : omp_gather_mapping_groups_1 (tree *list_p, vec<omp_mapping_group> *groups,
   11036              :                              tree gather_sentinel)
   11037              : {
   11038        89638 :   for (tree *cp = list_p;
   11039       267687 :        *cp && *cp != gather_sentinel;
   11040       178049 :        cp = &OMP_CLAUSE_CHAIN (*cp))
   11041              :     {
   11042       178049 :       if (OMP_CLAUSE_CODE (*cp) != OMP_CLAUSE_MAP)
   11043        98601 :         continue;
   11044              : 
   11045        79448 :       tree *grp_last_p = omp_group_last (cp);
   11046        79448 :       omp_mapping_group grp;
   11047              : 
   11048        79448 :       grp.grp_start = cp;
   11049        79448 :       grp.grp_end = *grp_last_p;
   11050        79448 :       grp.mark = UNVISITED;
   11051        79448 :       grp.sibling = NULL;
   11052        79448 :       grp.deleted = false;
   11053        79448 :       grp.reprocess_struct = false;
   11054        79448 :       grp.fragile = false;
   11055        79448 :       grp.next = NULL;
   11056        79448 :       groups->safe_push (grp);
   11057              : 
   11058        79448 :       cp = grp_last_p;
   11059              :     }
   11060        89638 : }
   11061              : 
   11062              : static vec<omp_mapping_group> *
   11063        89320 : omp_gather_mapping_groups (tree *list_p)
   11064              : {
   11065        89320 :   vec<omp_mapping_group> *groups = new vec<omp_mapping_group> ();
   11066              : 
   11067        89320 :   omp_gather_mapping_groups_1 (list_p, groups, NULL_TREE);
   11068              : 
   11069        89320 :   if (groups->length () > 0)
   11070              :     return groups;
   11071              :   else
   11072              :     {
   11073        44650 :       delete groups;
   11074        44650 :       return NULL;
   11075              :     }
   11076              : }
   11077              : 
   11078              : /* A pointer mapping group GRP may define a block of memory starting at some
   11079              :    base address, and maybe also define a firstprivate pointer or firstprivate
   11080              :    reference that points to that block.  The return value is a node containing
   11081              :    the former, and the *FIRSTPRIVATE pointer is set if we have the latter.
   11082              :    If we define several base pointers, i.e. for a GOMP_MAP_STRUCT mapping,
   11083              :    return the number of consecutive chained nodes in CHAINED.  */
   11084              : 
   11085              : static tree
   11086        79842 : omp_group_base (omp_mapping_group *grp, unsigned int *chained,
   11087              :                 tree *firstprivate)
   11088              : {
   11089        79842 :   tree node = *grp->grp_start;
   11090              : 
   11091        79842 :   *firstprivate = NULL_TREE;
   11092        79842 :   *chained = 1;
   11093              : 
   11094        79842 :   switch (OMP_CLAUSE_MAP_KIND (node))
   11095              :     {
   11096        75658 :     case GOMP_MAP_TO:
   11097        75658 :     case GOMP_MAP_FROM:
   11098        75658 :     case GOMP_MAP_TOFROM:
   11099        75658 :     case GOMP_MAP_ALWAYS_FROM:
   11100        75658 :     case GOMP_MAP_ALWAYS_TO:
   11101        75658 :     case GOMP_MAP_ALWAYS_TOFROM:
   11102        75658 :     case GOMP_MAP_FORCE_FROM:
   11103        75658 :     case GOMP_MAP_FORCE_TO:
   11104        75658 :     case GOMP_MAP_FORCE_TOFROM:
   11105        75658 :     case GOMP_MAP_FORCE_PRESENT:
   11106        75658 :     case GOMP_MAP_PRESENT_ALLOC:
   11107        75658 :     case GOMP_MAP_PRESENT_FROM:
   11108        75658 :     case GOMP_MAP_PRESENT_TO:
   11109        75658 :     case GOMP_MAP_PRESENT_TOFROM:
   11110        75658 :     case GOMP_MAP_ALWAYS_PRESENT_FROM:
   11111        75658 :     case GOMP_MAP_ALWAYS_PRESENT_TO:
   11112        75658 :     case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   11113        75658 :     case GOMP_MAP_ALLOC:
   11114        75658 :     case GOMP_MAP_RELEASE:
   11115        75658 :     case GOMP_MAP_DELETE:
   11116        75658 :     case GOMP_MAP_FORCE_ALLOC:
   11117        75658 :     case GOMP_MAP_IF_PRESENT:
   11118        75658 :       if (node == grp->grp_end)
   11119              :         return node;
   11120              : 
   11121        34756 :       node = OMP_CLAUSE_CHAIN (node);
   11122        34756 :       if (!node)
   11123            0 :         internal_error ("unexpected mapping node");
   11124        34756 :       if (omp_map_clause_descriptor_p (node))
   11125              :         {
   11126        10754 :           if (node == grp->grp_end)
   11127            0 :             return *grp->grp_start;
   11128        10754 :           node = OMP_CLAUSE_CHAIN (node);
   11129              :         }
   11130        34756 :       switch (OMP_CLAUSE_MAP_KIND (node))
   11131              :         {
   11132        23458 :         case GOMP_MAP_POINTER:
   11133        23458 :         case GOMP_MAP_FIRSTPRIVATE_POINTER:
   11134        23458 :         case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   11135        23458 :         case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   11136        23458 :           *firstprivate = OMP_CLAUSE_DECL (node);
   11137        23458 :           return *grp->grp_start;
   11138              : 
   11139        11298 :         case GOMP_MAP_ALWAYS_POINTER:
   11140        11298 :         case GOMP_MAP_ATTACH_DETACH:
   11141        11298 :         case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   11142        11298 :         case GOMP_MAP_DETACH:
   11143        11298 :           return *grp->grp_start;
   11144              : 
   11145            0 :         default:
   11146            0 :           internal_error ("unexpected mapping node");
   11147              :         }
   11148              :       return error_mark_node;
   11149              : 
   11150           26 :     case GOMP_MAP_TO_PSET:
   11151           26 :       gcc_assert (node != grp->grp_end);
   11152           26 :       node = OMP_CLAUSE_CHAIN (node);
   11153           26 :       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH
   11154           26 :           || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH)
   11155              :         return NULL_TREE;
   11156              :       else
   11157            0 :         internal_error ("unexpected mapping node");
   11158              :       return error_mark_node;
   11159              : 
   11160         1097 :     case GOMP_MAP_ATTACH:
   11161         1097 :     case GOMP_MAP_DETACH:
   11162         1097 :       node = OMP_CLAUSE_CHAIN (node);
   11163         1097 :       if (!node || *grp->grp_start == grp->grp_end)
   11164              :         return NULL_TREE;
   11165            0 :       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
   11166            0 :           || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   11167              :         {
   11168              :           /* We're mapping the base pointer itself in a bare attach or detach
   11169              :              node.  This is a side effect of how parsing works, and the mapping
   11170              :              will be removed anyway (at least for enter/exit data directives).
   11171              :              We should ignore the mapping here.  FIXME.  */
   11172              :           return NULL_TREE;
   11173              :         }
   11174              :       else
   11175            0 :         internal_error ("unexpected mapping node");
   11176              :       return error_mark_node;
   11177              : 
   11178         2777 :     case GOMP_MAP_STRUCT:
   11179         2777 :     case GOMP_MAP_STRUCT_UNORD:
   11180         2777 :       {
   11181         2777 :         unsigned HOST_WIDE_INT num_mappings
   11182         2777 :           = tree_to_uhwi (OMP_CLAUSE_SIZE (node));
   11183         2777 :         node = OMP_CLAUSE_CHAIN (node);
   11184         2777 :         if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
   11185         2777 :             || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   11186              :           {
   11187          393 :             *firstprivate = OMP_CLAUSE_DECL (node);
   11188          393 :             node = OMP_CLAUSE_CHAIN (node);
   11189              :           }
   11190         2384 :         else if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH_DETACH)
   11191          314 :           node = OMP_CLAUSE_CHAIN (node);
   11192         2777 :         *chained = num_mappings;
   11193         2777 :         return node;
   11194              :       }
   11195              : 
   11196              :     case GOMP_MAP_FORCE_DEVICEPTR:
   11197              :     case GOMP_MAP_DEVICE_RESIDENT:
   11198              :     case GOMP_MAP_LINK:
   11199              :     case GOMP_MAP_FIRSTPRIVATE:
   11200              :     case GOMP_MAP_FIRSTPRIVATE_INT:
   11201              :     case GOMP_MAP_USE_DEVICE_PTR:
   11202              :     case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   11203              :       return NULL_TREE;
   11204              : 
   11205            0 :     case GOMP_MAP_FIRSTPRIVATE_POINTER:
   11206            0 :     case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   11207            0 :     case GOMP_MAP_POINTER:
   11208            0 :     case GOMP_MAP_ALWAYS_POINTER:
   11209            0 :     case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   11210              :       /* These shouldn't appear by themselves.  */
   11211            0 :       if (!seen_error ())
   11212            0 :         internal_error ("unexpected pointer mapping node");
   11213            0 :       return error_mark_node;
   11214              : 
   11215            0 :     default:
   11216            0 :       gcc_unreachable ();
   11217              :     }
   11218              : 
   11219              :   return error_mark_node;
   11220              : }
   11221              : 
   11222              : /* Given a vector of omp_mapping_groups, build a hash table so we can look up
   11223              :    nodes by tree_operand_hash_no_se.  */
   11224              : 
   11225              : static void
   11226        45154 : omp_index_mapping_groups_1 (hash_map<tree_operand_hash_no_se,
   11227              :                                      omp_mapping_group *> *grpmap,
   11228              :                             vec<omp_mapping_group> *groups,
   11229              :                             tree reindex_sentinel)
   11230              : {
   11231        45154 :   omp_mapping_group *grp;
   11232        45154 :   unsigned int i;
   11233        45154 :   bool reindexing = reindex_sentinel != NULL_TREE, above_hwm = false;
   11234              : 
   11235       125450 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   11236              :     {
   11237        80296 :       if (reindexing && *grp->grp_start == reindex_sentinel)
   11238        80296 :         above_hwm = true;
   11239              : 
   11240        80296 :       if (reindexing && !above_hwm)
   11241        56445 :         continue;
   11242              : 
   11243        79996 :       if (grp->reprocess_struct)
   11244          154 :         continue;
   11245              : 
   11246        79842 :       tree fpp;
   11247        79842 :       unsigned int chained;
   11248        79842 :       tree node = omp_group_base (grp, &chained, &fpp);
   11249              : 
   11250        79842 :       if (node == error_mark_node || (!node && !fpp))
   11251         1407 :         continue;
   11252              : 
   11253              :       for (unsigned j = 0;
   11254       158314 :            node && j < chained;
   11255        79879 :            node = OMP_CLAUSE_CHAIN (node), j++)
   11256              :         {
   11257        79879 :           tree decl = OMP_CLAUSE_DECL (node);
   11258              :           /* Sometimes we see zero-offset MEM_REF instead of INDIRECT_REF,
   11259              :              meaning node-hash lookups don't work.  This is a workaround for
   11260              :              that, but ideally we should just create the INDIRECT_REF at
   11261              :              source instead.  FIXME.  */
   11262        79879 :           if (TREE_CODE (decl) == MEM_REF
   11263        79879 :               && integer_zerop (TREE_OPERAND (decl, 1)))
   11264            0 :             decl = build_fold_indirect_ref (TREE_OPERAND (decl, 0));
   11265              : 
   11266        79879 :           omp_mapping_group **prev = grpmap->get (decl);
   11267              : 
   11268        79879 :           if (prev && *prev == grp)
   11269              :             /* Empty.  */;
   11270        79879 :           else if (prev)
   11271              :             {
   11272              :               /* Mapping the same thing twice is normally diagnosed as an error,
   11273              :                  but can happen under some circumstances, e.g. in pr99928-16.c,
   11274              :                  the directive:
   11275              : 
   11276              :                  #pragma omp target simd reduction(+:a[:3]) \
   11277              :                                          map(always, tofrom: a[:6])
   11278              :                  ...
   11279              : 
   11280              :                  will result in two "a[0]" mappings (of different sizes).  */
   11281              : 
   11282          326 :               grp->sibling = (*prev)->sibling;
   11283          326 :               (*prev)->sibling = grp;
   11284              :             }
   11285              :           else
   11286        79553 :             grpmap->put (decl, grp);
   11287              :         }
   11288              : 
   11289        78435 :       if (!fpp)
   11290        54584 :         continue;
   11291              : 
   11292        23851 :       omp_mapping_group **prev = grpmap->get (fpp);
   11293        23851 :       if (prev && *prev != grp)
   11294              :         {
   11295           12 :           grp->sibling = (*prev)->sibling;
   11296           12 :           (*prev)->sibling = grp;
   11297              :         }
   11298              :       else
   11299        23839 :         grpmap->put (fpp, grp);
   11300              :     }
   11301        45154 : }
   11302              : 
   11303              : static hash_map<tree_operand_hash_no_se, omp_mapping_group *> *
   11304        44670 : omp_index_mapping_groups (vec<omp_mapping_group> *groups)
   11305              : {
   11306        44670 :   hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap
   11307        44670 :     = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>;
   11308              : 
   11309        44670 :   omp_index_mapping_groups_1 (grpmap, groups, NULL_TREE);
   11310              : 
   11311        44670 :   return grpmap;
   11312              : }
   11313              : 
   11314              : /* Rebuild group map from partially-processed clause list (during
   11315              :    omp_build_struct_sibling_lists).  We have already processed nodes up until
   11316              :    a high-water mark (HWM).  This is a bit tricky because the list is being
   11317              :    reordered as it is scanned, but we know:
   11318              : 
   11319              :    1. The list after HWM has not been touched yet, so we can reindex it safely.
   11320              : 
   11321              :    2. The list before and including HWM has been altered, but remains
   11322              :       well-formed throughout the sibling-list building operation.
   11323              : 
   11324              :    so, we can do the reindex operation in two parts, on the processed and
   11325              :    then the unprocessed halves of the list.  */
   11326              : 
   11327              : static hash_map<tree_operand_hash_no_se, omp_mapping_group *> *
   11328          318 : omp_reindex_mapping_groups (tree *list_p,
   11329              :                             vec<omp_mapping_group> *groups,
   11330              :                             vec<omp_mapping_group> *processed_groups,
   11331              :                             tree sentinel)
   11332              : {
   11333          318 :   hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap
   11334          318 :     = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>;
   11335              : 
   11336          318 :   processed_groups->truncate (0);
   11337              : 
   11338          318 :   omp_gather_mapping_groups_1 (list_p, processed_groups, sentinel);
   11339          318 :   omp_index_mapping_groups_1 (grpmap, processed_groups, NULL_TREE);
   11340          318 :   if (sentinel)
   11341          166 :     omp_index_mapping_groups_1 (grpmap, groups, sentinel);
   11342              : 
   11343          318 :   return grpmap;
   11344              : }
   11345              : 
   11346              : /* Find the immediately-containing struct for a component ref (etc.)
   11347              :    expression EXPR.  */
   11348              : 
   11349              : static tree
   11350        47979 : omp_containing_struct (tree expr)
   11351              : {
   11352        47979 :   tree expr0 = expr;
   11353              : 
   11354        47979 :   STRIP_NOPS (expr);
   11355              : 
   11356              :   /* Note: don't strip NOPs unless we're also stripping off array refs or a
   11357              :      component ref.  */
   11358        47979 :   if (TREE_CODE (expr) != ARRAY_REF && TREE_CODE (expr) != COMPONENT_REF)
   11359              :     return expr0;
   11360              : 
   11361        27222 :   while (TREE_CODE (expr) == ARRAY_REF)
   11362         3675 :     expr = TREE_OPERAND (expr, 0);
   11363              : 
   11364        23547 :   if (TREE_CODE (expr) == COMPONENT_REF)
   11365        21093 :     expr = TREE_OPERAND (expr, 0);
   11366              : 
   11367              :   return expr;
   11368              : }
   11369              : 
   11370              : /* Return TRUE if DECL describes a component that is part of a whole structure
   11371              :    that is mapped elsewhere in GRPMAP.  *MAPPED_BY_GROUP is set to the group
   11372              :    that maps that structure, if present.  */
   11373              : 
   11374              : static bool
   11375        25671 : omp_mapped_by_containing_struct (hash_map<tree_operand_hash_no_se,
   11376              :                                           omp_mapping_group *> *grpmap,
   11377              :                                  tree decl,
   11378              :                                  omp_mapping_group **mapped_by_group)
   11379              : {
   11380        25671 :   tree wsdecl = NULL_TREE;
   11381              : 
   11382        25671 :   *mapped_by_group = NULL;
   11383              : 
   11384        47979 :   while (true)
   11385              :     {
   11386        47979 :       wsdecl = omp_containing_struct (decl);
   11387        47979 :       if (wsdecl == decl)
   11388              :         break;
   11389        23547 :       omp_mapping_group **wholestruct = grpmap->get (wsdecl);
   11390        23547 :       if (!wholestruct
   11391        20978 :           && TREE_CODE (wsdecl) == MEM_REF
   11392        23548 :           && integer_zerop (TREE_OPERAND (wsdecl, 1)))
   11393              :         {
   11394            1 :           tree deref = TREE_OPERAND (wsdecl, 0);
   11395            1 :           deref = build_fold_indirect_ref (deref);
   11396            1 :           wholestruct = grpmap->get (deref);
   11397              :         }
   11398        23547 :       if (wholestruct)
   11399              :         {
   11400              :           /* An intermediate descriptor should not match here because the
   11401              :              pointee is actually not mapped by this group -- it is just a
   11402              :              zero-length alloc.  */
   11403         2569 :           tree desc = OMP_CLAUSE_CHAIN (*(*wholestruct)->grp_start);
   11404         2569 :           if (desc != NULL_TREE && omp_map_clause_descriptor_p (desc))
   11405         1330 :             goto next;
   11406         1239 :           *mapped_by_group = *wholestruct;
   11407         1239 :           return true;
   11408              :         }
   11409        20978 :     next:
   11410              :       decl = wsdecl;
   11411              :     }
   11412              : 
   11413              :   return false;
   11414              : }
   11415              : 
   11416              : /* Helper function for omp_tsort_mapping_groups.  Returns TRUE on success, or
   11417              :    FALSE on error.  */
   11418              : 
   11419              : static bool
   11420        20147 : omp_tsort_mapping_groups_1 (omp_mapping_group ***outlist,
   11421              :                             vec<omp_mapping_group> *groups,
   11422              :                             hash_map<tree_operand_hash_no_se,
   11423              :                                      omp_mapping_group *> *grpmap,
   11424              :                             omp_mapping_group *grp)
   11425              : {
   11426        20147 :   if (grp->mark == PERMANENT)
   11427              :     return true;
   11428        16811 :   if (grp->mark == TEMPORARY)
   11429              :     {
   11430            0 :       fprintf (stderr, "when processing group:\n");
   11431            0 :       debug_mapping_group (grp);
   11432            0 :       internal_error ("base pointer cycle detected");
   11433              :       return false;
   11434              :     }
   11435        16811 :   grp->mark = TEMPORARY;
   11436              : 
   11437        16811 :   tree attaches_to = omp_get_attachment (grp);
   11438              : 
   11439        16811 :   if (attaches_to)
   11440              :     {
   11441         3091 :       omp_mapping_group **basep = grpmap->get (attaches_to);
   11442              : 
   11443         3091 :       if (basep && *basep != grp)
   11444              :         {
   11445         2920 :           for (omp_mapping_group *w = *basep; w; w = w->sibling)
   11446         1460 :             if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w))
   11447              :               return false;
   11448              :         }
   11449              :     }
   11450              : 
   11451        16811 :   tree decl = OMP_CLAUSE_DECL (*grp->grp_start);
   11452              : 
   11453        23025 :   while (decl)
   11454              :     {
   11455        23025 :       tree base = omp_get_base_pointer (decl);
   11456              : 
   11457        23025 :       if (!base)
   11458              :         break;
   11459              : 
   11460         8974 :       omp_mapping_group **innerp = grpmap->get (base);
   11461         8974 :       omp_mapping_group *wholestruct;
   11462              : 
   11463              :       /* We should treat whole-structure mappings as if all (pointer, in this
   11464              :          case) members are mapped as individual list items.  Check if we have
   11465              :          such a whole-structure mapping, if we don't have an explicit reference
   11466              :          to the pointer member itself.  */
   11467         8974 :       if (!innerp
   11468         4165 :           && TREE_CODE (base) == COMPONENT_REF
   11469        11205 :           && omp_mapped_by_containing_struct (grpmap, base, &wholestruct))
   11470              :         innerp = &wholestruct;
   11471              : 
   11472         8974 :       if (innerp && *innerp != grp)
   11473              :         {
   11474         5532 :           for (omp_mapping_group *w = *innerp; w; w = w->sibling)
   11475         2772 :             if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w))
   11476            0 :               return false;
   11477              :           break;
   11478              :         }
   11479              : 
   11480         6214 :       decl = base;
   11481              :     }
   11482              : 
   11483        16811 :   grp->mark = PERMANENT;
   11484              : 
   11485              :   /* Emit grp to output list.  */
   11486              : 
   11487        16811 :   **outlist = grp;
   11488        16811 :   *outlist = &grp->next;
   11489              : 
   11490        16811 :   return true;
   11491              : }
   11492              : 
   11493              : /* Topologically sort GROUPS, so that OMP 5.0-defined base pointers come
   11494              :    before mappings that use those pointers.  This is an implementation of the
   11495              :    depth-first search algorithm, described e.g. at:
   11496              : 
   11497              :      https://en.wikipedia.org/wiki/Topological_sorting
   11498              : */
   11499              : 
   11500              : static omp_mapping_group *
   11501         8515 : omp_tsort_mapping_groups (vec<omp_mapping_group> *groups,
   11502              :                           hash_map<tree_operand_hash_no_se, omp_mapping_group *>
   11503              :                             *grpmap,
   11504              :                           bool enter_exit_data)
   11505              : {
   11506         8515 :   omp_mapping_group *grp, *outlist = NULL, **cursor;
   11507         8515 :   unsigned int i;
   11508         8515 :   bool saw_runtime_implicit = false;
   11509              : 
   11510         8515 :   cursor = &outlist;
   11511              : 
   11512        25326 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   11513              :     {
   11514        16811 :       if (grp->mark != PERMANENT)
   11515              :         {
   11516        15939 :           if (OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start))
   11517              :             {
   11518          683 :               saw_runtime_implicit = true;
   11519          683 :               continue;
   11520              :             }
   11521        15256 :           if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp))
   11522              :             return NULL;
   11523              :         }
   11524              :     }
   11525              : 
   11526         8515 :   if (!saw_runtime_implicit)
   11527         8233 :     return outlist;
   11528              : 
   11529         1634 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   11530              :     {
   11531         1352 :       if (grp->mark != PERMANENT
   11532         1352 :           && OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start))
   11533              :         {
   11534              :           /* Clear the flag for enter/exit data because it is currently
   11535              :              meaningless for those operations in libgomp.  */
   11536          659 :           if (enter_exit_data)
   11537          446 :             OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start) = 0;
   11538              : 
   11539          659 :           if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp))
   11540              :             return NULL;
   11541              :         }
   11542              :     }
   11543              : 
   11544          282 :   return outlist;
   11545              : }
   11546              : 
   11547              : /* Split INLIST into three parts:
   11548              : 
   11549              :      - "present" alloc/to/from groups
   11550              :      - other to/from groups
   11551              :      - other alloc/release/delete groups
   11552              : 
   11553              :    These sub-lists are then concatenated together to form the final list.
   11554              :    Each sub-list retains the order of the original list.
   11555              :    Note that ATTACH nodes are later moved to the end of the list in
   11556              :    gimplify_adjust_omp_clauses, for target regions.  */
   11557              : 
   11558              : static omp_mapping_group *
   11559         8515 : omp_segregate_mapping_groups (omp_mapping_group *inlist)
   11560              : {
   11561         8515 :   omp_mapping_group *ard_groups = NULL, *tf_groups = NULL;
   11562         8515 :   omp_mapping_group *p_groups = NULL;
   11563         8515 :   omp_mapping_group **ard_tail = &ard_groups, **tf_tail = &tf_groups;
   11564         8515 :   omp_mapping_group **p_tail = &p_groups;
   11565              : 
   11566        25326 :   for (omp_mapping_group *w = inlist; w;)
   11567              :     {
   11568        16811 :       tree c = *w->grp_start;
   11569        16811 :       omp_mapping_group *next = w->next;
   11570              : 
   11571        16811 :       gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP);
   11572              : 
   11573        16811 :       switch (OMP_CLAUSE_MAP_KIND (c))
   11574              :         {
   11575         1939 :         case GOMP_MAP_ALLOC:
   11576         1939 :         case GOMP_MAP_RELEASE:
   11577         1939 :         case GOMP_MAP_DELETE:
   11578         1939 :           *ard_tail = w;
   11579         1939 :           w->next = NULL;
   11580         1939 :           ard_tail = &w->next;
   11581         1939 :           break;
   11582              : 
   11583              :         /* These map types are all semantically identical, so are moved into a
   11584              :            single group.  They will each be changed into GOMP_MAP_FORCE_PRESENT
   11585              :            in gimplify_adjust_omp_clauses.  */
   11586          149 :         case GOMP_MAP_PRESENT_ALLOC:
   11587          149 :         case GOMP_MAP_PRESENT_FROM:
   11588          149 :         case GOMP_MAP_PRESENT_TO:
   11589          149 :         case GOMP_MAP_PRESENT_TOFROM:
   11590          149 :           *p_tail = w;
   11591          149 :           w->next = NULL;
   11592          149 :           p_tail = &w->next;
   11593          149 :           break;
   11594              : 
   11595        14723 :         default:
   11596        14723 :           *tf_tail = w;
   11597        14723 :           w->next = NULL;
   11598        14723 :           tf_tail = &w->next;
   11599              :         }
   11600              : 
   11601              :       w = next;
   11602              :     }
   11603              : 
   11604              :   /* Now splice the lists together...  */
   11605         8515 :   *tf_tail = ard_groups;
   11606         8515 :   *p_tail = tf_groups;
   11607              : 
   11608         8515 :   return p_groups;
   11609              : }
   11610              : 
   11611              : /* Given a list LIST_P containing groups of mappings given by GROUPS, reorder
   11612              :    those groups based on the output list of omp_tsort_mapping_groups --
   11613              :    singly-linked, threaded through each element's NEXT pointer starting at
   11614              :    HEAD.  Each list element appears exactly once in that linked list.
   11615              : 
   11616              :    Each element of GROUPS may correspond to one or several mapping nodes.
   11617              :    Node groups are kept together, and in the reordered list, the positions of
   11618              :    the original groups are reused for the positions of the reordered list.
   11619              :    Hence if we have e.g.
   11620              : 
   11621              :      {to ptr ptr} firstprivate {tofrom ptr} ...
   11622              :       ^             ^           ^
   11623              :       first group  non-"map"    second group
   11624              : 
   11625              :    and say the second group contains a base pointer for the first so must be
   11626              :    moved before it, the resulting list will contain:
   11627              : 
   11628              :      {tofrom ptr} firstprivate {to ptr ptr} ...
   11629              :       ^ prev. second group      ^ prev. first group
   11630              : */
   11631              : 
   11632              : static tree *
   11633         8515 : omp_reorder_mapping_groups (vec<omp_mapping_group> *groups,
   11634              :                             omp_mapping_group *head,
   11635              :                             tree *list_p)
   11636              : {
   11637         8515 :   omp_mapping_group *grp;
   11638         8515 :   unsigned int i;
   11639         8515 :   unsigned numgroups = groups->length ();
   11640         8515 :   auto_vec<tree> old_heads (numgroups);
   11641         8515 :   auto_vec<tree *> old_headps (numgroups);
   11642         8515 :   auto_vec<tree> new_heads (numgroups);
   11643         8515 :   auto_vec<tree> old_succs (numgroups);
   11644         8515 :   bool map_at_start = (list_p == (*groups)[0].grp_start);
   11645              : 
   11646         8515 :   tree *new_grp_tail = NULL;
   11647              : 
   11648              :   /* Stash the start & end nodes of each mapping group before we start
   11649              :      modifying the list.  */
   11650        25326 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   11651              :     {
   11652        16811 :       old_headps.quick_push (grp->grp_start);
   11653        16811 :       old_heads.quick_push (*grp->grp_start);
   11654        16811 :       old_succs.quick_push (OMP_CLAUSE_CHAIN (grp->grp_end));
   11655              :     }
   11656              : 
   11657              :   /* And similarly, the heads of the groups in the order we want to rearrange
   11658              :      the list to.  */
   11659        25326 :   for (omp_mapping_group *w = head; w; w = w->next)
   11660        16811 :     new_heads.quick_push (*w->grp_start);
   11661              : 
   11662        25326 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   11663              :     {
   11664        16811 :       gcc_assert (head);
   11665              : 
   11666        16811 :       if (new_grp_tail && old_succs[i - 1] == old_heads[i])
   11667              :         {
   11668              :           /* a {b c d} {e f g} h i j   (original)
   11669              :              -->
   11670              :              a {k l m} {e f g} h i j   (inserted new group on last iter)
   11671              :              -->
   11672              :              a {k l m} {n o p} h i j   (this time, chain last group to new one)
   11673              :                       ^new_grp_tail
   11674              :           */
   11675         7674 :           *new_grp_tail = new_heads[i];
   11676              :         }
   11677         9137 :       else if (new_grp_tail)
   11678              :         {
   11679              :           /* a {b c d} e {f g h} i j k   (original)
   11680              :              -->
   11681              :              a {l m n} e {f g h} i j k   (gap after last iter's group)
   11682              :              -->
   11683              :              a {l m n} e {o p q} h i j   (chain last group to old successor)
   11684              :                       ^new_grp_tail
   11685              :            */
   11686          622 :           *new_grp_tail = old_succs[i - 1];
   11687          622 :           *old_headps[i] = new_heads[i];
   11688              :         }
   11689              :       else
   11690              :         {
   11691              :           /* The first inserted group -- point to new group, and leave end
   11692              :              open.
   11693              :              a {b c d} e f
   11694              :              -->
   11695              :              a {g h i...
   11696              :           */
   11697         8515 :           *grp->grp_start = new_heads[i];
   11698              :         }
   11699              : 
   11700        16811 :       new_grp_tail = &OMP_CLAUSE_CHAIN (head->grp_end);
   11701              : 
   11702        16811 :       head = head->next;
   11703              :     }
   11704              : 
   11705         8515 :   if (new_grp_tail)
   11706         8515 :     *new_grp_tail = old_succs[numgroups - 1];
   11707              : 
   11708         8515 :   gcc_assert (!head);
   11709              : 
   11710        11909 :   return map_at_start ? (*groups)[0].grp_start : list_p;
   11711         8515 : }
   11712              : 
   11713              : /* DECL is supposed to have lastprivate semantics in the outer contexts
   11714              :    of combined/composite constructs, starting with OCTX.
   11715              :    Add needed lastprivate, shared or map clause if no data sharing or
   11716              :    mapping clause are present.  IMPLICIT_P is true if it is an implicit
   11717              :    clause (IV on simd), in which case the lastprivate will not be
   11718              :    copied to some constructs.  */
   11719              : 
   11720              : static void
   11721        14652 : omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
   11722              :                                                tree decl, bool implicit_p)
   11723              : {
   11724        14652 :   struct gimplify_omp_ctx *orig_octx = octx;
   11725        26973 :   for (; octx; octx = octx->outer_context)
   11726              :     {
   11727        25900 :       if ((octx->region_type == ORT_COMBINED_PARALLEL
   11728        20864 :            || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
   11729        25331 :           && splay_tree_lookup (octx->variables,
   11730              :                                 (splay_tree_key) decl) == NULL)
   11731              :         {
   11732         3887 :           omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
   11733         3887 :           continue;
   11734              :         }
   11735        18374 :       if ((octx->region_type & ORT_TASK) != 0
   11736          575 :           && octx->combined_loop
   11737        18655 :           && splay_tree_lookup (octx->variables,
   11738              :                                 (splay_tree_key) decl) == NULL)
   11739              :         {
   11740          248 :           omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
   11741          248 :           continue;
   11742              :         }
   11743        22710 :       if (implicit_p
   11744        13619 :           && octx->region_type == ORT_WORKSHARE
   11745        10405 :           && octx->combined_loop
   11746        10300 :           && splay_tree_lookup (octx->variables,
   11747              :                                 (splay_tree_key) decl) == NULL
   11748        10300 :           && octx->outer_context
   11749         8907 :           && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
   11750        22717 :           && splay_tree_lookup (octx->outer_context->variables,
   11751              :                                 (splay_tree_key) decl) == NULL)
   11752              :         {
   11753         4832 :           octx = octx->outer_context;
   11754         4832 :           omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
   11755         4832 :           continue;
   11756              :         }
   11757         5564 :       if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
   11758         7482 :           && octx->combined_loop
   11759         7295 :           && splay_tree_lookup (octx->variables,
   11760              :                                 (splay_tree_key) decl) == NULL
   11761        19071 :           && !omp_check_private (octx, decl, false))
   11762              :         {
   11763         3354 :           omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
   11764         3354 :           continue;
   11765              :         }
   11766         9692 :       if (octx->region_type == ORT_COMBINED_TARGET)
   11767              :         {
   11768         2008 :           splay_tree_node n = splay_tree_lookup (octx->variables,
   11769              :                                                  (splay_tree_key) decl);
   11770         2008 :           if (n == NULL)
   11771              :             {
   11772         1986 :               omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
   11773         1986 :               octx = octx->outer_context;
   11774              :             }
   11775           22 :           else if (!implicit_p
   11776           22 :                    && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
   11777              :             {
   11778           12 :               n->value &= ~(GOVD_FIRSTPRIVATE
   11779              :                             | GOVD_FIRSTPRIVATE_IMPLICIT
   11780              :                             | GOVD_EXPLICIT);
   11781           12 :               omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
   11782           12 :               octx = octx->outer_context;
   11783              :             }
   11784              :         }
   11785              :       break;
   11786              :     }
   11787        14652 :   if (octx && (implicit_p || octx != orig_octx))
   11788         4046 :     omp_notice_variable (octx, decl, true);
   11789        14652 : }
   11790              : 
   11791              : /* We might have indexed several groups for DECL, e.g. a "TO" mapping and also
   11792              :    a "FIRSTPRIVATE" mapping.  Return the one that isn't firstprivate, etc.  */
   11793              : 
   11794              : static omp_mapping_group *
   11795         5977 : omp_get_nonfirstprivate_group (hash_map<tree_operand_hash_no_se,
   11796              :                                         omp_mapping_group *> *grpmap,
   11797              :                                tree decl, bool allow_deleted = false)
   11798              : {
   11799         5977 :   omp_mapping_group **to_group_p = grpmap->get (decl);
   11800              : 
   11801         5977 :   if (!to_group_p)
   11802              :     return NULL;
   11803              : 
   11804         2449 :   omp_mapping_group *to_group = *to_group_p;
   11805              : 
   11806         3776 :   for (; to_group; to_group = to_group->sibling)
   11807              :     {
   11808         2486 :       tree grp_end = to_group->grp_end;
   11809         2486 :       switch (OMP_CLAUSE_MAP_KIND (grp_end))
   11810              :         {
   11811              :         case GOMP_MAP_FIRSTPRIVATE_POINTER:
   11812              :         case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   11813              :           break;
   11814              : 
   11815         1161 :         default:
   11816         1161 :           if (allow_deleted || !to_group->deleted)
   11817              :             return to_group;
   11818              :         }
   11819              :     }
   11820              : 
   11821              :   return NULL;
   11822              : }
   11823              : 
   11824              : /* Return TRUE if the directive (whose clauses are described by the hash table
   11825              :    of mapping groups, GRPMAP) maps DECL explicitly.  If TO_SPECIFICALLY is
   11826              :    true, only count TO mappings.  If ALLOW_DELETED is true, ignore the
   11827              :    "deleted" flag for groups.  If CONTAINED_IN_STRUCT is true, also return
   11828              :    TRUE if DECL is mapped as a member of a whole-struct mapping.  */
   11829              : 
   11830              : static bool
   11831         4445 : omp_directive_maps_explicitly (hash_map<tree_operand_hash_no_se,
   11832              :                                         omp_mapping_group *> *grpmap,
   11833              :                                tree decl, omp_mapping_group **base_group,
   11834              :                                bool to_specifically, bool allow_deleted,
   11835              :                                bool contained_in_struct)
   11836              : {
   11837         4445 :   omp_mapping_group *decl_group
   11838         4445 :     = omp_get_nonfirstprivate_group (grpmap, decl, allow_deleted);
   11839              : 
   11840         4445 :   *base_group = NULL;
   11841              : 
   11842         4445 :   if (decl_group)
   11843              :     {
   11844         1042 :       tree grp_first = *decl_group->grp_start;
   11845              :       /* We might be called during omp_build_struct_sibling_lists, when
   11846              :          GOMP_MAP_STRUCT might have been inserted at the start of the group.
   11847              :          Skip over that, and also possibly the node after it.  */
   11848         1042 :       if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT
   11849         1042 :           || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT_UNORD)
   11850              :         {
   11851            6 :           grp_first = OMP_CLAUSE_CHAIN (grp_first);
   11852            6 :           if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_FIRSTPRIVATE_POINTER
   11853            6 :               || (OMP_CLAUSE_MAP_KIND (grp_first)
   11854              :                   == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   11855           12 :               || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_ATTACH_DETACH)
   11856            0 :             grp_first = OMP_CLAUSE_CHAIN (grp_first);
   11857              :         }
   11858         1042 :       enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
   11859         1042 :       if (!to_specifically
   11860          592 :           || GOMP_MAP_COPY_TO_P (first_kind)
   11861          382 :           || first_kind == GOMP_MAP_ALLOC)
   11862              :         {
   11863          960 :           *base_group = decl_group;
   11864          960 :           return true;
   11865              :         }
   11866              :     }
   11867              : 
   11868         3485 :   if (contained_in_struct
   11869         3485 :       && omp_mapped_by_containing_struct (grpmap, decl, base_group))
   11870              :     return true;
   11871              : 
   11872              :   return false;
   11873              : }
   11874              : 
   11875              : /* If we have mappings INNER and OUTER, where INNER is a component access and
   11876              :    OUTER is a mapping of the whole containing struct, check that the mappings
   11877              :    are compatible.  We'll be deleting the inner mapping, so we need to make
   11878              :    sure the outer mapping does (at least) the same transfers to/from the device
   11879              :    as the inner mapping.  */
   11880              : 
   11881              : bool
   11882          172 : omp_check_mapping_compatibility (location_t loc,
   11883              :                                  omp_mapping_group *outer,
   11884              :                                  omp_mapping_group *inner)
   11885              : {
   11886          172 :   tree first_outer = *outer->grp_start, first_inner = *inner->grp_start;
   11887              : 
   11888          172 :   gcc_assert (OMP_CLAUSE_CODE (first_outer) == OMP_CLAUSE_MAP);
   11889          172 :   gcc_assert (OMP_CLAUSE_CODE (first_inner) == OMP_CLAUSE_MAP);
   11890              : 
   11891          172 :   enum gomp_map_kind outer_kind = OMP_CLAUSE_MAP_KIND (first_outer);
   11892          172 :   enum gomp_map_kind inner_kind = OMP_CLAUSE_MAP_KIND (first_inner);
   11893              : 
   11894          172 :   if (outer_kind == inner_kind)
   11895              :     return true;
   11896              : 
   11897           70 :   switch (outer_kind)
   11898              :     {
   11899            0 :     case GOMP_MAP_ALWAYS_TO:
   11900            0 :       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   11901            0 :           || inner_kind == GOMP_MAP_ALLOC
   11902            0 :           || inner_kind == GOMP_MAP_TO)
   11903              :         return true;
   11904              :       break;
   11905              : 
   11906            0 :     case GOMP_MAP_ALWAYS_FROM:
   11907            0 :       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   11908            0 :           || inner_kind == GOMP_MAP_RELEASE
   11909              :           || inner_kind == GOMP_MAP_FROM)
   11910              :         return true;
   11911              :       break;
   11912              : 
   11913           10 :     case GOMP_MAP_TO:
   11914           10 :       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   11915           10 :           || inner_kind == GOMP_MAP_ALLOC)
   11916              :         return true;
   11917              :       break;
   11918              : 
   11919            8 :     case GOMP_MAP_FROM:
   11920            8 :       if (inner_kind == GOMP_MAP_RELEASE
   11921            8 :           || inner_kind == GOMP_MAP_FORCE_PRESENT)
   11922              :         return true;
   11923              :       break;
   11924              : 
   11925           32 :     case GOMP_MAP_ALWAYS_TOFROM:
   11926           32 :     case GOMP_MAP_TOFROM:
   11927           32 :       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   11928           32 :           || inner_kind == GOMP_MAP_ALLOC
   11929              :           || inner_kind == GOMP_MAP_TO
   11930           24 :           || inner_kind == GOMP_MAP_FROM
   11931           12 :           || inner_kind == GOMP_MAP_TOFROM)
   11932              :         return true;
   11933              :       break;
   11934              : 
   11935           28 :     default:
   11936           28 :       ;
   11937              :     }
   11938              : 
   11939           84 :   error_at (loc, "data movement for component %qE is not compatible with "
   11940           28 :             "movement for struct %qE", OMP_CLAUSE_DECL (first_inner),
   11941           28 :             OMP_CLAUSE_DECL (first_outer));
   11942              : 
   11943           28 :   return false;
   11944              : }
   11945              : 
   11946              : /* This function handles several cases where clauses on a mapping directive
   11947              :    can interact with each other.
   11948              : 
   11949              :    If we have a FIRSTPRIVATE_POINTER node and we're also mapping the pointer
   11950              :    on the same directive, change the mapping of the first node to
   11951              :    ATTACH_DETACH.  We should have detected that this will happen already in
   11952              :    c-omp.cc:c_omp_adjust_map_clauses and marked the appropriate decl
   11953              :    as addressable.  (If we didn't, bail out.)
   11954              : 
   11955              :    If we have a FIRSTPRIVATE_REFERENCE (for a reference to pointer) and we're
   11956              :    mapping the base pointer also, we may need to change the mapping type to
   11957              :    ATTACH_DETACH and synthesize an alloc node for the reference itself.
   11958              : 
   11959              :    If we have an ATTACH_DETACH node, this is an array section with a pointer
   11960              :    base.  If we're mapping the base on the same directive too, we can drop its
   11961              :    mapping.  However, if we have a reference to pointer, make other appropriate
   11962              :    adjustments to the mapping nodes instead.
   11963              : 
   11964              :    If we have an ATTACH_DETACH node with a Fortran pointer-set (array
   11965              :    descriptor) mapping for a derived-type component, and we're also mapping the
   11966              :    whole of the derived-type variable on another clause, the pointer-set
   11967              :    mapping is removed.
   11968              : 
   11969              :    If we have a component access but we're also mapping the whole of the
   11970              :    containing struct, drop the former access.
   11971              : 
   11972              :    If the expression is a component access, and we're also mapping a base
   11973              :    pointer used in that component access in the same expression, change the
   11974              :    mapping type of the latter to ALLOC (ready for processing by
   11975              :    omp_build_struct_sibling_lists).  */
   11976              : 
   11977              : void
   11978         8515 : omp_resolve_clause_dependencies (enum tree_code code,
   11979              :                                  vec<omp_mapping_group> *groups,
   11980              :                                  hash_map<tree_operand_hash_no_se,
   11981              :                                           omp_mapping_group *> *grpmap)
   11982              : {
   11983         8515 :   int i;
   11984         8515 :   omp_mapping_group *grp;
   11985         8515 :   bool repair_chain = false;
   11986              : 
   11987        24262 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   11988              :     {
   11989        15747 :       tree grp_end = grp->grp_end;
   11990        15747 :       tree decl = OMP_CLAUSE_DECL (grp_end);
   11991              : 
   11992        15747 :       gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP);
   11993              : 
   11994        15747 :       switch (OMP_CLAUSE_MAP_KIND (grp_end))
   11995              :         {
   11996         1216 :         case GOMP_MAP_FIRSTPRIVATE_POINTER:
   11997         1216 :           {
   11998         1216 :             omp_mapping_group *to_group
   11999         1216 :               = omp_get_nonfirstprivate_group (grpmap, decl);
   12000              : 
   12001         1216 :             if (!to_group || to_group == grp)
   12002         1191 :               continue;
   12003              : 
   12004           25 :             tree grp_first = *to_group->grp_start;
   12005           25 :             enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
   12006              : 
   12007           25 :             if ((GOMP_MAP_COPY_TO_P (first_kind)
   12008            7 :                  || first_kind == GOMP_MAP_ALLOC)
   12009           50 :                 && (OMP_CLAUSE_MAP_KIND (to_group->grp_end)
   12010              :                     != GOMP_MAP_FIRSTPRIVATE_POINTER))
   12011              :               {
   12012           25 :                 gcc_assert (TREE_ADDRESSABLE (OMP_CLAUSE_DECL (grp_end)));
   12013           25 :                 OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH);
   12014              :               }
   12015              :           }
   12016              :           break;
   12017              : 
   12018          160 :         case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   12019          160 :           {
   12020          160 :             tree ptr = build_fold_indirect_ref (decl);
   12021              : 
   12022          160 :             omp_mapping_group *to_group
   12023          160 :               = omp_get_nonfirstprivate_group (grpmap, ptr);
   12024              : 
   12025          160 :             if (!to_group || to_group == grp)
   12026          156 :               continue;
   12027              : 
   12028            4 :             tree grp_first = *to_group->grp_start;
   12029            4 :             enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
   12030              : 
   12031            4 :             if (GOMP_MAP_COPY_TO_P (first_kind)
   12032            4 :                 || first_kind == GOMP_MAP_ALLOC)
   12033              :               {
   12034            4 :                 OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH);
   12035            4 :                 OMP_CLAUSE_DECL (grp_end) = ptr;
   12036            4 :                 if ((OMP_CLAUSE_CHAIN (*to_group->grp_start)
   12037            4 :                      == to_group->grp_end)
   12038            4 :                     && (OMP_CLAUSE_MAP_KIND (to_group->grp_end)
   12039              :                         == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   12040              :                   {
   12041            0 :                     gcc_assert (TREE_ADDRESSABLE
   12042              :                                   (OMP_CLAUSE_DECL (to_group->grp_end)));
   12043            0 :                     OMP_CLAUSE_SET_MAP_KIND (to_group->grp_end,
   12044              :                                              GOMP_MAP_ATTACH_DETACH);
   12045              : 
   12046            0 :                     location_t loc = OMP_CLAUSE_LOCATION (to_group->grp_end);
   12047            0 :                     tree alloc
   12048            0 :                       = build_omp_clause (loc, OMP_CLAUSE_MAP);
   12049            0 :                     OMP_CLAUSE_SET_MAP_KIND (alloc, GOMP_MAP_ALLOC);
   12050            0 :                     tree tmp = build_fold_addr_expr (OMP_CLAUSE_DECL
   12051              :                                                       (to_group->grp_end));
   12052            0 :                     tree char_ptr_type = build_pointer_type (char_type_node);
   12053            0 :                     OMP_CLAUSE_DECL (alloc)
   12054            0 :                       = build2 (MEM_REF, char_type_node,
   12055              :                                 tmp,
   12056              :                                 build_int_cst (char_ptr_type, 0));
   12057            0 :                     OMP_CLAUSE_SIZE (alloc) = TYPE_SIZE_UNIT (TREE_TYPE (tmp));
   12058              : 
   12059            0 :                     OMP_CLAUSE_CHAIN (alloc)
   12060            0 :                       = OMP_CLAUSE_CHAIN (*to_group->grp_start);
   12061            0 :                     OMP_CLAUSE_CHAIN (*to_group->grp_start) = alloc;
   12062              :                   }
   12063              :               }
   12064              :           }
   12065              :           break;
   12066              : 
   12067              :         case GOMP_MAP_ATTACH_DETACH:
   12068              :         case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   12069              :           {
   12070         2621 :             tree base_ptr, referenced_ptr_node = NULL_TREE;
   12071              : 
   12072         2621 :             while (TREE_CODE (decl) == ARRAY_REF)
   12073            0 :               decl = TREE_OPERAND (decl, 0);
   12074              : 
   12075         2621 :             if (TREE_CODE (decl) == INDIRECT_REF)
   12076           13 :               decl = TREE_OPERAND (decl, 0);
   12077              : 
   12078              :             /* Only component accesses.  */
   12079         2621 :             if (DECL_P (decl))
   12080          226 :               continue;
   12081              : 
   12082              :             /* We want the pointer itself when checking if the base pointer is
   12083              :                mapped elsewhere in the same directive -- if we have a
   12084              :                reference to the pointer, don't use that.  */
   12085              : 
   12086         2395 :             if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   12087         2395 :                 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
   12088              :               {
   12089          394 :                 referenced_ptr_node = OMP_CLAUSE_CHAIN (*grp->grp_start);
   12090          394 :                 base_ptr = OMP_CLAUSE_DECL (referenced_ptr_node);
   12091              :               }
   12092              :             else
   12093              :               base_ptr = decl;
   12094              : 
   12095         1977 :             gomp_map_kind zlas_kind
   12096         2395 :               = (code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
   12097         2395 :                 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION;
   12098              : 
   12099         2395 :             if (TREE_CODE (TREE_TYPE (base_ptr)) == POINTER_TYPE)
   12100              :               {
   12101              :                 /* If we map the base TO, and we're doing an attachment, we can
   12102              :                    skip the TO mapping altogether and create an ALLOC mapping
   12103              :                    instead, since the attachment will overwrite the device
   12104              :                    pointer in that location immediately anyway.  Otherwise,
   12105              :                    change our mapping to
   12106              :                    GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION in case the
   12107              :                    attachment target has not been copied to the device already
   12108              :                    by some earlier directive.  */
   12109              : 
   12110         1971 :                 bool base_mapped_to = false;
   12111              : 
   12112         1971 :                 omp_mapping_group *base_group;
   12113              : 
   12114         1971 :                 if (omp_directive_maps_explicitly (grpmap, base_ptr,
   12115              :                                                    &base_group, false, true,
   12116              :                                                    false))
   12117              :                   {
   12118          450 :                     if (referenced_ptr_node)
   12119              :                       {
   12120          129 :                         base_mapped_to = true;
   12121          129 :                         if ((OMP_CLAUSE_MAP_KIND (base_group->grp_end)
   12122              :                              == GOMP_MAP_ATTACH_DETACH)
   12123          129 :                             && (OMP_CLAUSE_CHAIN (*base_group->grp_start)
   12124              :                                 == base_group->grp_end))
   12125              :                           {
   12126          258 :                             OMP_CLAUSE_CHAIN (*base_group->grp_start)
   12127          129 :                               = OMP_CLAUSE_CHAIN (base_group->grp_end);
   12128          129 :                             base_group->grp_end = *base_group->grp_start;
   12129          129 :                             repair_chain = true;
   12130              :                           }
   12131              :                       }
   12132              :                     else
   12133              :                       {
   12134          321 :                         base_group->deleted = true;
   12135          321 :                         OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end) = 1;
   12136              :                       }
   12137              :                   }
   12138              : 
   12139              :                 /* We're dealing with a reference to a pointer, and we are
   12140              :                    attaching both the reference and the pointer.  We know the
   12141              :                    reference itself is on the target, because we are going to
   12142              :                    create an ALLOC node for it in accumulate_sibling_list.  The
   12143              :                    pointer might be on the target already or it might not, but
   12144              :                    if it isn't then it's not an error, so use
   12145              :                    GOMP_MAP_ATTACH_ZLAS for it.  */
   12146         1971 :                 if (!base_mapped_to && referenced_ptr_node)
   12147           56 :                   OMP_CLAUSE_SET_MAP_KIND (referenced_ptr_node, zlas_kind);
   12148              : 
   12149         1971 :                 omp_mapping_group *struct_group;
   12150         1971 :                 tree desc;
   12151         1971 :                 if ((desc = OMP_CLAUSE_CHAIN (*grp->grp_start))
   12152         1971 :                     && omp_map_clause_descriptor_p (desc)
   12153         3049 :                     && omp_mapped_by_containing_struct (grpmap, decl,
   12154              :                                                         &struct_group))
   12155              :                   /* If we have a pointer set but we're mapping (or unmapping)
   12156              :                      the whole of the containing struct, we can remove the
   12157              :                      pointer set mapping.  */
   12158           15 :                   OMP_CLAUSE_CHAIN (*grp->grp_start) = OMP_CLAUSE_CHAIN (desc);
   12159              :               }
   12160          424 :             else if (TREE_CODE (TREE_TYPE (base_ptr)) == REFERENCE_TYPE
   12161          424 :                      && (TREE_CODE (TREE_TYPE (TREE_TYPE (base_ptr)))
   12162              :                          == ARRAY_TYPE)
   12163          562 :                      && OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION
   12164              :                           (*grp->grp_start))
   12165           92 :               OMP_CLAUSE_SET_MAP_KIND (grp->grp_end, zlas_kind);
   12166              :           }
   12167              :           break;
   12168              : 
   12169              :         case GOMP_MAP_ATTACH:
   12170              :           /* Ignore standalone attach here.  */
   12171              :           break;
   12172              : 
   12173        11687 :         default:
   12174        11687 :           {
   12175        11687 :             omp_mapping_group *struct_group;
   12176        11687 :             if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group)
   12177        11687 :                 && *grp->grp_start == grp_end)
   12178              :               {
   12179           94 :                 omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end),
   12180              :                                                  struct_group, grp);
   12181              :                 /* Remove the whole of this mapping -- redundant.  */
   12182           94 :                 grp->deleted = true;
   12183              :               }
   12184              : 
   12185              :             tree base = decl;
   12186        13295 :             while ((base = omp_get_base_pointer (base)))
   12187              :               {
   12188         1608 :                 omp_mapping_group *base_group;
   12189              : 
   12190         1608 :                 if (omp_directive_maps_explicitly (grpmap, base, &base_group,
   12191              :                                                    true, true, false))
   12192              :                   {
   12193          343 :                     tree grp_first = *base_group->grp_start;
   12194          343 :                     OMP_CLAUSE_SET_MAP_KIND (grp_first, GOMP_MAP_ALLOC);
   12195              :                   }
   12196              :               }
   12197              :           }
   12198              :         }
   12199              :     }
   12200              : 
   12201         8515 :   if (repair_chain)
   12202              :     {
   12203              :       /* Group start pointers may have become detached from the
   12204              :          OMP_CLAUSE_CHAIN of previous groups if elements were removed from the
   12205              :          end of those groups.  Fix that now.  */
   12206              :       tree *new_next = NULL;
   12207          716 :       FOR_EACH_VEC_ELT (*groups, i, grp)
   12208              :         {
   12209          587 :           if (new_next)
   12210          458 :             grp->grp_start = new_next;
   12211              : 
   12212          587 :           new_next = &OMP_CLAUSE_CHAIN (grp->grp_end);
   12213              :         }
   12214              :     }
   12215         8515 : }
   12216              : 
   12217              : /* Similar to omp_resolve_clause_dependencies, but for OpenACC.  The only
   12218              :    clause dependencies we handle for now are struct element mappings and
   12219              :    whole-struct mappings on the same directive, and duplicate clause
   12220              :    detection.  */
   12221              : 
   12222              : void
   12223         9462 : oacc_resolve_clause_dependencies (vec<omp_mapping_group> *groups,
   12224              :                                   hash_map<tree_operand_hash_no_se,
   12225              :                                            omp_mapping_group *> *grpmap)
   12226              : {
   12227         9462 :   int i;
   12228         9462 :   omp_mapping_group *grp;
   12229         9462 :   hash_set<tree_operand_hash> *seen_components = NULL;
   12230         9462 :   hash_set<tree_operand_hash> *shown_error = NULL;
   12231              : 
   12232        24643 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   12233              :     {
   12234        15181 :       tree grp_end = grp->grp_end;
   12235        15181 :       tree decl = OMP_CLAUSE_DECL (grp_end);
   12236              : 
   12237        15181 :       gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP);
   12238              : 
   12239        15181 :       if (DECL_P (grp_end))
   12240        14664 :         continue;
   12241              : 
   12242        15181 :       tree c = OMP_CLAUSE_DECL (*grp->grp_start);
   12243        16806 :       while (TREE_CODE (c) == ARRAY_REF)
   12244         1625 :         c = TREE_OPERAND (c, 0);
   12245        15181 :       if (TREE_CODE (c) != COMPONENT_REF)
   12246        14664 :         continue;
   12247          517 :       if (!seen_components)
   12248          474 :         seen_components = new hash_set<tree_operand_hash> ();
   12249          517 :       if (!shown_error)
   12250          474 :         shown_error = new hash_set<tree_operand_hash> ();
   12251          517 :       if (seen_components->contains (c)
   12252          517 :           && !shown_error->contains (c))
   12253              :         {
   12254           10 :           error_at (OMP_CLAUSE_LOCATION (grp_end),
   12255              :                     "%qE appears more than once in map clauses",
   12256            5 :                     OMP_CLAUSE_DECL (grp_end));
   12257            5 :           shown_error->add (c);
   12258              :         }
   12259              :       else
   12260          512 :         seen_components->add (c);
   12261              : 
   12262          517 :       omp_mapping_group *struct_group;
   12263          517 :       if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group)
   12264          517 :           && *grp->grp_start == grp_end)
   12265              :         {
   12266           78 :           omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end),
   12267              :                                            struct_group, grp);
   12268              :           /* Remove the whole of this mapping -- redundant.  */
   12269           78 :           grp->deleted = true;
   12270              :         }
   12271              :     }
   12272              : 
   12273         9462 :   if (seen_components)
   12274          474 :     delete seen_components;
   12275         9462 :   if (shown_error)
   12276          474 :     delete shown_error;
   12277         9462 : }
   12278              : 
   12279              : /* Link node NEWNODE so it is pointed to by chain INSERT_AT.  NEWNODE's chain
   12280              :    is linked to the previous node pointed to by INSERT_AT.  */
   12281              : 
   12282              : static tree *
   12283         1133 : omp_siblist_insert_node_after (tree newnode, tree *insert_at)
   12284              : {
   12285         1133 :   OMP_CLAUSE_CHAIN (newnode) = *insert_at;
   12286         1133 :   *insert_at = newnode;
   12287         1133 :   return &OMP_CLAUSE_CHAIN (newnode);
   12288              : }
   12289              : 
   12290              : /* Move NODE (which is currently pointed to by the chain OLD_POS) so it is
   12291              :    pointed to by chain MOVE_AFTER instead.  */
   12292              : 
   12293              : static void
   12294         1320 : omp_siblist_move_node_after (tree node, tree *old_pos, tree *move_after)
   12295              : {
   12296         1320 :   gcc_assert (node == *old_pos);
   12297         1320 :   *old_pos = OMP_CLAUSE_CHAIN (node);
   12298         1320 :   OMP_CLAUSE_CHAIN (node) = *move_after;
   12299         1320 :   *move_after = node;
   12300         1320 : }
   12301              : 
   12302              : /* Move nodes from FIRST_PTR (pointed to by previous node's chain) to
   12303              :    LAST_NODE to after MOVE_AFTER chain.  Similar to below function, but no
   12304              :    new nodes are prepended to the list before splicing into the new position.
   12305              :    Return the position we should continue scanning the list at, or NULL to
   12306              :    stay where we were.  */
   12307              : 
   12308              : static tree *
   12309          254 : omp_siblist_move_nodes_after (tree *first_ptr, tree last_node,
   12310              :                               tree *move_after)
   12311              : {
   12312          254 :   if (first_ptr == move_after)
   12313              :     return NULL;
   12314              : 
   12315          243 :   tree tmp = *first_ptr;
   12316          243 :   *first_ptr = OMP_CLAUSE_CHAIN (last_node);
   12317          243 :   OMP_CLAUSE_CHAIN (last_node) = *move_after;
   12318          243 :   *move_after = tmp;
   12319              : 
   12320          243 :   return first_ptr;
   12321              : }
   12322              : 
   12323              : /* Concatenate two lists described by [FIRST_NEW, LAST_NEW_TAIL] and
   12324              :    [FIRST_PTR, LAST_NODE], and insert them in the OMP clause list after chain
   12325              :    pointer MOVE_AFTER.
   12326              : 
   12327              :    The latter list was previously part of the OMP clause list, and the former
   12328              :    (prepended) part is comprised of new nodes.
   12329              : 
   12330              :    We start with a list of nodes starting with a struct mapping node.  We
   12331              :    rearrange the list so that new nodes starting from FIRST_NEW and whose last
   12332              :    node's chain is LAST_NEW_TAIL comes directly after MOVE_AFTER, followed by
   12333              :    the group of mapping nodes we are currently processing (from the chain
   12334              :    FIRST_PTR to LAST_NODE).  The return value is the pointer to the next chain
   12335              :    we should continue processing from, or NULL to stay where we were.
   12336              : 
   12337              :    The transformation (in the case where MOVE_AFTER and FIRST_PTR are
   12338              :    different) is worked through below.  Here we are processing LAST_NODE, and
   12339              :    FIRST_PTR points at the preceding mapping clause:
   12340              : 
   12341              :   #. mapping node               chain
   12342              :   ---------------------------------------------------
   12343              :   A. struct_node                [->B]
   12344              :   B. comp_1                     [->C]
   12345              :   C. comp_2                     [->D (move_after)]
   12346              :   D. map_to_3                   [->E]
   12347              :   E. attach_3                   [->F (first_ptr)]
   12348              :   F. map_to_4                   [->G (continue_at)]
   12349              :   G. attach_4 (last_node)       [->H]
   12350              :   H. ...
   12351              : 
   12352              :      *last_new_tail = *first_ptr;
   12353              : 
   12354              :   I. new_node (first_new)       [->F (last_new_tail)]
   12355              : 
   12356              :      *first_ptr = OMP_CLAUSE_CHAIN (last_node)
   12357              : 
   12358              :   #. mapping node               chain
   12359              :   ----------------------------------------------------
   12360              :   A. struct_node                [->B]
   12361              :   B. comp_1                     [->C]
   12362              :   C. comp_2                     [->D (move_after)]
   12363              :   D. map_to_3                   [->E]
   12364              :   E. attach_3                   [->H (first_ptr)]
   12365              :   F. map_to_4                   [->G (continue_at)]
   12366              :   G. attach_4 (last_node)       [->H]
   12367              :   H. ...
   12368              : 
   12369              :   I. new_node (first_new)       [->F  (last_new_tail)]
   12370              : 
   12371              :      OMP_CLAUSE_CHAIN (last_node) = *move_after;
   12372              : 
   12373              :   #. mapping node               chain
   12374              :   ---------------------------------------------------
   12375              :   A. struct_node                [->B]
   12376              :   B. comp_1                     [->C]
   12377              :   C. comp_2                     [->D (move_after)]
   12378              :   D. map_to_3                   [->E]
   12379              :   E. attach_3                   [->H (continue_at)]
   12380              :   F. map_to_4                   [->G]
   12381              :   G. attach_4 (last_node)       [->D]
   12382              :   H. ...
   12383              : 
   12384              :   I. new_node (first_new)       [->F  (last_new_tail)]
   12385              : 
   12386              :      *move_after = first_new;
   12387              : 
   12388              :   #. mapping node               chain
   12389              :   ---------------------------------------------------
   12390              :   A. struct_node                [->B]
   12391              :   B. comp_1                     [->C]
   12392              :   C. comp_2                     [->I (move_after)]
   12393              :   D. map_to_3                   [->E]
   12394              :   E. attach_3                   [->H (continue_at)]
   12395              :   F. map_to_4                   [->G]
   12396              :   G. attach_4 (last_node)       [->D]
   12397              :   H. ...
   12398              :   I. new_node (first_new)       [->F (last_new_tail)]
   12399              : 
   12400              :   or, in order:
   12401              : 
   12402              :   #. mapping node               chain
   12403              :   ---------------------------------------------------
   12404              :   A. struct_node                [->B]
   12405              :   B. comp_1                     [->C]
   12406              :   C. comp_2                     [->I (move_after)]
   12407              :   I. new_node (first_new)       [->F (last_new_tail)]
   12408              :   F. map_to_4                   [->G]
   12409              :   G. attach_4 (last_node)       [->D]
   12410              :   D. map_to_3                   [->E]
   12411              :   E. attach_3                   [->H (continue_at)]
   12412              :   H. ...
   12413              : */
   12414              : 
   12415              : static tree *
   12416           71 : omp_siblist_move_concat_nodes_after (tree first_new, tree *last_new_tail,
   12417              :                                      tree *first_ptr, tree last_node,
   12418              :                                      tree *move_after)
   12419              : {
   12420           71 :   tree *continue_at = NULL;
   12421           71 :   *last_new_tail = *first_ptr;
   12422           71 :   if (first_ptr == move_after)
   12423           12 :     *move_after = first_new;
   12424              :   else
   12425              :     {
   12426           59 :       *first_ptr = OMP_CLAUSE_CHAIN (last_node);
   12427           59 :       continue_at = first_ptr;
   12428           59 :       OMP_CLAUSE_CHAIN (last_node) = *move_after;
   12429           59 :       *move_after = first_new;
   12430              :     }
   12431           71 :   return continue_at;
   12432              : }
   12433              : 
   12434              : static omp_addr_token *
   12435        11540 : omp_first_chained_access_token (vec<omp_addr_token *> &addr_tokens)
   12436              : {
   12437        11540 :   using namespace omp_addr_tokenizer;
   12438        11540 :   int idx = addr_tokens.length () - 1;
   12439        11540 :   gcc_assert (idx >= 0);
   12440        11540 :   if (addr_tokens[idx]->type != ACCESS_METHOD)
   12441              :     return addr_tokens[idx];
   12442        11567 :   while (idx > 0 && addr_tokens[idx - 1]->type == ACCESS_METHOD)
   12443              :     idx--;
   12444        11540 :   return addr_tokens[idx];
   12445              : }
   12446              : 
   12447              : /* Mapping struct members causes an additional set of nodes to be created,
   12448              :    starting with GOMP_MAP_STRUCT followed by a number of mappings equal to the
   12449              :    number of members being mapped, in order of ascending position (address or
   12450              :    bitwise).
   12451              : 
   12452              :    We scan through the list of mapping clauses, calling this function for each
   12453              :    struct member mapping we find, and build up the list of mappings after the
   12454              :    initial GOMP_MAP_STRUCT node.  For pointer members, these will be
   12455              :    newly-created ALLOC nodes.  For non-pointer members, the existing mapping is
   12456              :    moved into place in the sorted list.
   12457              : 
   12458              :      struct {
   12459              :        int *a;
   12460              :        int *b;
   12461              :        int c;
   12462              :        int *d;
   12463              :      };
   12464              : 
   12465              :      #pragma (acc|omp directive) copy(struct.a[0:n], struct.b[0:n], struct.c,
   12466              :                                       struct.d[0:n])
   12467              : 
   12468              :      GOMP_MAP_STRUCT (4)
   12469              :      [GOMP_MAP_FIRSTPRIVATE_REFERENCE -- for refs to structs]
   12470              :      GOMP_MAP_ALLOC  (struct.a)
   12471              :      GOMP_MAP_ALLOC  (struct.b)
   12472              :      GOMP_MAP_TO     (struct.c)
   12473              :      GOMP_MAP_ALLOC  (struct.d)
   12474              :      ...
   12475              : 
   12476              :    In the case where we are mapping references to pointers, or in Fortran if
   12477              :    we are mapping an array with a descriptor, additional nodes may be created
   12478              :    after the struct node list also.
   12479              : 
   12480              :    The return code is either a pointer to the next node to process (if the
   12481              :    list has been rearranged), else NULL to continue with the next node in the
   12482              :    original list.  */
   12483              : 
   12484              : static tree *
   12485         4765 : omp_accumulate_sibling_list (enum omp_region_type region_type,
   12486              :                              enum tree_code code,
   12487              :                              hash_map<tree_operand_hash, tree>
   12488              :                                *&struct_map_to_clause,
   12489              :                              hash_map<tree_operand_hash_no_se,
   12490              :                                       omp_mapping_group *> *group_map,
   12491              :                              tree *grp_start_p, tree grp_end,
   12492              :                              vec<omp_addr_token *> &addr_tokens, tree **inner,
   12493              :                              bool *fragile_p, bool reprocessing_struct,
   12494              :                              tree **added_tail)
   12495              : {
   12496         4765 :   using namespace omp_addr_tokenizer;
   12497         4765 :   poly_offset_int coffset;
   12498         4765 :   poly_int64 cbitpos;
   12499         4765 :   tree ocd = OMP_CLAUSE_DECL (grp_end);
   12500         4765 :   bool openmp = !(region_type & ORT_ACC);
   12501         4765 :   bool target = (region_type & ORT_TARGET) != 0;
   12502         4765 :   tree *continue_at = NULL;
   12503              : 
   12504         5078 :   while (TREE_CODE (ocd) == ARRAY_REF)
   12505          313 :     ocd = TREE_OPERAND (ocd, 0);
   12506              : 
   12507         4765 :   if (*fragile_p)
   12508              :     {
   12509          156 :       omp_mapping_group *to_group
   12510          156 :         = omp_get_nonfirstprivate_group (group_map, ocd, true);
   12511              : 
   12512          156 :       if (to_group)
   12513              :         return NULL;
   12514              :     }
   12515              : 
   12516         4677 :   omp_addr_token *last_token = omp_first_chained_access_token (addr_tokens);
   12517         4677 :   if (last_token->type == ACCESS_METHOD)
   12518              :     {
   12519         4677 :       switch (last_token->u.access_kind)
   12520              :         {
   12521          735 :         case ACCESS_REF:
   12522          735 :         case ACCESS_REF_TO_POINTER:
   12523          735 :         case ACCESS_REF_TO_POINTER_OFFSET:
   12524          735 :         case ACCESS_INDEXED_REF_TO_ARRAY:
   12525              :           /* We may see either a bare reference or a dereferenced
   12526              :              "convert_from_reference"-like one here.  Handle either way.  */
   12527          735 :           if (TREE_CODE (ocd) == INDIRECT_REF)
   12528           64 :             ocd = TREE_OPERAND (ocd, 0);
   12529          735 :           gcc_assert (TREE_CODE (TREE_TYPE (ocd)) == REFERENCE_TYPE);
   12530              :           break;
   12531              : 
   12532              :         default:
   12533              :           ;
   12534              :         }
   12535              :     }
   12536              : 
   12537         4677 :   bool variable_offset;
   12538         9354 :   tree iterators = OMP_CLAUSE_HAS_ITERATORS (grp_end)
   12539         4710 :                      ? OMP_CLAUSE_ITERATORS (grp_end) : NULL_TREE;
   12540         4677 :   tree base
   12541         4677 :     = extract_base_bit_offset (ocd, &cbitpos, &coffset, &variable_offset,
   12542         4677 :                                iterators);
   12543              : 
   12544         4677 :   int base_token;
   12545        23897 :   for (base_token = addr_tokens.length () - 1; base_token >= 0; base_token--)
   12546              :     {
   12547        19220 :       if (addr_tokens[base_token]->type == ARRAY_BASE
   12548        19220 :           || addr_tokens[base_token]->type == STRUCTURE_BASE)
   12549              :         break;
   12550              :     }
   12551              : 
   12552              :   /* The two expressions in the assertion below aren't quite the same: if we
   12553              :      have 'struct_base_decl access_indexed_array' for something like
   12554              :      "myvar[2].x" then base will be "myvar" and addr_tokens[base_token]->expr
   12555              :      will be "myvar[2]" -- the actual base of the structure.
   12556              :      The former interpretation leads to a strange situation where we get
   12557              :        struct(myvar) alloc(myvar[2].ptr1)
   12558              :      That is, the array of structures is kind of treated as one big structure
   12559              :      for the purposes of gathering sibling lists, etc.  */
   12560              :   /* gcc_assert (base == addr_tokens[base_token]->expr);  */
   12561              : 
   12562         4677 :   bool attach_detach = ((OMP_CLAUSE_MAP_KIND (grp_end)
   12563              :                          == GOMP_MAP_ATTACH_DETACH)
   12564         4677 :                         || (OMP_CLAUSE_MAP_KIND (grp_end)
   12565         4677 :                             == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION));
   12566         4677 :   bool has_descriptor = false;
   12567         4677 :   if (OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
   12568              :     {
   12569         3137 :       tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p);
   12570         3137 :       if (grp_mid && omp_map_clause_descriptor_p (grp_mid))
   12571              :         has_descriptor = true;
   12572              :     }
   12573              : 
   12574         4677 :   if (!struct_map_to_clause || struct_map_to_clause->get (base) == NULL)
   12575              :     {
   12576         3058 :       enum gomp_map_kind str_kind = GOMP_MAP_STRUCT;
   12577              : 
   12578         3058 :       if (struct_map_to_clause == NULL)
   12579         2495 :         struct_map_to_clause = new hash_map<tree_operand_hash, tree>;
   12580              : 
   12581         3058 :       if (variable_offset)
   12582          274 :         str_kind = GOMP_MAP_STRUCT_UNORD;
   12583              : 
   12584         3058 :       tree l = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
   12585              : 
   12586         3058 :       OMP_CLAUSE_SET_MAP_KIND (l, str_kind);
   12587         3058 :       OMP_CLAUSE_DECL (l) = unshare_expr (base);
   12588         3058 :       OMP_CLAUSE_SIZE (l) = size_int (1);
   12589              : 
   12590         3058 :       struct_map_to_clause->put (base, l);
   12591              : 
   12592              :       /* On first iterating through the clause list, we insert the struct node
   12593              :          just before the component access node that triggers the initial
   12594              :          omp_accumulate_sibling_list call for a particular sibling list (and
   12595              :          it then forms the first entry in that list).  When reprocessing
   12596              :          struct bases that are themselves component accesses, we insert the
   12597              :          struct node on an off-side list to avoid inserting the new
   12598              :          GOMP_MAP_STRUCT into the middle of the old one.  */
   12599         3058 :       tree *insert_node_pos = reprocessing_struct ? *added_tail : grp_start_p;
   12600              : 
   12601         3058 :       if (has_descriptor)
   12602              :         {
   12603          759 :           tree desc = OMP_CLAUSE_CHAIN (*grp_start_p);
   12604          759 :           if (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
   12605          187 :             OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE);
   12606          759 :           tree sc = *insert_node_pos;
   12607          759 :           OMP_CLAUSE_CHAIN (l) = desc;
   12608          759 :           OMP_CLAUSE_CHAIN (*grp_start_p) = OMP_CLAUSE_CHAIN (desc);
   12609          759 :           OMP_CLAUSE_CHAIN (desc) = sc;
   12610          759 :           *insert_node_pos = l;
   12611              :         }
   12612         2299 :       else if (attach_detach)
   12613              :         {
   12614         1396 :           tree extra_node;
   12615         1396 :           tree alloc_node
   12616         1396 :             = build_omp_struct_comp_nodes (code, *grp_start_p, grp_end,
   12617              :                                            &extra_node);
   12618         1396 :           tree *tail;
   12619         1396 :           OMP_CLAUSE_CHAIN (l) = alloc_node;
   12620              : 
   12621         1396 :           if (extra_node)
   12622              :             {
   12623            0 :               OMP_CLAUSE_CHAIN (extra_node) = *insert_node_pos;
   12624            0 :               OMP_CLAUSE_CHAIN (alloc_node) = extra_node;
   12625            0 :               tail = &OMP_CLAUSE_CHAIN (extra_node);
   12626              :             }
   12627              :           else
   12628              :             {
   12629         1396 :               OMP_CLAUSE_CHAIN (alloc_node) = *insert_node_pos;
   12630         1396 :               tail = &OMP_CLAUSE_CHAIN (alloc_node);
   12631              :             }
   12632              : 
   12633              :           /* For OpenMP semantics, we don't want to implicitly allocate
   12634              :              space for the pointer here for non-compute regions (e.g. "enter
   12635              :              data").  A FRAGILE_P node is only being created so that
   12636              :              omp-low.cc is able to rewrite the struct properly.
   12637              :              For references (to pointers), we want to actually allocate the
   12638              :              space for the reference itself in the sorted list following the
   12639              :              struct node.
   12640              :              For pointers, we want to allocate space if we had an explicit
   12641              :              mapping of the attachment point, but not otherwise.  */
   12642         1396 :           if (*fragile_p
   12643         1396 :               || (openmp
   12644              :                   && !target
   12645              :                   && attach_detach
   12646          234 :                   && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE
   12647           88 :                   && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end)))
   12648              :             {
   12649          133 :               if (!lang_GNU_Fortran ())
   12650              :                /* In Fortran, pointers are dereferenced automatically, but may
   12651              :                   be unassociated.  So we still want to allocate space for the
   12652              :                   pointer (as the base for an attach operation that should be
   12653              :                   present in the same directive's clause list also).  */
   12654          103 :                 OMP_CLAUSE_SIZE (alloc_node) = size_zero_node;
   12655          133 :               OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1;
   12656              :             }
   12657              : 
   12658         1396 :           *insert_node_pos = l;
   12659              : 
   12660         1396 :           if (reprocessing_struct)
   12661              :             {
   12662              :               /* When reprocessing a struct node group used as the base of a
   12663              :                  subcomponent access, if we have a reference-to-pointer base,
   12664              :                  we will see:
   12665              :                    struct(**ptr) attach(*ptr)
   12666              :                  whereas for a non-reprocess-struct group, we see, e.g.:
   12667              :                    tofrom(**ptr) attach(*ptr) attach(ptr)
   12668              :                  and we create the "alloc" for the second "attach", i.e.
   12669              :                  for the reference itself.  When reprocessing a struct group we
   12670              :                  thus change the pointer attachment into a reference attachment
   12671              :                  by stripping the indirection.  (The attachment of the
   12672              :                  referenced pointer must happen elsewhere, either on the same
   12673              :                  directive, or otherwise.)  */
   12674          180 :               tree adecl = OMP_CLAUSE_DECL (alloc_node);
   12675              : 
   12676          180 :               if ((TREE_CODE (adecl) == INDIRECT_REF
   12677          148 :                    || (TREE_CODE (adecl) == MEM_REF
   12678            0 :                        && integer_zerop (TREE_OPERAND (adecl, 1))))
   12679           32 :                   && (TREE_CODE (TREE_TYPE (TREE_OPERAND (adecl, 0)))
   12680              :                       == REFERENCE_TYPE)
   12681          212 :                   && (TREE_CODE (TREE_TYPE (TREE_TYPE
   12682              :                         (TREE_OPERAND (adecl, 0)))) == POINTER_TYPE))
   12683           32 :                 OMP_CLAUSE_DECL (alloc_node) = TREE_OPERAND (adecl, 0);
   12684              : 
   12685          180 :               *added_tail = tail;
   12686              :             }
   12687              :         }
   12688              :       else
   12689              :         {
   12690          903 :           gcc_assert (*grp_start_p == grp_end);
   12691          903 :           if (reprocessing_struct)
   12692              :             {
   12693              :               /* If we don't have an attach/detach node, this is a
   12694              :                  "target data" directive or similar, not an offload region.
   12695              :                  Synthesize an "alloc" node using just the initiating
   12696              :                  GOMP_MAP_STRUCT decl.  */
   12697           16 :               gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA
   12698           32 :                                  || code == OACC_EXIT_DATA)
   12699           32 :                                 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
   12700           32 :               tree alloc_node
   12701           32 :                 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
   12702              :                                     OMP_CLAUSE_MAP);
   12703           32 :               OMP_CLAUSE_SET_MAP_KIND (alloc_node, k);
   12704           32 :               OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr);
   12705           64 :               OMP_CLAUSE_SIZE (alloc_node)
   12706           32 :                 = TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node)));
   12707              : 
   12708           32 :               OMP_CLAUSE_CHAIN (alloc_node) = OMP_CLAUSE_CHAIN (l);
   12709           32 :               OMP_CLAUSE_CHAIN (l) = alloc_node;
   12710           32 :               *insert_node_pos = l;
   12711           32 :               *added_tail = &OMP_CLAUSE_CHAIN (alloc_node);
   12712              :             }
   12713              :           else
   12714          871 :             grp_start_p = omp_siblist_insert_node_after (l, insert_node_pos);
   12715              :         }
   12716              : 
   12717         3058 :       unsigned last_access = base_token + 1;
   12718              : 
   12719         3058 :       while (last_access + 1 < addr_tokens.length ()
   12720         3393 :              && addr_tokens[last_access + 1]->type == ACCESS_METHOD)
   12721              :         last_access++;
   12722              : 
   12723         3058 :       if ((region_type & ORT_TARGET)
   12724         3058 :           && addr_tokens[base_token + 1]->type == ACCESS_METHOD)
   12725              :         {
   12726         1708 :           bool base_ref = false;
   12727         1708 :           access_method_kinds access_kind
   12728         1708 :             = addr_tokens[last_access]->u.access_kind;
   12729              : 
   12730         1708 :           switch (access_kind)
   12731              :             {
   12732              :             case ACCESS_DIRECT:
   12733              :             case ACCESS_INDEXED_ARRAY:
   12734         1060 :               return NULL;
   12735              : 
   12736          403 :             case ACCESS_REF:
   12737          403 :             case ACCESS_REF_TO_POINTER:
   12738          403 :             case ACCESS_REF_TO_POINTER_OFFSET:
   12739          403 :             case ACCESS_INDEXED_REF_TO_ARRAY:
   12740          403 :               base_ref = true;
   12741          403 :               break;
   12742              : 
   12743          866 :             default:
   12744          866 :               ;
   12745              :             }
   12746          866 :           tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
   12747              :                                       OMP_CLAUSE_MAP);
   12748          866 :           enum gomp_map_kind mkind;
   12749          866 :           omp_mapping_group *decl_group;
   12750          866 :           tree use_base;
   12751          866 :           switch (access_kind)
   12752              :             {
   12753          463 :             case ACCESS_POINTER:
   12754          463 :             case ACCESS_POINTER_OFFSET:
   12755          463 :               use_base = addr_tokens[last_access]->expr;
   12756          463 :               break;
   12757          198 :             case ACCESS_REF_TO_POINTER:
   12758          198 :             case ACCESS_REF_TO_POINTER_OFFSET:
   12759          198 :               use_base
   12760          198 :                 = build_fold_indirect_ref (addr_tokens[last_access]->expr);
   12761          198 :               break;
   12762          205 :             default:
   12763          205 :               use_base = addr_tokens[base_token]->expr;
   12764              :             }
   12765          866 :           bool mapped_to_p
   12766          866 :             = omp_directive_maps_explicitly (group_map, use_base, &decl_group,
   12767              :                                              true, false, true);
   12768          866 :           if (addr_tokens[base_token]->type == STRUCTURE_BASE
   12769          866 :               && DECL_P (addr_tokens[last_access]->expr)
   12770         1372 :               && !mapped_to_p)
   12771          444 :             mkind = base_ref ? GOMP_MAP_FIRSTPRIVATE_REFERENCE
   12772              :                              : GOMP_MAP_FIRSTPRIVATE_POINTER;
   12773              :           else
   12774              :             mkind = GOMP_MAP_ATTACH_DETACH;
   12775              : 
   12776          866 :           OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
   12777              :           /* If we have a reference to pointer base, we want to attach the
   12778              :              pointer here, not the reference.  The reference attachment happens
   12779              :              elsewhere.  */
   12780          866 :           bool ref_to_ptr
   12781          866 :             = (access_kind == ACCESS_REF_TO_POINTER
   12782          866 :                || access_kind == ACCESS_REF_TO_POINTER_OFFSET);
   12783          866 :           tree sdecl = addr_tokens[last_access]->expr;
   12784          866 :           tree sdecl_ptr = ref_to_ptr ? build_fold_indirect_ref (sdecl)
   12785              :                                       : sdecl;
   12786              :           /* For the FIRSTPRIVATE_REFERENCE after the struct node, we
   12787              :              want to use the reference itself for the decl, but we
   12788              :              still want to use the pointer to calculate the bias.  */
   12789          866 :           OMP_CLAUSE_DECL (c2) = (mkind == GOMP_MAP_ATTACH_DETACH)
   12790          866 :                                  ? sdecl_ptr : sdecl;
   12791          866 :           sdecl = sdecl_ptr;
   12792          866 :           tree baddr = build_fold_addr_expr (base);
   12793          866 :           baddr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end),
   12794              :                                     ptrdiff_type_node, baddr);
   12795          866 :           tree decladdr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end),
   12796              :                                             ptrdiff_type_node, sdecl);
   12797          866 :           OMP_CLAUSE_SIZE (c2)
   12798          866 :             = fold_build2_loc (OMP_CLAUSE_LOCATION (grp_end), MINUS_EXPR,
   12799              :                                ptrdiff_type_node, baddr, decladdr);
   12800              :           /* Insert after struct node.  */
   12801          866 :           OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
   12802          866 :           OMP_CLAUSE_CHAIN (l) = c2;
   12803              : 
   12804          866 :           if (addr_tokens[base_token]->type == STRUCTURE_BASE
   12805          866 :               && (addr_tokens[base_token]->u.structure_base_kind
   12806              :                   == BASE_COMPONENT_EXPR)
   12807          286 :               && mkind == GOMP_MAP_ATTACH_DETACH
   12808         1152 :               && addr_tokens[last_access]->u.access_kind != ACCESS_REF)
   12809              :             {
   12810          218 :               *inner = insert_node_pos;
   12811          218 :               if (openmp)
   12812          166 :                 *fragile_p = true;
   12813          218 :               return NULL;
   12814              :             }
   12815              :         }
   12816              : 
   12817         1998 :       if (addr_tokens[base_token]->type == STRUCTURE_BASE
   12818         1998 :           && (addr_tokens[base_token]->u.structure_base_kind
   12819              :               == BASE_COMPONENT_EXPR)
   12820         2465 :           && addr_tokens[last_access]->u.access_kind == ACCESS_REF)
   12821          100 :         *inner = insert_node_pos;
   12822              : 
   12823         1998 :       return NULL;
   12824              :     }
   12825         1619 :   else if (struct_map_to_clause)
   12826              :     {
   12827         1619 :       tree *osc = struct_map_to_clause->get (base);
   12828         1619 :       tree *sc = NULL, *scp = NULL;
   12829              : 
   12830         1619 :       unsigned HOST_WIDE_INT i, elems = tree_to_uhwi (OMP_CLAUSE_SIZE (*osc));
   12831         1619 :       sc = &OMP_CLAUSE_CHAIN (*osc);
   12832              :       /* The struct mapping might be immediately followed by a
   12833              :          FIRSTPRIVATE_POINTER,  FIRSTPRIVATE_REFERENCE or an ATTACH_DETACH --
   12834              :          if it's an indirect access or a reference, or if the structure base
   12835              :          is not a decl.  The FIRSTPRIVATE_* nodes are removed in omp-low.cc
   12836              :          after they have been processed there, and ATTACH_DETACH nodes are
   12837              :          recomputed and moved out of the GOMP_MAP_STRUCT construct once
   12838              :          sibling list building is complete.  */
   12839         1619 :       if (OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_POINTER
   12840         1574 :           || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   12841         3148 :           || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_ATTACH_DETACH)
   12842          201 :         sc = &OMP_CLAUSE_CHAIN (*sc);
   12843         4108 :       for (i = 0; i < elems; i++, sc = &OMP_CLAUSE_CHAIN (*sc))
   12844         3062 :         if (attach_detach && sc == grp_start_p)
   12845              :           break;
   12846         3062 :         else if (TREE_CODE (OMP_CLAUSE_DECL (*sc)) != COMPONENT_REF
   12847          182 :                  && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != INDIRECT_REF
   12848         3244 :                  && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != ARRAY_REF)
   12849              :           break;
   12850              :         else
   12851              :           {
   12852         3062 :             tree sc_decl = OMP_CLAUSE_DECL (*sc);
   12853         3062 :             poly_offset_int offset;
   12854         3062 :             poly_int64 bitpos;
   12855              : 
   12856         3062 :             if (TREE_CODE (sc_decl) == ARRAY_REF)
   12857              :               {
   12858          366 :                 while (TREE_CODE (sc_decl) == ARRAY_REF)
   12859          184 :                   sc_decl = TREE_OPERAND (sc_decl, 0);
   12860          182 :                 if (TREE_CODE (sc_decl) != COMPONENT_REF
   12861          182 :                     || TREE_CODE (TREE_TYPE (sc_decl)) != ARRAY_TYPE)
   12862              :                   break;
   12863              :               }
   12864         2880 :             else if (INDIRECT_REF_P (sc_decl)
   12865            0 :                      && TREE_CODE (TREE_OPERAND (sc_decl, 0)) == COMPONENT_REF
   12866         2880 :                      && (TREE_CODE (TREE_TYPE (TREE_OPERAND (sc_decl, 0)))
   12867              :                          == REFERENCE_TYPE))
   12868            0 :               sc_decl = TREE_OPERAND (sc_decl, 0);
   12869              : 
   12870         3062 :             bool variable_offset2;
   12871         3062 :             tree iterators2 = OMP_CLAUSE_HAS_ITERATORS (*sc)
   12872         3062 :                                 ? OMP_CLAUSE_ITERATORS (*sc) : NULL_TREE;
   12873              : 
   12874         3062 :             tree base2 = extract_base_bit_offset (sc_decl, &bitpos, &offset,
   12875              :                                                   &variable_offset2,
   12876              :                                                   iterators2);
   12877         3062 :             if (!base2 || !operand_equal_p (base2, base, 0))
   12878              :               break;
   12879         3062 :             if (scp)
   12880          469 :               continue;
   12881         2842 :             if (variable_offset2)
   12882              :               {
   12883          341 :                 OMP_CLAUSE_SET_MAP_KIND (*osc, GOMP_MAP_STRUCT_UNORD);
   12884              : 
   12885          341 :                 if (has_descriptor)
   12886              :                   {
   12887              :                     /* Sort mapped components by offset. This is needed for
   12888              :                        libgomp to handle Fortran derived-type allocatable
   12889              :                        components transparently.  */
   12890              : 
   12891          323 :                     poly_int64 bitsize;
   12892          323 :                     tree offset, coffset;
   12893          323 :                     machine_mode mode;
   12894          323 :                     int unsignedp, reversep, volatilep;
   12895          323 :                     tree inner_ref1
   12896          323 :                       = get_inner_reference (sc_decl, &bitsize, &bitpos,
   12897              :                                              &offset, &mode, &unsignedp,
   12898              :                                              &reversep, &volatilep);
   12899          323 :                     tree osc_decl = ocd;
   12900          323 :                     STRIP_NOPS (osc_decl);
   12901          323 :                     tree inner_ref2
   12902          323 :                       = get_inner_reference (osc_decl, &bitsize, &bitpos,
   12903              :                                              &coffset, &mode, &unsignedp,
   12904              :                                              &reversep, &volatilep);
   12905          323 :                     gcc_assert (operand_equal_p (inner_ref1, inner_ref2, 0));
   12906          323 :                     tree offset_diff
   12907          323 :                       = fold_binary_to_constant (MINUS_EXPR, size_type_node,
   12908              :                                                  coffset, offset);
   12909          572 :                     if (offset_diff == NULL_TREE
   12910          323 :                         || TREE_INT_CST_ELT (offset_diff, 0) > 0)
   12911          249 :                       continue;
   12912              :                     else
   12913              :                       break;
   12914              :                   }
   12915              :               }
   12916         2501 :             else if ((region_type & ORT_ACC) != 0)
   12917              :               {
   12918              :                 /* For OpenACC, allow (ignore) duplicate struct accesses in
   12919              :                    the middle of a mapping clause, e.g. "mystruct->foo" in:
   12920              :                    copy(mystruct->foo->bar) copy(mystruct->foo->qux).  */
   12921          223 :                 if (reprocessing_struct
   12922            8 :                     && known_eq (coffset, offset)
   12923          223 :                     && known_eq (cbitpos, bitpos))
   12924           16 :                   return NULL;
   12925              :               }
   12926         2278 :             else if (known_eq (coffset, offset)
   12927         2278 :                      && known_eq (cbitpos, bitpos))
   12928              :               {
   12929              :                 /* Having two struct members at the same offset doesn't work,
   12930              :                    so make sure we don't.  (We're allowed to ignore this.
   12931              :                    Should we report the error?)  */
   12932              :                 /*error_at (OMP_CLAUSE_LOCATION (grp_end),
   12933              :                           "duplicate struct member %qE in map clauses",
   12934              :                           OMP_CLAUSE_DECL (grp_end));*/
   12935              :                 return NULL;
   12936              :               }
   12937         2503 :             if (maybe_lt (coffset, offset)
   12938         4231 :                 || (known_eq (coffset, offset)
   12939           20 :                     && maybe_lt (cbitpos, bitpos)))
   12940              :               {
   12941          775 :                 if (attach_detach)
   12942              :                   scp = sc;
   12943              :                 else
   12944              :                   break;
   12945              :               }
   12946              :           }
   12947              : 
   12948         1603 :       OMP_CLAUSE_SIZE (*osc)
   12949         1603 :         = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc), size_one_node);
   12950              : 
   12951         1603 :       if (reprocessing_struct)
   12952              :         {
   12953              :           /* If we're reprocessing a struct node, we don't want to do most of
   12954              :              the list manipulation below.  We only need to handle the (pointer
   12955              :              or reference) attach/detach case.  */
   12956            8 :           tree extra_node, alloc_node;
   12957            8 :           if (has_descriptor)
   12958            0 :             gcc_unreachable ();
   12959            8 :           else if (attach_detach)
   12960            8 :             alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p,
   12961              :                                                       grp_end, &extra_node);
   12962              :           else
   12963              :             {
   12964              :               /* If we don't have an attach/detach node, this is a
   12965              :                  "target data" directive or similar, not an offload region.
   12966              :                  Synthesize an "alloc" node using just the initiating
   12967              :                  GOMP_MAP_STRUCT decl.  */
   12968            0 :               gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA
   12969            0 :                                  || code == OACC_EXIT_DATA)
   12970            0 :                                 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
   12971            0 :               alloc_node
   12972            0 :                 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
   12973              :                                     OMP_CLAUSE_MAP);
   12974            0 :               OMP_CLAUSE_SET_MAP_KIND (alloc_node, k);
   12975            0 :               OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr);
   12976            0 :               OMP_CLAUSE_SIZE (alloc_node)
   12977            0 :                 = TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node)));
   12978              :             }
   12979              : 
   12980            8 :           if (scp)
   12981            0 :             omp_siblist_insert_node_after (alloc_node, scp);
   12982              :           else
   12983              :             {
   12984            8 :               tree *new_end = omp_siblist_insert_node_after (alloc_node, sc);
   12985            8 :               if (sc == *added_tail)
   12986            8 :                 *added_tail = new_end;
   12987              :             }
   12988              : 
   12989            8 :           return NULL;
   12990              :         }
   12991              : 
   12992         1595 :       if (has_descriptor)
   12993              :         {
   12994          538 :           tree desc = OMP_CLAUSE_CHAIN (*grp_start_p);
   12995          538 :           if (code == OMP_TARGET_EXIT_DATA
   12996          538 :               || code == OACC_EXIT_DATA)
   12997          105 :             OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE);
   12998         1076 :           omp_siblist_move_node_after (desc,
   12999          538 :                                        &OMP_CLAUSE_CHAIN (*grp_start_p),
   13000              :                                        scp ? scp : sc);
   13001              :         }
   13002         1057 :       else if (attach_detach)
   13003              :         {
   13004          325 :           tree cl = NULL_TREE, extra_node;
   13005          325 :           tree alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p,
   13006              :                                                          grp_end, &extra_node);
   13007          325 :           tree *tail_chain = NULL;
   13008              : 
   13009          325 :           if (*fragile_p
   13010          325 :               || (openmp
   13011              :                   && !target
   13012              :                   && attach_detach
   13013           62 :                   && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE
   13014           23 :                   && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end)))
   13015              :             {
   13016            6 :               if (!lang_GNU_Fortran ())
   13017            6 :                 OMP_CLAUSE_SIZE (alloc_node) = size_zero_node;
   13018            6 :               OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1;
   13019              :             }
   13020              : 
   13021              :           /* Here, we have:
   13022              : 
   13023              :              grp_end : the last (or only) node in this group.
   13024              :              grp_start_p : pointer to the first node in a pointer mapping group
   13025              :                            up to and including GRP_END.
   13026              :              sc : pointer to the chain for the end of the struct component
   13027              :                   list.
   13028              :              scp : pointer to the chain for the sorted position at which we
   13029              :                    should insert in the middle of the struct component list
   13030              :                    (else NULL to insert at end).
   13031              :              alloc_node : the "alloc" node for the structure (pointer-type)
   13032              :                           component. We insert at SCP (if present), else SC
   13033              :                           (the end of the struct component list).
   13034              :              extra_node : a newly-synthesized node for an additional indirect
   13035              :                           pointer mapping or a Fortran pointer set, if needed.
   13036              :              cl : first node to prepend before grp_start_p.
   13037              :              tail_chain : pointer to chain of last prepended node.
   13038              : 
   13039              :              The general idea is we move the nodes for this struct mapping
   13040              :              together: the alloc node goes into the sorted list directly after
   13041              :              the struct mapping, and any extra nodes (together with the nodes
   13042              :              mapping arrays pointed to by struct components) get moved after
   13043              :              that list.  When SCP is NULL, we insert the nodes at SC, i.e. at
   13044              :              the end of the struct component mapping list.  It's important that
   13045              :              the alloc_node comes first in that case because it's part of the
   13046              :              sorted component mapping list (but subsequent nodes are not!).  */
   13047              : 
   13048          325 :           if (scp)
   13049          254 :             omp_siblist_insert_node_after (alloc_node, scp);
   13050              : 
   13051              :           /* Make [cl,tail_chain] a list of the alloc node (if we haven't
   13052              :              already inserted it) and the extra_node (if it is present).  The
   13053              :              list can be empty if we added alloc_node above and there is no
   13054              :              extra node.  */
   13055          254 :           if (scp && extra_node)
   13056              :             {
   13057            0 :               cl = extra_node;
   13058            0 :               tail_chain = &OMP_CLAUSE_CHAIN (extra_node);
   13059              :             }
   13060          325 :           else if (extra_node)
   13061              :             {
   13062            0 :               OMP_CLAUSE_CHAIN (alloc_node) = extra_node;
   13063            0 :               cl = alloc_node;
   13064            0 :               tail_chain = &OMP_CLAUSE_CHAIN (extra_node);
   13065              :             }
   13066          325 :           else if (!scp)
   13067              :             {
   13068           71 :               cl = alloc_node;
   13069           71 :               tail_chain = &OMP_CLAUSE_CHAIN (alloc_node);
   13070              :             }
   13071              : 
   13072          325 :           continue_at
   13073           71 :             = cl ? omp_siblist_move_concat_nodes_after (cl, tail_chain,
   13074              :                                                         grp_start_p, grp_end,
   13075              :                                                         sc)
   13076          254 :                  : omp_siblist_move_nodes_after (grp_start_p, grp_end, sc);
   13077              :         }
   13078          732 :       else if (*sc != grp_end)
   13079              :         {
   13080          692 :           gcc_assert (*grp_start_p == grp_end);
   13081              : 
   13082              :           /* We are moving the current node back to a previous struct node:
   13083              :              the node that used to point to the current node will now point to
   13084              :              the next node.  */
   13085          692 :           continue_at = grp_start_p;
   13086              :           /* In the non-pointer case, the mapping clause itself is moved into
   13087              :              the correct position in the struct component list, which in this
   13088              :              case is just SC.  */
   13089          692 :           omp_siblist_move_node_after (*grp_start_p, grp_start_p, sc);
   13090              :         }
   13091              :     }
   13092              :   return continue_at;
   13093              : }
   13094              : 
   13095              : /* Scan through GROUPS, and create sorted structure sibling lists without
   13096              :    gimplifying.  */
   13097              : 
   13098              : static bool
   13099        17977 : omp_build_struct_sibling_lists (enum tree_code code,
   13100              :                                 enum omp_region_type region_type,
   13101              :                                 vec<omp_mapping_group> *groups,
   13102              :                                 hash_map<tree_operand_hash_no_se,
   13103              :                                          omp_mapping_group *> **grpmap,
   13104              :                                 tree *list_p)
   13105              : {
   13106        17977 :   using namespace omp_addr_tokenizer;
   13107        17977 :   unsigned i;
   13108        17977 :   omp_mapping_group *grp;
   13109        17977 :   hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL;
   13110        17977 :   bool success = true;
   13111        17977 :   tree *new_next = NULL;
   13112        35954 :   tree *tail = &OMP_CLAUSE_CHAIN ((*groups)[groups->length () - 1].grp_end);
   13113        17977 :   tree added_nodes = NULL_TREE;
   13114        17977 :   tree *added_tail = &added_nodes;
   13115        17977 :   auto_vec<omp_mapping_group> pre_hwm_groups;
   13116              : 
   13117        67200 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   13118              :     {
   13119        31246 :       tree c = grp->grp_end;
   13120        31246 :       tree decl = OMP_CLAUSE_DECL (c);
   13121        31246 :       tree grp_end = grp->grp_end;
   13122        31246 :       auto_vec<omp_addr_token *> addr_tokens;
   13123        31246 :       tree sentinel = OMP_CLAUSE_CHAIN (grp_end);
   13124              : 
   13125        31246 :       if (new_next && !grp->reprocess_struct)
   13126          622 :         grp->grp_start = new_next;
   13127              : 
   13128        31246 :       new_next = NULL;
   13129              : 
   13130        31246 :       tree *grp_start_p = grp->grp_start;
   13131              : 
   13132        31246 :       if (DECL_P (decl))
   13133        21114 :         continue;
   13134              : 
   13135              :       /* Skip groups we marked for deletion in
   13136              :          {omp,oacc}_resolve_clause_dependencies.  */
   13137        10132 :       if (grp->deleted)
   13138          462 :         continue;
   13139              : 
   13140         9670 :       if (OMP_CLAUSE_CHAIN (*grp_start_p)
   13141         9670 :           && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
   13142              :         {
   13143              :           /* Don't process an array descriptor that isn't inside a derived type
   13144              :              as a struct (the GOMP_MAP_POINTER following will have the form
   13145              :              "var.data", but such mappings are handled specially).  */
   13146         6111 :           tree grpmid = OMP_CLAUSE_CHAIN (*grp_start_p);
   13147         6111 :           if (omp_map_clause_descriptor_p (grpmid)
   13148        10262 :               && DECL_P (OMP_CLAUSE_DECL (grpmid)))
   13149         2807 :             continue;
   13150              :         }
   13151              : 
   13152              :       tree expr = decl;
   13153              : 
   13154         7876 :       while (TREE_CODE (expr) == ARRAY_REF)
   13155         1013 :         expr = TREE_OPERAND (expr, 0);
   13156              : 
   13157         6863 :       if (!omp_parse_expr (addr_tokens, expr))
   13158            0 :         continue;
   13159              : 
   13160         6863 :       omp_addr_token *last_token
   13161         6863 :         = omp_first_chained_access_token (addr_tokens);
   13162              : 
   13163              :       /* A mapping of a reference to a pointer member that doesn't specify an
   13164              :          array section, etc., like this:
   13165              :            *mystruct.ref_to_ptr
   13166              :          should not be processed by the struct sibling-list handling code --
   13167              :          it just transfers the referenced pointer.
   13168              : 
   13169              :          In contrast, the quite similar-looking construct:
   13170              :            *mystruct.ptr
   13171              :          which is equivalent to e.g.
   13172              :            mystruct.ptr[0]
   13173              :          *does* trigger sibling-list processing.
   13174              : 
   13175              :          An exception for the former case is for "fragile" groups where the
   13176              :          reference itself is not handled otherwise; this is subject to special
   13177              :          handling in omp_accumulate_sibling_list also.  */
   13178              : 
   13179         6863 :       if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
   13180         3397 :           && last_token->type == ACCESS_METHOD
   13181         3397 :           && last_token->u.access_kind == ACCESS_REF
   13182         7145 :           && !grp->fragile)
   13183          217 :         continue;
   13184              : 
   13185         6646 :       tree d = decl;
   13186         6646 :       if (TREE_CODE (d) == ARRAY_REF)
   13187              :         {
   13188         1974 :           while (TREE_CODE (d) == ARRAY_REF)
   13189          998 :             d = TREE_OPERAND (d, 0);
   13190          976 :           if (TREE_CODE (d) == COMPONENT_REF
   13191          976 :               && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
   13192              :             decl = d;
   13193              :         }
   13194         6646 :       if (d == decl
   13195         5981 :           && INDIRECT_REF_P (decl)
   13196          734 :           && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   13197          105 :           && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   13198              :               == REFERENCE_TYPE)
   13199         6743 :           && (OMP_CLAUSE_MAP_KIND (c)
   13200              :               != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
   13201           97 :         decl = TREE_OPERAND (decl, 0);
   13202              : 
   13203         6646 :       STRIP_NOPS (decl);
   13204              : 
   13205         6646 :       if (TREE_CODE (decl) != COMPONENT_REF)
   13206         1343 :         continue;
   13207              : 
   13208              :       /* If we're mapping the whole struct in another node, skip adding this
   13209              :          node to a sibling list.  */
   13210         5303 :       omp_mapping_group *wholestruct;
   13211         5303 :       if (omp_mapped_by_containing_struct (*grpmap, OMP_CLAUSE_DECL (c),
   13212              :                                            &wholestruct))
   13213              :         {
   13214          177 :           if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   13215          160 :             OMP_CLAUSE_MAP_SIZE_NEEDS_ADJUSTMENT (c) = 0;
   13216          177 :           continue;
   13217              :         }
   13218              : 
   13219         5126 :       if (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
   13220         5126 :           && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
   13221         5023 :           && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
   13222              :           && code != OACC_UPDATE
   13223        10082 :           && code != OMP_TARGET_UPDATE)
   13224              :         {
   13225         4765 :           if (error_operand_p (decl))
   13226              :             {
   13227            0 :               success = false;
   13228            0 :               goto error_out;
   13229              :             }
   13230              : 
   13231         4765 :           tree stype = TREE_TYPE (decl);
   13232         4765 :           if (TREE_CODE (stype) == REFERENCE_TYPE)
   13233          768 :             stype = TREE_TYPE (stype);
   13234         4765 :           if (TYPE_SIZE_UNIT (stype) == NULL
   13235         4765 :               || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
   13236              :             {
   13237            0 :               error_at (OMP_CLAUSE_LOCATION (c),
   13238              :                         "mapping field %qE of variable length "
   13239            0 :                         "structure", OMP_CLAUSE_DECL (c));
   13240            0 :               success = false;
   13241            0 :               goto error_out;
   13242              :             }
   13243              : 
   13244         4765 :           tree *inner = NULL;
   13245         4765 :           bool fragile_p = grp->fragile;
   13246              : 
   13247         4765 :           new_next
   13248         9530 :             = omp_accumulate_sibling_list (region_type, code,
   13249              :                                            struct_map_to_clause, *grpmap,
   13250              :                                            grp_start_p, grp_end, addr_tokens,
   13251              :                                            &inner, &fragile_p,
   13252         4765 :                                            grp->reprocess_struct, &added_tail);
   13253              : 
   13254         4765 :           if (inner)
   13255              :             {
   13256          318 :               omp_mapping_group newgrp;
   13257          318 :               newgrp.grp_start = inner;
   13258          318 :               if (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (*inner))
   13259              :                   == GOMP_MAP_ATTACH_DETACH)
   13260          286 :                 newgrp.grp_end = OMP_CLAUSE_CHAIN (*inner);
   13261              :               else
   13262           32 :                 newgrp.grp_end = *inner;
   13263          318 :               newgrp.mark = UNVISITED;
   13264          318 :               newgrp.sibling = NULL;
   13265          318 :               newgrp.deleted = false;
   13266          318 :               newgrp.reprocess_struct = true;
   13267          318 :               newgrp.fragile = fragile_p;
   13268          318 :               newgrp.next = NULL;
   13269          318 :               groups->safe_push (newgrp);
   13270              : 
   13271              :               /* !!! Growing GROUPS might invalidate the pointers in the group
   13272              :                  map.  Rebuild it here.  This is a bit inefficient, but
   13273              :                  shouldn't happen very often.  */
   13274          636 :               delete (*grpmap);
   13275          318 :               *grpmap
   13276          318 :                 = omp_reindex_mapping_groups (list_p, groups, &pre_hwm_groups,
   13277              :                                               sentinel);
   13278              :             }
   13279              :         }
   13280        31246 :     }
   13281              : 
   13282              :   /* Delete groups marked for deletion above.  At this point the order of the
   13283              :      groups may no longer correspond to the order of the underlying list,
   13284              :      which complicates this a little.  First clear out OMP_CLAUSE_DECL for
   13285              :      deleted nodes...  */
   13286              : 
   13287        49223 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   13288        31246 :     if (grp->deleted)
   13289          462 :       for (tree d = *grp->grp_start;
   13290          924 :            d != OMP_CLAUSE_CHAIN (grp->grp_end);
   13291          462 :            d = OMP_CLAUSE_CHAIN (d))
   13292          462 :         OMP_CLAUSE_DECL (d) = NULL_TREE;
   13293              : 
   13294              :   /* ...then sweep through the list removing the now-empty nodes.  */
   13295              : 
   13296              :   tail = list_p;
   13297        95883 :   while (*tail)
   13298              :     {
   13299        77906 :       if (OMP_CLAUSE_CODE (*tail) == OMP_CLAUSE_MAP
   13300        77906 :           && OMP_CLAUSE_DECL (*tail) == NULL_TREE)
   13301          462 :         *tail = OMP_CLAUSE_CHAIN (*tail);
   13302              :       else
   13303        77444 :         tail = &OMP_CLAUSE_CHAIN (*tail);
   13304              :     }
   13305              : 
   13306              :   /* Tack on the struct nodes added during nested struct reprocessing.  */
   13307        17977 :   if (added_nodes)
   13308              :     {
   13309          192 :       *tail = added_nodes;
   13310          192 :       tail = added_tail;
   13311              :     }
   13312              : 
   13313              :   /* Find each attach node whose bias needs to be adjusted and move it to the
   13314              :      group containing its pointee, right after the struct node, so that it can
   13315              :      be picked up by the adjustment code further down in this function.  */
   13316        17977 :   bool attach_bias_needs_adjustment;
   13317        17977 :   attach_bias_needs_adjustment = false;
   13318        67200 :   FOR_EACH_VEC_ELT_REVERSE (*groups, i, grp)
   13319              :     {
   13320        31246 :       tree c = *grp->grp_start;
   13321        30307 :       if (c != NULL && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13322        30292 :           && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
   13323        27221 :               || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD)
   13324         3351 :           && OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c)) == GOMP_MAP_TO_PSET
   13325          560 :           && OMP_CLAUSE_MAP_KIND (grp->grp_end) == GOMP_MAP_ATTACH_DETACH
   13326        31806 :           && OMP_CLAUSE_MAP_SIZE_NEEDS_ADJUSTMENT (grp->grp_end))
   13327              :         {
   13328           90 :           OMP_CLAUSE_MAP_SIZE_NEEDS_ADJUSTMENT (grp->grp_end) = 0;
   13329           90 :           attach_bias_needs_adjustment = true;
   13330           90 :           tree *cp;
   13331           90 :           for (cp = &OMP_CLAUSE_CHAIN (c); cp != NULL;
   13332          206 :                cp = &OMP_CLAUSE_CHAIN (*cp))
   13333          296 :             if (*cp == grp->grp_end)
   13334              :               {
   13335              :                 c = *cp;
   13336              :                 break;
   13337              :               }
   13338              : 
   13339           90 :           tree base = OMP_CLAUSE_DECL (c);
   13340           90 :           gcc_assert (TREE_CODE (base) == NOP_EXPR);
   13341           90 :           base = build_fold_indirect_ref (base);
   13342           90 :           tree *struct_node = struct_map_to_clause->get (base);
   13343           90 :           omp_siblist_move_node_after (c, cp, &OMP_CLAUSE_CHAIN (*struct_node));
   13344              :         }
   13345              :     }
   13346              : 
   13347              :   /* Now we have finished building the struct sibling lists, reprocess
   13348              :      newly-added "attach" nodes: we need the address of the first
   13349              :      mapped element of each struct sibling list for the bias of the attach
   13350              :      operation -- not necessarily the base address of the whole struct.  */
   13351        17977 :   if (struct_map_to_clause)
   13352         5553 :     for (hash_map<tree_operand_hash, tree>::iterator iter
   13353         2495 :            = struct_map_to_clause->begin ();
   13354         8048 :          iter != struct_map_to_clause->end ();
   13355         3058 :          ++iter)
   13356              :       {
   13357         3058 :         tree struct_node = (*iter).second;
   13358         3058 :         gcc_assert (OMP_CLAUSE_CODE (struct_node) == OMP_CLAUSE_MAP);
   13359         3058 :         tree attach = OMP_CLAUSE_CHAIN (struct_node);
   13360              : 
   13361         3058 :         if (OMP_CLAUSE_CODE (attach) != OMP_CLAUSE_MAP
   13362         3058 :             || OMP_CLAUSE_MAP_KIND (attach) != GOMP_MAP_ATTACH_DETACH)
   13363         2546 :           continue;
   13364              : 
   13365          512 :         OMP_CLAUSE_SET_MAP_KIND (attach, GOMP_MAP_ATTACH);
   13366              : 
   13367              :         /* Sanity check: the standalone attach node will not work if we have
   13368              :            an "enter data" operation (because for those, variables need to be
   13369              :            mapped separately and attach nodes must be grouped together with the
   13370              :            base they attach to).  We should only have created the
   13371              :            ATTACH_DETACH node either after GOMP_MAP_STRUCT for a target region
   13372              :            or for an intermediate descriptor that needs adjustment -- so this
   13373              :            should never be true.  */
   13374          512 :         gcc_assert ((region_type & ORT_TARGET) != 0
   13375              :                     || attach_bias_needs_adjustment);
   13376              : 
   13377              :         /* This is the first sorted node in the struct sibling list.  Use it
   13378              :            to recalculate the correct bias to use.
   13379              :            (&first_node - attach_decl).
   13380              :            For GOMP_MAP_STRUCT_UNORD, we need e.g. the
   13381              :            min(min(min(first,second),third),fourth) element, because the
   13382              :            elements aren't in any particular order.  */
   13383          512 :         tree lowest_addr;
   13384          512 :         if (OMP_CLAUSE_MAP_KIND (struct_node) == GOMP_MAP_STRUCT_UNORD)
   13385              :           {
   13386           94 :             tree first_node = OMP_CLAUSE_CHAIN (attach);
   13387           94 :             unsigned HOST_WIDE_INT num_mappings
   13388           94 :               = tree_to_uhwi (OMP_CLAUSE_SIZE (struct_node));
   13389           94 :             lowest_addr = OMP_CLAUSE_DECL (first_node);
   13390           94 :             lowest_addr = build_fold_addr_expr (lowest_addr);
   13391           94 :             lowest_addr = fold_convert (pointer_sized_int_node, lowest_addr);
   13392           94 :             tree next_node = OMP_CLAUSE_CHAIN (first_node);
   13393          185 :             while (num_mappings > 1)
   13394              :               {
   13395           91 :                 tree tmp = OMP_CLAUSE_DECL (next_node);
   13396           91 :                 tmp = build_fold_addr_expr (tmp);
   13397           91 :                 tmp = fold_convert (pointer_sized_int_node, tmp);
   13398           91 :                 lowest_addr = fold_build2 (MIN_EXPR, pointer_sized_int_node,
   13399              :                                            lowest_addr, tmp);
   13400           91 :                 next_node = OMP_CLAUSE_CHAIN (next_node);
   13401           91 :                 num_mappings--;
   13402              :               }
   13403           94 :             lowest_addr = fold_convert (ptrdiff_type_node, lowest_addr);
   13404              :           }
   13405              :         else
   13406              :           {
   13407          418 :             tree first_node = OMP_CLAUSE_DECL (OMP_CLAUSE_CHAIN (attach));
   13408          418 :             first_node = build_fold_addr_expr (first_node);
   13409          418 :             lowest_addr = fold_convert (ptrdiff_type_node, first_node);
   13410              :           }
   13411          512 :         tree attach_decl = OMP_CLAUSE_DECL (attach);
   13412          512 :         attach_decl = fold_convert (ptrdiff_type_node, attach_decl);
   13413          512 :         OMP_CLAUSE_SIZE (attach)
   13414          512 :           = fold_build2 (MINUS_EXPR, ptrdiff_type_node, lowest_addr,
   13415              :                          attach_decl);
   13416              : 
   13417              :         /* Remove GOMP_MAP_ATTACH node from after struct node.  */
   13418          512 :         OMP_CLAUSE_CHAIN (struct_node) = OMP_CLAUSE_CHAIN (attach);
   13419              :         /* ...and re-insert it at the end of our clause list.  */
   13420          512 :         *tail = attach;
   13421          512 :         OMP_CLAUSE_CHAIN (attach) = NULL_TREE;
   13422          512 :         tail = &OMP_CLAUSE_CHAIN (attach);
   13423              :       }
   13424              : 
   13425        15482 : error_out:
   13426        17977 :   if (struct_map_to_clause)
   13427         2495 :     delete struct_map_to_clause;
   13428              : 
   13429        17977 :   return success;
   13430        17977 : }
   13431              : 
   13432              : struct instantiate_mapper_info
   13433              : {
   13434              :   tree *mapper_clauses_p;
   13435              :   struct gimplify_omp_ctx *omp_ctx;
   13436              :   gimple_seq *pre_p;
   13437              : };
   13438              : 
   13439              : /* Helper function for omp_instantiate_mapper.  */
   13440              : 
   13441              : static tree
   13442         1592 : remap_mapper_decl_1 (tree *tp, int *walk_subtrees, void *data)
   13443              : {
   13444         1592 :   copy_body_data *id = (copy_body_data *) data;
   13445              : 
   13446         1592 :   if (DECL_P (*tp))
   13447              :     {
   13448          724 :       tree replacement = remap_decl (*tp, id);
   13449          724 :       if (*tp != replacement)
   13450              :         {
   13451          369 :           *tp = unshare_expr (replacement);
   13452          369 :           *walk_subtrees = 0;
   13453              :         }
   13454              :     }
   13455              : 
   13456         1592 :   return NULL_TREE;
   13457              : }
   13458              : 
   13459              : /* A copy_decl implementation (for use with tree-inline.cc functions) that
   13460              :    only transform decls or SSA names that are part of a map we already
   13461              :    prepared.  */
   13462              : 
   13463              : static tree
   13464          126 : omp_mapper_copy_decl (tree var, copy_body_data *cb)
   13465              : {
   13466          126 :   tree *repl = cb->decl_map->get (var);
   13467              : 
   13468          126 :   if (repl)
   13469            0 :     return *repl;
   13470              : 
   13471          126 :   return var;
   13472              : }
   13473              : 
   13474              : static tree *
   13475           90 : omp_instantiate_mapper (gimple_seq *pre_p,
   13476              :                         hash_map<omp_name_type<tree>, tree> *implicit_mappers,
   13477              :                         tree mapperfn, tree expr, enum gomp_map_kind outer_kind,
   13478              :                         tree *mapper_clauses_p)
   13479              : {
   13480           90 :   tree mapper_name = NULL_TREE;
   13481           90 :   tree mapper = lang_hooks.decls.omp_extract_mapper_directive (mapperfn);
   13482           90 :   gcc_assert (TREE_CODE (mapper) == OMP_DECLARE_MAPPER);
   13483              : 
   13484           90 :   tree clause = OMP_DECLARE_MAPPER_CLAUSES (mapper);
   13485           90 :   tree dummy_var = OMP_DECLARE_MAPPER_DECL (mapper);
   13486              : 
   13487              :   /* The "extraction map" is used to map the mapper variable in the "declare
   13488              :      mapper" directive, and also any temporary variables that have been created
   13489              :      as part of expanding the mapper function's body (which are expanded as a
   13490              :      "bind" expression in the pre_p sequence).  */
   13491           90 :   hash_map<tree, tree> extraction_map;
   13492              : 
   13493           90 :   extraction_map.put (dummy_var, expr);
   13494           90 :   extraction_map.put (expr, expr);
   13495              : 
   13496              :   /* This copy_body_data is only used to remap the decls in the
   13497              :      OMP_DECLARE_MAPPER tree node expansion itself.  All relevant decls should
   13498              :      already be in the current function.  */
   13499           90 :   copy_body_data id;
   13500           90 :   memset (&id, 0, sizeof (id));
   13501           90 :   id.src_fn = current_function_decl;
   13502           90 :   id.dst_fn = current_function_decl;
   13503           90 :   id.src_cfun = cfun;
   13504           90 :   id.decl_map = &extraction_map;
   13505           90 :   id.copy_decl = omp_mapper_copy_decl;
   13506           90 :   id.transform_call_graph_edges = CB_CGE_DUPLICATE; // ???
   13507           90 :   id.transform_new_cfg = true; // ???
   13508              : 
   13509          282 :   for (; clause; clause = OMP_CLAUSE_CHAIN (clause))
   13510              :     {
   13511          192 :       enum gomp_map_kind map_kind = OMP_CLAUSE_MAP_KIND (clause);
   13512          192 :       tree *nested_mapper_p = NULL;
   13513              : 
   13514          192 :       if (map_kind == GOMP_MAP_PUSH_MAPPER_NAME)
   13515              :         {
   13516            0 :           mapper_name = OMP_CLAUSE_DECL (clause);
   13517           25 :           continue;
   13518              :         }
   13519          192 :       else if (map_kind == GOMP_MAP_POP_MAPPER_NAME)
   13520              :         {
   13521            0 :           mapper_name = NULL_TREE;
   13522            0 :           continue;
   13523              :         }
   13524              : 
   13525          192 :       if (OMP_CLAUSE_HAS_ITERATORS (clause))
   13526              :         {
   13527            2 :           sorry_at (OMP_CLAUSE_LOCATION (clause),
   13528              :                     "user-defined mapper that uses a %<map%> clause "
   13529              :                     "with %<iterator%>");
   13530            2 :           continue;
   13531              :         }
   13532              : 
   13533          190 :       tree decl = OMP_CLAUSE_DECL (clause);
   13534          190 :       tree unshared, type;
   13535          190 :       bool nonunit_array_with_mapper = false;
   13536              : 
   13537          190 :       if (TREE_CODE (decl) == OMP_ARRAY_SECTION)
   13538              :         {
   13539           62 :           location_t loc = OMP_CLAUSE_LOCATION (clause);
   13540           62 :           tree tmp = lang_hooks.decls.omp_map_array_section (loc, decl);
   13541           62 :           if (tmp == decl)
   13542              :             {
   13543           48 :               unshared = unshare_expr (clause);
   13544           48 :               nonunit_array_with_mapper = true;
   13545           48 :               type = TREE_TYPE (TREE_TYPE (decl));
   13546              :             }
   13547              :           else
   13548              :             {
   13549           14 :               unshared = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
   13550           14 :                                            OMP_CLAUSE_CODE (clause));
   13551           14 :               OMP_CLAUSE_DECL (unshared) = tmp;
   13552           14 :               OMP_CLAUSE_SIZE (unshared)
   13553           28 :                 = DECL_P (tmp) ? DECL_SIZE_UNIT (tmp)
   13554           14 :                                : TYPE_SIZE_UNIT (TREE_TYPE (tmp));
   13555           14 :               type = TREE_TYPE (tmp);
   13556              :             }
   13557              :         }
   13558              :       else
   13559              :         {
   13560          128 :           unshared = unshare_expr (clause);
   13561          128 :           type = TREE_TYPE (decl);
   13562              :         }
   13563              : 
   13564          190 :       walk_tree (&unshared, remap_mapper_decl_1, &id, NULL);
   13565              : 
   13566          190 :       if (OMP_CLAUSE_MAP_KIND (unshared) == GOMP_MAP_UNSET)
   13567           28 :         OMP_CLAUSE_SET_MAP_KIND (unshared, outer_kind);
   13568              : 
   13569          190 :       decl = OMP_CLAUSE_DECL (unshared);
   13570          190 :       type = TYPE_MAIN_VARIANT (type);
   13571              : 
   13572          190 :       nested_mapper_p = implicit_mappers->get ({ mapper_name, type });
   13573              : 
   13574          190 :       if (nested_mapper_p && *nested_mapper_p != mapperfn)
   13575              :         {
   13576           23 :           if (nonunit_array_with_mapper)
   13577              :             {
   13578            8 :               sorry ("user-defined mapper with non-unit length array section");
   13579            8 :               continue;
   13580              :             }
   13581              : 
   13582           15 :           if (map_kind == GOMP_MAP_UNSET)
   13583            0 :             map_kind = outer_kind;
   13584              : 
   13585           15 :           mapper_clauses_p
   13586           15 :             = omp_instantiate_mapper (pre_p, implicit_mappers,
   13587              :                                       *nested_mapper_p, decl, map_kind,
   13588              :                                       mapper_clauses_p);
   13589           15 :           continue;
   13590              :         }
   13591              : 
   13592          167 :       *mapper_clauses_p = unshared;
   13593          167 :       mapper_clauses_p = &OMP_CLAUSE_CHAIN (unshared);
   13594              :     }
   13595              : 
   13596           90 :   return mapper_clauses_p;
   13597           90 : }
   13598              : 
   13599              : static int
   13600       138031 : omp_instantiate_implicit_mappers (splay_tree_node n, void *data)
   13601              : {
   13602       138031 :   tree decl = (tree) n->key;
   13603       138031 :   instantiate_mapper_info *im_info = (instantiate_mapper_info *) data;
   13604       138031 :   gimplify_omp_ctx *ctx = im_info->omp_ctx;
   13605       138031 :   tree *mapper_p = NULL;
   13606       138031 :   tree type = TREE_TYPE (decl);
   13607       138031 :   bool ref_p = false;
   13608       138031 :   unsigned flags = n->value;
   13609              : 
   13610       138031 :   if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
   13611              :     return 0;
   13612        23626 :   if ((flags & GOVD_SEEN) == 0)
   13613              :     return 0;
   13614              :   /* If we already have clauses pertaining to a struct variable, then we don't
   13615              :      want to implicitly invoke a user-defined mapper.  */
   13616        20096 :   if ((flags & GOVD_EXPLICIT) != 0 && AGGREGATE_TYPE_P (TREE_TYPE (decl)))
   13617              :     return 0;
   13618              : 
   13619        20096 :   if (TREE_CODE (type) == REFERENCE_TYPE)
   13620              :     {
   13621          900 :       ref_p = true;
   13622          900 :       type = TREE_TYPE (type);
   13623              :     }
   13624              : 
   13625        20096 :   type = TYPE_MAIN_VARIANT (type);
   13626              : 
   13627        20096 :   if (DECL_P (decl) && type && AGGREGATE_TYPE_P (type))
   13628              :     {
   13629         5298 :       gcc_assert (ctx);
   13630         5298 :       mapper_p = ctx->implicit_mappers->get ({ NULL_TREE, type });
   13631              :     }
   13632              : 
   13633         5298 :   if (mapper_p)
   13634              :     {
   13635              :       /* If we have a reference, map the pointed-to object rather than the
   13636              :          reference itself.  */
   13637           75 :       if (ref_p)
   13638            2 :         decl = build_fold_indirect_ref (decl);
   13639              : 
   13640           75 :       im_info->mapper_clauses_p
   13641           75 :         = omp_instantiate_mapper (im_info->pre_p, ctx->implicit_mappers,
   13642              :                                   *mapper_p, decl, GOMP_MAP_TOFROM,
   13643              :                                   im_info->mapper_clauses_p);
   13644              :       /* Make sure we don't map the same variable implicitly in
   13645              :          gimplify_adjust_omp_clauses_1 also.  */
   13646           75 :       n->value |= GOVD_EXPLICIT;
   13647              :     }
   13648              : 
   13649              :   return 0;
   13650              : }
   13651              : 
   13652              : /* Scan the OMP clauses in *LIST_P, installing mappings into a new
   13653              :    and previous omp contexts.  */
   13654              : 
   13655              : static void
   13656       130565 : gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
   13657              :                            enum omp_region_type region_type,
   13658              :                            enum tree_code code,
   13659              :                            gimple_seq *loops_seq_p = NULL)
   13660              : {
   13661       130565 :   using namespace omp_addr_tokenizer;
   13662       130565 :   struct gimplify_omp_ctx *ctx, *outer_ctx;
   13663       130565 :   tree c;
   13664       130565 :   tree *orig_list_p = list_p;
   13665       130565 :   int handled_depend_iterators = -1;
   13666       130565 :   int nowait = -1;
   13667              : 
   13668       130565 :   ctx = new_omp_context (region_type);
   13669       130565 :   ctx->code = code;
   13670       130565 :   outer_ctx = ctx->outer_context;
   13671       130565 :   if (code == OMP_TARGET)
   13672              :     {
   13673        13492 :       if (!lang_GNU_Fortran ())
   13674        11146 :         ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
   13675        13492 :       ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
   13676        26984 :       ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
   13677        13492 :                                              ? GOVD_MAP : GOVD_FIRSTPRIVATE);
   13678              :     }
   13679       130565 :   if (!lang_GNU_Fortran ())
   13680        99341 :     switch (code)
   13681              :       {
   13682        18590 :       case OMP_TARGET:
   13683        18590 :       case OMP_TARGET_DATA:
   13684        18590 :       case OMP_TARGET_ENTER_DATA:
   13685        18590 :       case OMP_TARGET_EXIT_DATA:
   13686        18590 :       case OACC_DECLARE:
   13687        18590 :       case OACC_HOST_DATA:
   13688        18590 :       case OACC_PARALLEL:
   13689        18590 :       case OACC_KERNELS:
   13690        18590 :         ctx->target_firstprivatize_array_bases = true;
   13691              :       default:
   13692              :         break;
   13693              :       }
   13694              : 
   13695       130565 :   vec<omp_mapping_group> *groups = NULL;
   13696       130565 :   hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL;
   13697       130565 :   unsigned grpnum = 0;
   13698       130565 :   tree *grp_start_p = NULL, grp_end = NULL_TREE;
   13699              : 
   13700       130565 :   if (code == OMP_TARGET
   13701       130565 :       || code == OMP_TARGET_DATA
   13702       130565 :       || code == OMP_TARGET_ENTER_DATA
   13703              :       || code == OMP_TARGET_EXIT_DATA
   13704              :       || code == OACC_DATA
   13705              :       || code == OACC_KERNELS
   13706              :       || code == OACC_PARALLEL
   13707              :       || code == OACC_SERIAL
   13708              :       || code == OACC_ENTER_DATA
   13709              :       || code == OACC_EXIT_DATA
   13710              :       || code == OACC_UPDATE
   13711              :       || code == OACC_DECLARE)
   13712              :     {
   13713        33862 :       if (!(region_type & ORT_ACC))
   13714        17350 :         *list_p = omp_remove_duplicate_maps (*list_p, false);
   13715        33862 :       groups = omp_gather_mapping_groups (list_p);
   13716              : 
   13717        33862 :       if (groups)
   13718        18178 :         grpmap = omp_index_mapping_groups (groups);
   13719              :     }
   13720              : 
   13721       335975 :   while ((c = *list_p) != NULL)
   13722              :     {
   13723       205410 :       bool remove = false;
   13724       205410 :       bool notice_outer = true;
   13725       205410 :       bool map_descriptor;
   13726       205410 :       const char *check_non_private = NULL;
   13727       205410 :       unsigned int flags;
   13728       205410 :       tree decl;
   13729       205410 :       auto_vec<omp_addr_token *, 10> addr_tokens;
   13730       205410 :       tree op = NULL_TREE;
   13731       205410 :       location_t loc = OMP_CLAUSE_LOCATION (c);
   13732              : 
   13733       242899 :       if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end))
   13734              :         {
   13735              :           grp_start_p = NULL;
   13736              :           grp_end = NULL_TREE;
   13737              :         }
   13738              : 
   13739       205410 :       if (code == OMP_TARGET
   13740              :           || code == OMP_TARGET_DATA
   13741              :           || code == OMP_TARGET_ENTER_DATA
   13742       172823 :           || code == OMP_TARGET_EXIT_DATA)
   13743              :         /* Do some target-specific type checks for map operands.  */
   13744        35011 :         switch (OMP_CLAUSE_CODE (c))
   13745              :           {
   13746        25612 :           case OMP_CLAUSE_MAP:
   13747        25612 :             op = OMP_CLAUSE_OPERAND (c, 0);
   13748        25612 :             verify_type_context (loc, TCTX_OMP_MAP, TREE_TYPE (op));
   13749        25612 :             break;
   13750          180 :           case OMP_CLAUSE_PRIVATE:
   13751          180 :             op = OMP_CLAUSE_OPERAND (c, 0);
   13752          180 :             verify_type_context (loc, TCTX_OMP_PRIVATE, TREE_TYPE (op));
   13753          180 :             break;
   13754         1362 :           case OMP_CLAUSE_FIRSTPRIVATE:
   13755         1362 :             op = OMP_CLAUSE_OPERAND (c, 0);
   13756         1362 :             verify_type_context (loc, TCTX_OMP_FIRSTPRIVATE, TREE_TYPE (op));
   13757         1362 :             break;
   13758         2922 :           case OMP_CLAUSE_IS_DEVICE_PTR:
   13759         2922 :           case OMP_CLAUSE_USE_DEVICE_ADDR:
   13760         2922 :           case OMP_CLAUSE_USE_DEVICE_PTR:
   13761         2922 :           case OMP_CLAUSE_HAS_DEVICE_ADDR:
   13762         2922 :             op = OMP_CLAUSE_OPERAND (c, 0);
   13763         2922 :             verify_type_context (loc, TCTX_OMP_DEVICE_ADDR, TREE_TYPE (op));
   13764         2922 :             break;
   13765              :           default:
   13766              :             break;
   13767              :           }
   13768              : 
   13769       205410 :       switch (OMP_CLAUSE_CODE (c))
   13770              :         {
   13771        12231 :         case OMP_CLAUSE_PRIVATE:
   13772        12231 :           flags = GOVD_PRIVATE | GOVD_EXPLICIT;
   13773        12231 :           if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
   13774              :             {
   13775          167 :               flags |= GOVD_PRIVATE_OUTER_REF;
   13776          167 :               OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
   13777              :             }
   13778              :           else
   13779              :             notice_outer = false;
   13780        12231 :           goto do_add;
   13781         5536 :         case OMP_CLAUSE_SHARED:
   13782         5536 :           flags = GOVD_SHARED | GOVD_EXPLICIT;
   13783         5536 :           goto do_add;
   13784         8023 :         case OMP_CLAUSE_FIRSTPRIVATE:
   13785         8023 :           flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
   13786         8023 :           check_non_private = "firstprivate";
   13787         8023 :           if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   13788              :             {
   13789          380 :               gcc_assert (code == OMP_TARGET);
   13790              :               flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
   13791              :             }
   13792         8023 :           goto do_add;
   13793         7332 :         case OMP_CLAUSE_LASTPRIVATE:
   13794         7332 :           if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   13795          496 :             switch (code)
   13796              :               {
   13797           25 :               case OMP_DISTRIBUTE:
   13798           25 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13799              :                           "conditional %<lastprivate%> clause on "
   13800              :                           "%qs construct", "distribute");
   13801           25 :                 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
   13802           25 :                 break;
   13803           13 :               case OMP_TASKLOOP:
   13804           13 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13805              :                           "conditional %<lastprivate%> clause on "
   13806              :                           "%qs construct", "taskloop");
   13807           13 :                 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
   13808           13 :                 break;
   13809              :               default:
   13810              :                 break;
   13811              :               }
   13812         7332 :           flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
   13813         7332 :           if (code != OMP_LOOP)
   13814         6981 :             check_non_private = "lastprivate";
   13815         7332 :           decl = OMP_CLAUSE_DECL (c);
   13816         7332 :           if (error_operand_p (decl))
   13817            0 :             goto do_add;
   13818         7332 :           if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
   13819         7332 :               && !lang_hooks.decls.omp_scalar_p (decl, true))
   13820              :             {
   13821            5 :               error_at (OMP_CLAUSE_LOCATION (c),
   13822              :                         "non-scalar variable %qD in conditional "
   13823              :                         "%<lastprivate%> clause", decl);
   13824            5 :               OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
   13825              :             }
   13826         7332 :           if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   13827          453 :             flags |= GOVD_LASTPRIVATE_CONDITIONAL;
   13828         7332 :           omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
   13829              :                                                          false);
   13830         7332 :           goto do_add;
   13831        15220 :         case OMP_CLAUSE_REDUCTION:
   13832        15220 :           if (OMP_CLAUSE_REDUCTION_TASK (c))
   13833              :             {
   13834          595 :               if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
   13835              :                 {
   13836          408 :                   if (nowait == -1)
   13837          293 :                     nowait = omp_find_clause (*list_p,
   13838          293 :                                               OMP_CLAUSE_NOWAIT) != NULL_TREE;
   13839          408 :                   if (nowait
   13840           15 :                       && (outer_ctx == NULL
   13841            0 :                           || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
   13842              :                     {
   13843           15 :                       error_at (OMP_CLAUSE_LOCATION (c),
   13844              :                                 "%<task%> reduction modifier on a construct "
   13845              :                                 "with a %<nowait%> clause");
   13846           15 :                       OMP_CLAUSE_REDUCTION_TASK (c) = 0;
   13847              :                     }
   13848              :                 }
   13849          187 :               else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
   13850              :                 {
   13851           40 :                   error_at (OMP_CLAUSE_LOCATION (c),
   13852              :                             "invalid %<task%> reduction modifier on construct "
   13853              :                             "other than %<parallel%>, %qs, %<sections%> or "
   13854           20 :                             "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
   13855           20 :                   OMP_CLAUSE_REDUCTION_TASK (c) = 0;
   13856              :                 }
   13857              :             }
   13858        15220 :           if (OMP_CLAUSE_REDUCTION_INSCAN (c))
   13859          831 :             switch (code)
   13860              :               {
   13861            4 :               case OMP_SECTIONS:
   13862            4 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13863              :                           "%<inscan%> %<reduction%> clause on "
   13864              :                           "%qs construct", "sections");
   13865            4 :                 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   13866            4 :                 break;
   13867            4 :               case OMP_PARALLEL:
   13868            4 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13869              :                           "%<inscan%> %<reduction%> clause on "
   13870              :                           "%qs construct", "parallel");
   13871            4 :                 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   13872            4 :                 break;
   13873            4 :               case OMP_TEAMS:
   13874            4 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13875              :                           "%<inscan%> %<reduction%> clause on "
   13876              :                           "%qs construct", "teams");
   13877            4 :                 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   13878            4 :                 break;
   13879            4 :               case OMP_TASKLOOP:
   13880            4 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13881              :                           "%<inscan%> %<reduction%> clause on "
   13882              :                           "%qs construct", "taskloop");
   13883            4 :                 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   13884            4 :                 break;
   13885            4 :               case OMP_SCOPE:
   13886            4 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13887              :                           "%<inscan%> %<reduction%> clause on "
   13888              :                           "%qs construct", "scope");
   13889            4 :                 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   13890            4 :                 break;
   13891              :               default:
   13892              :                 break;
   13893              :               }
   13894              :           /* FALLTHRU */
   13895        17824 :         case OMP_CLAUSE_IN_REDUCTION:
   13896        17824 :         case OMP_CLAUSE_TASK_REDUCTION:
   13897        17824 :           flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
   13898              :           /* OpenACC permits reductions on private variables.  */
   13899        17824 :           if (!(region_type & ORT_ACC)
   13900              :               /* taskgroup is actually not a worksharing region.  */
   13901        12305 :               && code != OMP_TASKGROUP)
   13902        11775 :             check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
   13903        17824 :           decl = OMP_CLAUSE_DECL (c);
   13904        17824 :           if (TREE_CODE (decl) == MEM_REF)
   13905              :             {
   13906         2539 :               tree type = TREE_TYPE (decl);
   13907         2539 :               bool saved_into_ssa = gimplify_ctxp->into_ssa;
   13908         2539 :               gimplify_ctxp->into_ssa = false;
   13909         2539 :               if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
   13910              :                                  NULL, is_gimple_val, fb_rvalue, false)
   13911              :                   == GS_ERROR)
   13912              :                 {
   13913            0 :                   gimplify_ctxp->into_ssa = saved_into_ssa;
   13914            0 :                   remove = true;
   13915            0 :                   break;
   13916              :                 }
   13917         2539 :               gimplify_ctxp->into_ssa = saved_into_ssa;
   13918         2539 :               tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
   13919         2539 :               if (DECL_P (v))
   13920              :                 {
   13921          571 :                   omp_firstprivatize_variable (ctx, v);
   13922          571 :                   omp_notice_variable (ctx, v, true);
   13923              :                 }
   13924         2539 :               decl = TREE_OPERAND (decl, 0);
   13925         2539 :               if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
   13926              :                 {
   13927          477 :                   gimplify_ctxp->into_ssa = false;
   13928          477 :                   if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
   13929              :                                      NULL, is_gimple_val, fb_rvalue, false)
   13930              :                       == GS_ERROR)
   13931              :                     {
   13932            0 :                       gimplify_ctxp->into_ssa = saved_into_ssa;
   13933            0 :                       remove = true;
   13934            0 :                       break;
   13935              :                     }
   13936          477 :                   gimplify_ctxp->into_ssa = saved_into_ssa;
   13937          477 :                   v = TREE_OPERAND (decl, 1);
   13938          477 :                   if (DECL_P (v))
   13939              :                     {
   13940          477 :                       omp_firstprivatize_variable (ctx, v);
   13941          477 :                       omp_notice_variable (ctx, v, true);
   13942              :                     }
   13943          477 :                   decl = TREE_OPERAND (decl, 0);
   13944              :                 }
   13945         2539 :               if (TREE_CODE (decl) == ADDR_EXPR
   13946         1163 :                   || TREE_CODE (decl) == INDIRECT_REF)
   13947         1474 :                 decl = TREE_OPERAND (decl, 0);
   13948              :             }
   13949        17824 :           goto do_add_decl;
   13950         2668 :         case OMP_CLAUSE_LINEAR:
   13951         2668 :           if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
   13952              :                              is_gimple_val, fb_rvalue) == GS_ERROR)
   13953              :             {
   13954              :               remove = true;
   13955              :               break;
   13956              :             }
   13957              :           else
   13958              :             {
   13959         2668 :               if (code == OMP_SIMD
   13960         2668 :                   && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   13961              :                 {
   13962         1154 :                   struct gimplify_omp_ctx *octx = outer_ctx;
   13963         1154 :                   if (octx
   13964          741 :                       && octx->region_type == ORT_WORKSHARE
   13965          500 :                       && octx->combined_loop
   13966          500 :                       && !octx->distribute)
   13967              :                     {
   13968          492 :                       if (octx->outer_context
   13969          430 :                           && (octx->outer_context->region_type
   13970              :                               == ORT_COMBINED_PARALLEL))
   13971          393 :                         octx = octx->outer_context->outer_context;
   13972              :                       else
   13973              :                         octx = octx->outer_context;
   13974              :                     }
   13975          905 :                   if (octx
   13976          316 :                       && octx->region_type == ORT_WORKSHARE
   13977           16 :                       && octx->combined_loop
   13978           16 :                       && octx->distribute)
   13979              :                     {
   13980           16 :                       error_at (OMP_CLAUSE_LOCATION (c),
   13981              :                                 "%<linear%> clause for variable other than "
   13982              :                                 "loop iterator specified on construct "
   13983              :                                 "combined with %<distribute%>");
   13984           16 :                       remove = true;
   13985           16 :                       break;
   13986              :                     }
   13987              :                 }
   13988              :               /* For combined #pragma omp parallel for simd, need to put
   13989              :                  lastprivate and perhaps firstprivate too on the
   13990              :                  parallel.  Similarly for #pragma omp for simd.  */
   13991              :               struct gimplify_omp_ctx *octx = outer_ctx;
   13992              :               bool taskloop_seen = false;
   13993              :               decl = NULL_TREE;
   13994         3443 :               do
   13995              :                 {
   13996         3443 :                   if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
   13997         3443 :                       && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   13998              :                     break;
   13999         3383 :                   decl = OMP_CLAUSE_DECL (c);
   14000         3383 :                   if (error_operand_p (decl))
   14001              :                     {
   14002              :                       decl = NULL_TREE;
   14003              :                       break;
   14004              :                     }
   14005         3383 :                   flags = GOVD_SEEN;
   14006         3383 :                   if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   14007         1672 :                     flags |= GOVD_FIRSTPRIVATE;
   14008         3383 :                   if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   14009         3383 :                     flags |= GOVD_LASTPRIVATE;
   14010         3383 :                   if (octx
   14011         2506 :                       && octx->region_type == ORT_WORKSHARE
   14012         1213 :                       && octx->combined_loop)
   14013              :                     {
   14014         1207 :                       if (octx->outer_context
   14015         1037 :                           && (octx->outer_context->region_type
   14016              :                               == ORT_COMBINED_PARALLEL))
   14017              :                         octx = octx->outer_context;
   14018          476 :                       else if (omp_check_private (octx, decl, false))
   14019              :                         break;
   14020              :                     }
   14021              :                   else if (octx
   14022         1299 :                            && (octx->region_type & ORT_TASK) != 0
   14023          307 :                            && octx->combined_loop)
   14024              :                     taskloop_seen = true;
   14025              :                   else if (octx
   14026          996 :                            && octx->region_type == ORT_COMBINED_PARALLEL
   14027          301 :                            && ((ctx->region_type == ORT_WORKSHARE
   14028          201 :                                 && octx == outer_ctx)
   14029          100 :                                || taskloop_seen))
   14030              :                     flags = GOVD_SEEN | GOVD_SHARED;
   14031              :                   else if (octx
   14032          695 :                            && ((octx->region_type & ORT_COMBINED_TEAMS)
   14033              :                                == ORT_COMBINED_TEAMS))
   14034              :                     flags = GOVD_SEEN | GOVD_SHARED;
   14035          540 :                   else if (octx
   14036          540 :                            && octx->region_type == ORT_COMBINED_TARGET)
   14037              :                     {
   14038          195 :                       if (flags & GOVD_LASTPRIVATE)
   14039          195 :                         flags = GOVD_SEEN | GOVD_MAP;
   14040              :                     }
   14041              :                   else
   14042              :                     break;
   14043         2071 :                   splay_tree_node on
   14044         2071 :                     = splay_tree_lookup (octx->variables,
   14045              :                                          (splay_tree_key) decl);
   14046         2071 :                   if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
   14047              :                     {
   14048              :                       octx = NULL;
   14049              :                       break;
   14050              :                     }
   14051         2067 :                   omp_add_variable (octx, decl, flags);
   14052         2067 :                   if (octx->outer_context == NULL)
   14053              :                     break;
   14054              :                   octx = octx->outer_context;
   14055              :                 }
   14056              :               while (1);
   14057         2652 :               if (octx
   14058         2652 :                   && decl
   14059         2652 :                   && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
   14060          728 :                       || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
   14061         1711 :                 omp_notice_variable (octx, decl, true);
   14062              :             }
   14063         2652 :           flags = GOVD_LINEAR | GOVD_EXPLICIT;
   14064         2652 :           if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
   14065         2652 :               && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   14066              :             {
   14067              :               notice_outer = false;
   14068              :               flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   14069              :             }
   14070         2652 :           goto do_add;
   14071              : 
   14072        51197 :         case OMP_CLAUSE_MAP:
   14073        51197 :           if (!grp_start_p)
   14074              :             {
   14075        31023 :               grp_start_p = list_p;
   14076        31023 :               grp_end = (*groups)[grpnum].grp_end;
   14077        31023 :               grpnum++;
   14078              :             }
   14079        51197 :           decl = OMP_CLAUSE_DECL (c);
   14080              : 
   14081        51197 :           if (error_operand_p (decl))
   14082              :             {
   14083              :               remove = true;
   14084              :               break;
   14085              :             }
   14086              : 
   14087        51197 :           if (!omp_parse_expr (addr_tokens, decl))
   14088              :             {
   14089              :               remove = true;
   14090              :               break;
   14091              :             }
   14092              : 
   14093        51197 :           if (remove)
   14094              :             break;
   14095        51197 :           if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
   14096              :             {
   14097              :               struct gimplify_omp_ctx *octx;
   14098         1167 :               for (octx = outer_ctx; octx; octx = octx->outer_context)
   14099              :                 {
   14100         1167 :                   if (octx->region_type != ORT_ACC_HOST_DATA)
   14101              :                     break;
   14102           12 :                   splay_tree_node n2
   14103           12 :                     = splay_tree_lookup (octx->variables,
   14104              :                                          (splay_tree_key) decl);
   14105           12 :                   if (n2)
   14106            4 :                     error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
   14107              :                               "declared in enclosing %<host_data%> region",
   14108            4 :                               DECL_NAME (decl));
   14109              :                 }
   14110              :             }
   14111              : 
   14112        51197 :           map_descriptor = false;
   14113              : 
   14114              :           /* This condition checks if we're mapping an array descriptor that
   14115              :              isn't inside a derived type -- these have special handling, and
   14116              :              are not handled as structs in omp_build_struct_sibling_lists.
   14117              :              See that function for further details.  */
   14118        51197 :           if (*grp_start_p != grp_end
   14119        34170 :               && OMP_CLAUSE_CHAIN (*grp_start_p)
   14120        85367 :               && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
   14121              :             {
   14122        17096 :               tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p);
   14123        17096 :               if (omp_map_clause_descriptor_p (grp_mid)
   14124        32365 :                   && DECL_P (OMP_CLAUSE_DECL (grp_mid)))
   14125              :                 map_descriptor = true;
   14126              :             }
   14127        34101 :           else if (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP
   14128        34101 :                    && (OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_RELEASE
   14129        33357 :                        || OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_DELETE)
   14130        35023 :                    && OMP_CLAUSE_RELEASE_DESCRIPTOR (grp_end))
   14131              :             map_descriptor = true;
   14132              : 
   14133              :           /* Adding the decl for a struct access: we haven't created
   14134              :              GOMP_MAP_STRUCT nodes yet, so this statement needs to predict
   14135              :              whether they will be created in gimplify_adjust_omp_clauses.
   14136              :              NOTE: Technically we should probably look through DECL_VALUE_EXPR
   14137              :              here because something that looks like a DECL_P may actually be a
   14138              :              struct access, e.g. variables in a lambda closure
   14139              :              (__closure->__foo) or class members (this->foo). Currently in both
   14140              :              those cases we map the whole of the containing object (directly in
   14141              :              the C++ FE) though, so struct nodes are not created.  */
   14142        51197 :           if (c == grp_end
   14143        31023 :               && addr_tokens[0]->type == STRUCTURE_BASE
   14144         8396 :               && addr_tokens[0]->u.structure_base_kind == BASE_DECL
   14145        59593 :               && !map_descriptor)
   14146              :             {
   14147         5592 :               gcc_assert (addr_tokens[1]->type == ACCESS_METHOD);
   14148              :               /* If we got to this struct via a chain of pointers, maybe we
   14149              :                  want to map it implicitly instead.  */
   14150         5592 :               if (omp_access_chain_p (addr_tokens, 1))
   14151              :                 break;
   14152         5431 :               omp_mapping_group *wholestruct;
   14153         5431 :               if (!(region_type & ORT_ACC)
   14154         9587 :                   && omp_mapped_by_containing_struct (grpmap,
   14155         4156 :                                                       OMP_CLAUSE_DECL (c),
   14156              :                                                       &wholestruct))
   14157              :                 break;
   14158         5195 :               decl = addr_tokens[1]->expr;
   14159         5195 :               if (splay_tree_lookup (ctx->variables, (splay_tree_key) decl))
   14160              :                 break;
   14161              :               /* Standalone attach or detach clauses for a struct element
   14162              :                  should not inhibit implicit mapping of the whole struct.  */
   14163         2983 :               if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   14164         2983 :                   || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
   14165              :                 break;
   14166         2833 :               flags = GOVD_MAP | GOVD_EXPLICIT;
   14167              : 
   14168         2833 :               gcc_assert (addr_tokens[1]->u.access_kind != ACCESS_DIRECT
   14169              :                           || TREE_ADDRESSABLE (decl));
   14170         2833 :               goto do_add_decl;
   14171              :             }
   14172              : 
   14173        45605 :           if (!DECL_P (decl))
   14174              :             {
   14175        21080 :               tree d = decl, *pd;
   14176        21080 :               if (TREE_CODE (d) == ARRAY_REF)
   14177              :                 {
   14178         5022 :                   while (TREE_CODE (d) == ARRAY_REF)
   14179         2568 :                     d = TREE_OPERAND (d, 0);
   14180         2454 :                   if (TREE_CODE (d) == COMPONENT_REF
   14181         2454 :                       && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
   14182              :                     decl = d;
   14183              :                 }
   14184        21080 :               pd = &OMP_CLAUSE_DECL (c);
   14185        21080 :               if (d == decl
   14186        18672 :                   && TREE_CODE (decl) == INDIRECT_REF
   14187        13936 :                   && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   14188         1069 :                   && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   14189              :                       == REFERENCE_TYPE)
   14190        21731 :                   && (OMP_CLAUSE_MAP_KIND (c)
   14191              :                       != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
   14192              :                 {
   14193          647 :                   pd = &TREE_OPERAND (decl, 0);
   14194          647 :                   decl = TREE_OPERAND (decl, 0);
   14195              :                 }
   14196              : 
   14197        21080 :               if (addr_tokens[0]->type == STRUCTURE_BASE
   14198        11439 :                   && addr_tokens[0]->u.structure_base_kind == BASE_DECL
   14199        11438 :                   && addr_tokens[1]->type == ACCESS_METHOD
   14200        11438 :                   && (addr_tokens[1]->u.access_kind == ACCESS_POINTER
   14201        10940 :                       || (addr_tokens[1]->u.access_kind
   14202              :                           == ACCESS_POINTER_OFFSET))
   14203        21660 :                   && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)))
   14204              :                 {
   14205            0 :                   tree base = addr_tokens[1]->expr;
   14206            0 :                   splay_tree_node n
   14207            0 :                     = splay_tree_lookup (ctx->variables,
   14208              :                                          (splay_tree_key) base);
   14209            0 :                   n->value |= GOVD_SEEN;
   14210              :                 }
   14211              : 
   14212        21080 :               if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
   14213              :                 {
   14214              :                   /* Don't gimplify *pd fully at this point, as the base
   14215              :                      will need to be adjusted during omp lowering.  */
   14216           88 :                   auto_vec<tree, 10> expr_stack;
   14217           88 :                   tree *p = pd;
   14218           88 :                   while (handled_component_p (*p)
   14219              :                          || TREE_CODE (*p) == INDIRECT_REF
   14220              :                          || TREE_CODE (*p) == ADDR_EXPR
   14221              :                          || TREE_CODE (*p) == MEM_REF
   14222          224 :                          || TREE_CODE (*p) == NON_LVALUE_EXPR)
   14223              :                     {
   14224          136 :                       expr_stack.safe_push (*p);
   14225          136 :                       p = &TREE_OPERAND (*p, 0);
   14226              :                     }
   14227          312 :                   for (int i = expr_stack.length () - 1; i >= 0; i--)
   14228              :                     {
   14229          136 :                       tree t = expr_stack[i];
   14230          136 :                       if (TREE_CODE (t) == ARRAY_REF
   14231          136 :                           || TREE_CODE (t) == ARRAY_RANGE_REF)
   14232              :                         {
   14233           56 :                           if (TREE_OPERAND (t, 2) == NULL_TREE)
   14234              :                             {
   14235           56 :                               tree low = unshare_expr (array_ref_low_bound (t));
   14236           56 :                               if (!is_gimple_min_invariant (low))
   14237              :                                 {
   14238            0 :                                   TREE_OPERAND (t, 2) = low;
   14239            0 :                                   if (gimplify_expr (&TREE_OPERAND (t, 2),
   14240              :                                                      pre_p, NULL,
   14241              :                                                      is_gimple_reg,
   14242              :                                                      fb_rvalue) == GS_ERROR)
   14243            0 :                                     remove = true;
   14244              :                                 }
   14245              :                             }
   14246            0 :                           else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
   14247              :                                                   NULL, is_gimple_reg,
   14248              :                                                   fb_rvalue) == GS_ERROR)
   14249            0 :                             remove = true;
   14250           56 :                           if (TREE_OPERAND (t, 3) == NULL_TREE)
   14251              :                             {
   14252           56 :                               tree elmt_size = array_ref_element_size (t);
   14253           56 :                               if (!is_gimple_min_invariant (elmt_size))
   14254              :                                 {
   14255            0 :                                   elmt_size = unshare_expr (elmt_size);
   14256            0 :                                   tree elmt_type
   14257            0 :                                     = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
   14258              :                                                                           0)));
   14259            0 :                                   tree factor
   14260            0 :                                     = size_int (TYPE_ALIGN_UNIT (elmt_type));
   14261            0 :                                   elmt_size
   14262            0 :                                     = size_binop (EXACT_DIV_EXPR, elmt_size,
   14263              :                                                   factor);
   14264            0 :                                   TREE_OPERAND (t, 3) = elmt_size;
   14265            0 :                                   if (gimplify_expr (&TREE_OPERAND (t, 3),
   14266              :                                                      pre_p, NULL,
   14267              :                                                      is_gimple_reg,
   14268              :                                                      fb_rvalue) == GS_ERROR)
   14269            0 :                                     remove = true;
   14270              :                                 }
   14271              :                             }
   14272            0 :                           else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
   14273              :                                                   NULL, is_gimple_reg,
   14274              :                                                   fb_rvalue) == GS_ERROR)
   14275            0 :                             remove = true;
   14276              :                         }
   14277           80 :                       else if (TREE_CODE (t) == COMPONENT_REF)
   14278              :                         {
   14279            0 :                           if (TREE_OPERAND (t, 2) == NULL_TREE)
   14280              :                             {
   14281            0 :                               tree offset = component_ref_field_offset (t);
   14282            0 :                               if (!is_gimple_min_invariant (offset))
   14283              :                                 {
   14284            0 :                                   offset = unshare_expr (offset);
   14285            0 :                                   tree field = TREE_OPERAND (t, 1);
   14286            0 :                                   tree factor
   14287            0 :                                     = size_int (DECL_OFFSET_ALIGN (field)
   14288              :                                                 / BITS_PER_UNIT);
   14289            0 :                                   offset = size_binop (EXACT_DIV_EXPR, offset,
   14290              :                                                        factor);
   14291            0 :                                   TREE_OPERAND (t, 2) = offset;
   14292            0 :                                   if (gimplify_expr (&TREE_OPERAND (t, 2),
   14293              :                                                      pre_p, NULL,
   14294              :                                                      is_gimple_reg,
   14295              :                                                      fb_rvalue) == GS_ERROR)
   14296            0 :                                     remove = true;
   14297              :                                 }
   14298              :                             }
   14299            0 :                           else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
   14300              :                                                   NULL, is_gimple_reg,
   14301              :                                                   fb_rvalue) == GS_ERROR)
   14302            0 :                             remove = true;
   14303              :                         }
   14304              :                     }
   14305          224 :                   for (; expr_stack.length () > 0; )
   14306              :                     {
   14307          136 :                       tree t = expr_stack.pop ();
   14308              : 
   14309          136 :                       if (TREE_CODE (t) == ARRAY_REF
   14310          136 :                           || TREE_CODE (t) == ARRAY_RANGE_REF)
   14311              :                         {
   14312           56 :                           if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
   14313           56 :                               && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
   14314              :                                                 NULL, is_gimple_val,
   14315              :                                                 fb_rvalue) == GS_ERROR)
   14316          144 :                             remove = true;
   14317              :                         }
   14318              :                     }
   14319           88 :                 }
   14320              :               break;
   14321              :             }
   14322              : 
   14323        24525 :           if ((code == OMP_TARGET
   14324              :                || code == OMP_TARGET_DATA
   14325              :                || code == OMP_TARGET_ENTER_DATA
   14326        14224 :                || code == OMP_TARGET_EXIT_DATA)
   14327        25162 :               && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   14328              :             {
   14329              :               /* If we have attach/detach but the decl we have is a pointer to
   14330              :                  pointer, we're probably mapping the "base level" array
   14331              :                  implicitly.  Make sure we don't add the decl as if we mapped
   14332              :                  it explicitly.  That is,
   14333              : 
   14334              :                    int **arr;
   14335              :                    [...]
   14336              :                    #pragma omp target map(arr[a][b:c])
   14337              : 
   14338              :                  should *not* map "arr" explicitly.  That way we get a
   14339              :                  zero-length "alloc" mapping for it, and assuming it's been
   14340              :                  mapped by some previous directive, etc., things work as they
   14341              :                  should.  */
   14342              : 
   14343          213 :               tree basetype = TREE_TYPE (addr_tokens[0]->expr);
   14344              : 
   14345          213 :               if (TREE_CODE (basetype) == REFERENCE_TYPE)
   14346           34 :                 basetype = TREE_TYPE (basetype);
   14347              : 
   14348          213 :               if (code == OMP_TARGET
   14349           54 :                   && addr_tokens[0]->type == ARRAY_BASE
   14350           54 :                   && addr_tokens[0]->u.structure_base_kind == BASE_DECL
   14351           54 :                   && TREE_CODE (basetype) == POINTER_TYPE
   14352          267 :                   && TREE_CODE (TREE_TYPE (basetype)) == POINTER_TYPE)
   14353              :                 break;
   14354              :             }
   14355              : 
   14356        24503 :           flags = GOVD_MAP | GOVD_EXPLICIT;
   14357        24503 :           if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
   14358        24368 :               || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM
   14359        23864 :               || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TO
   14360        48337 :               || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TOFROM)
   14361              :             flags |= GOVD_MAP_ALWAYS_TO;
   14362              : 
   14363        24503 :           goto do_add;
   14364              : 
   14365          374 :         case OMP_CLAUSE_AFFINITY:
   14366          374 :           gimplify_omp_affinity (list_p, pre_p);
   14367          374 :           remove = true;
   14368          374 :           break;
   14369            8 :         case OMP_CLAUSE_DOACROSS:
   14370            8 :           if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
   14371              :             {
   14372            4 :               tree deps = OMP_CLAUSE_DECL (c);
   14373            8 :               while (deps && TREE_CODE (deps) == TREE_LIST)
   14374              :                 {
   14375            4 :                   if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
   14376            4 :                       && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
   14377            0 :                     gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
   14378              :                                    pre_p, NULL, is_gimple_val, fb_rvalue);
   14379            4 :                   deps = TREE_CHAIN (deps);
   14380              :                 }
   14381              :             }
   14382              :           else
   14383            4 :             gcc_assert (OMP_CLAUSE_DOACROSS_KIND (c)
   14384              :                         == OMP_CLAUSE_DOACROSS_SOURCE);
   14385              :           break;
   14386         2207 :         case OMP_CLAUSE_DEPEND:
   14387         2207 :           if (handled_depend_iterators == -1)
   14388         1905 :             handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
   14389         2207 :           if (handled_depend_iterators)
   14390              :             {
   14391          348 :               if (handled_depend_iterators == 2)
   14392            0 :                 remove = true;
   14393              :               break;
   14394              :             }
   14395         1859 :           if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
   14396              :             {
   14397            0 :               gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
   14398              :                              NULL, is_gimple_val, fb_rvalue);
   14399            0 :               OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
   14400              :             }
   14401         1859 :           if (error_operand_p (OMP_CLAUSE_DECL (c)))
   14402              :             {
   14403              :               remove = true;
   14404              :               break;
   14405              :             }
   14406         1859 :           if (OMP_CLAUSE_DECL (c) != null_pointer_node)
   14407              :             {
   14408         1828 :               OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
   14409         1828 :               if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
   14410              :                                  is_gimple_val, fb_rvalue) == GS_ERROR)
   14411              :                 {
   14412              :                   remove = true;
   14413              :                   break;
   14414              :                 }
   14415              :             }
   14416         1859 :           if (code == OMP_TASK)
   14417         1401 :             ctx->has_depend = true;
   14418              :           break;
   14419              : 
   14420         8333 :         case OMP_CLAUSE_TO:
   14421         8333 :         case OMP_CLAUSE_FROM:
   14422         8333 :         case OMP_CLAUSE__CACHE_:
   14423         8333 :           decl = OMP_CLAUSE_DECL (c);
   14424         8333 :           if (error_operand_p (decl))
   14425              :             {
   14426              :               remove = true;
   14427              :               break;
   14428              :             }
   14429         8333 :           if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   14430         7660 :             OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
   14431          796 :                                   : TYPE_SIZE_UNIT (TREE_TYPE (decl));
   14432         8333 :           gimple_seq *seq_p;
   14433         8333 :           seq_p = enter_omp_iterator_loop_context (c, loops_seq_p, pre_p);
   14434         8333 :           if (gimplify_expr (&OMP_CLAUSE_SIZE (c), seq_p, NULL,
   14435              :                              is_gimple_val, fb_rvalue) == GS_ERROR)
   14436              :             {
   14437            0 :               remove = true;
   14438            0 :               exit_omp_iterator_loop_context (c);
   14439            0 :               break;
   14440              :             }
   14441         8333 :           if (!DECL_P (decl))
   14442              :             {
   14443         2144 :               if (gimplify_expr (&OMP_CLAUSE_DECL (c), seq_p, NULL,
   14444              :                                  is_gimple_lvalue, fb_lvalue) == GS_ERROR)
   14445            0 :                 remove = true;
   14446         2144 :               exit_omp_iterator_loop_context (c);
   14447         2144 :               break;
   14448              :             }
   14449         6189 :           exit_omp_iterator_loop_context (c);
   14450         6189 :           goto do_notice;
   14451              : 
   14452          135 :         case OMP_CLAUSE__MAPPER_BINDING_:
   14453          135 :           {
   14454          135 :             tree name = OMP_CLAUSE__MAPPER_BINDING__ID (c);
   14455          135 :             tree var = OMP_CLAUSE__MAPPER_BINDING__DECL (c);
   14456          135 :             tree type = TYPE_MAIN_VARIANT (TREE_TYPE (var));
   14457          135 :             tree fndecl = OMP_CLAUSE__MAPPER_BINDING__MAPPER (c);
   14458          135 :             ctx->implicit_mappers->put ({ name, type }, fndecl);
   14459          135 :             remove = true;
   14460          135 :             break;
   14461              :           }
   14462              : 
   14463         2118 :         case OMP_CLAUSE_USE_DEVICE_PTR:
   14464         2118 :         case OMP_CLAUSE_USE_DEVICE_ADDR:
   14465         2118 :           flags = GOVD_EXPLICIT;
   14466         2118 :           goto do_add;
   14467              : 
   14468          557 :         case OMP_CLAUSE_HAS_DEVICE_ADDR:
   14469          557 :           decl = OMP_CLAUSE_DECL (c);
   14470          557 :           while (TREE_CODE (decl) == INDIRECT_REF
   14471          606 :                  || TREE_CODE (decl) == ARRAY_REF)
   14472           49 :             decl = TREE_OPERAND (decl, 0);
   14473          557 :           flags = GOVD_EXPLICIT;
   14474          557 :           goto do_add_decl;
   14475              : 
   14476          500 :         case OMP_CLAUSE_IS_DEVICE_PTR:
   14477          500 :           flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
   14478          500 :           goto do_add;
   14479              : 
   14480        63085 :         do_add:
   14481        63085 :           decl = OMP_CLAUSE_DECL (c);
   14482        84299 :         do_add_decl:
   14483        84299 :           if (error_operand_p (decl))
   14484              :             {
   14485              :               remove = true;
   14486              :               break;
   14487              :             }
   14488        84291 :           if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
   14489              :             {
   14490         1755 :               tree t = omp_member_access_dummy_var (decl);
   14491         1755 :               if (t)
   14492              :                 {
   14493          668 :                   tree v = DECL_VALUE_EXPR (decl);
   14494          668 :                   DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
   14495          668 :                   if (outer_ctx)
   14496          140 :                     omp_notice_variable (outer_ctx, t, true);
   14497              :                 }
   14498              :             }
   14499        84291 :           if (code == OACC_DATA
   14500         2402 :               && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   14501        86693 :               && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
   14502          307 :             flags |= GOVD_MAP_0LEN_ARRAY;
   14503        84291 :           omp_add_variable (ctx, decl, flags);
   14504        84291 :           if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   14505        69071 :                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
   14506        66997 :                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
   14507        86895 :               && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   14508              :             {
   14509         2093 :               struct gimplify_omp_ctx *pctx
   14510         2153 :                 = code == OMP_TARGET ? outer_ctx : ctx;
   14511         2153 :               if (pctx)
   14512         2123 :                 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
   14513              :                                   GOVD_LOCAL | GOVD_SEEN);
   14514         2123 :               if (pctx
   14515         2123 :                   && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
   14516          632 :                   && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
   14517              :                                 find_decl_expr,
   14518              :                                 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
   14519              :                                 NULL) == NULL_TREE)
   14520          208 :                 omp_add_variable (pctx,
   14521          208 :                                   OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
   14522              :                                   GOVD_LOCAL | GOVD_SEEN);
   14523         2153 :               gimplify_omp_ctxp = pctx;
   14524         2153 :               push_gimplify_context ();
   14525              : 
   14526         2153 :               OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
   14527         2153 :               OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
   14528              : 
   14529         2153 :               gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
   14530         2153 :                                 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
   14531         2153 :               pop_gimplify_context
   14532         2153 :                 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
   14533         2153 :               push_gimplify_context ();
   14534         4306 :               gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
   14535         2153 :                                 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
   14536         2153 :               pop_gimplify_context
   14537         2153 :                 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
   14538         2153 :               OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
   14539         2153 :               OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
   14540              : 
   14541         2153 :               gimplify_omp_ctxp = outer_ctx;
   14542              :             }
   14543        82138 :           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   14544        82138 :                    && OMP_CLAUSE_LASTPRIVATE_STMT (c))
   14545              :             {
   14546          303 :               gimplify_omp_ctxp = ctx;
   14547          303 :               push_gimplify_context ();
   14548          303 :               if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
   14549              :                 {
   14550          303 :                   tree bind = build3 (BIND_EXPR, void_type_node, NULL,
   14551              :                                       NULL, NULL);
   14552          303 :                   TREE_SIDE_EFFECTS (bind) = 1;
   14553          303 :                   BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
   14554          303 :                   OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
   14555              :                 }
   14556          606 :               gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
   14557          303 :                                 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
   14558          303 :               pop_gimplify_context
   14559          303 :                 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
   14560          303 :               OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
   14561              : 
   14562          303 :               gimplify_omp_ctxp = outer_ctx;
   14563              :             }
   14564        81835 :           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   14565        81835 :                    && OMP_CLAUSE_LINEAR_STMT (c))
   14566              :             {
   14567           60 :               gimplify_omp_ctxp = ctx;
   14568           60 :               push_gimplify_context ();
   14569           60 :               if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
   14570              :                 {
   14571           60 :                   tree bind = build3 (BIND_EXPR, void_type_node, NULL,
   14572              :                                       NULL, NULL);
   14573           60 :                   TREE_SIDE_EFFECTS (bind) = 1;
   14574           60 :                   BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
   14575           60 :                   OMP_CLAUSE_LINEAR_STMT (c) = bind;
   14576              :                 }
   14577          120 :               gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
   14578           60 :                                 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
   14579           60 :               pop_gimplify_context
   14580           60 :                 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
   14581           60 :               OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
   14582              : 
   14583           60 :               gimplify_omp_ctxp = outer_ctx;
   14584              :             }
   14585        84291 :           if (notice_outer)
   14586        72167 :             goto do_notice;
   14587              :           break;
   14588              : 
   14589          906 :         case OMP_CLAUSE_COPYIN:
   14590          906 :         case OMP_CLAUSE_COPYPRIVATE:
   14591          906 :           decl = OMP_CLAUSE_DECL (c);
   14592          906 :           if (error_operand_p (decl))
   14593              :             {
   14594              :               remove = true;
   14595              :               break;
   14596              :             }
   14597          906 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
   14598              :               && !remove
   14599          906 :               && !omp_check_private (ctx, decl, true))
   14600              :             {
   14601           35 :               remove = true;
   14602           35 :               if (is_global_var (decl))
   14603              :                 {
   14604           30 :                   if (DECL_THREAD_LOCAL_P (decl))
   14605              :                     remove = false;
   14606           10 :                   else if (DECL_HAS_VALUE_EXPR_P (decl))
   14607              :                     {
   14608            2 :                       tree value = get_base_address (DECL_VALUE_EXPR (decl));
   14609              : 
   14610            2 :                       if (value
   14611            2 :                           && DECL_P (value)
   14612            4 :                           && DECL_THREAD_LOCAL_P (value))
   14613              :                         remove = false;
   14614              :                     }
   14615              :                 }
   14616              :               if (remove)
   14617           13 :                 error_at (OMP_CLAUSE_LOCATION (c),
   14618              :                           "copyprivate variable %qE is not threadprivate"
   14619           13 :                           " or private in outer context", DECL_NAME (decl));
   14620              :             }
   14621        79262 :         do_notice:
   14622        79262 :           if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   14623        64042 :                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
   14624        56019 :                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
   14625        30575 :               && outer_ctx
   14626        17547 :               && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
   14627        16208 :                    || (region_type == ORT_WORKSHARE
   14628         3884 :                        && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   14629         1087 :                        && (OMP_CLAUSE_REDUCTION_INSCAN (c)
   14630          912 :                            || code == OMP_LOOP)))
   14631        81207 :               && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
   14632          857 :                   || (code == OMP_LOOP
   14633          138 :                       && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   14634          138 :                       && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
   14635              :                           == ORT_COMBINED_TEAMS))))
   14636              :             {
   14637         1209 :               splay_tree_node on
   14638         1209 :                 = splay_tree_lookup (outer_ctx->variables,
   14639              :                                      (splay_tree_key)decl);
   14640         1209 :               if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
   14641              :                 {
   14642          891 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   14643          705 :                       && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
   14644         1003 :                       && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
   14645           56 :                           || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   14646            0 :                               && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
   14647              :                                   == POINTER_TYPE))))
   14648           56 :                     omp_firstprivatize_variable (outer_ctx, decl);
   14649              :                   else
   14650              :                     {
   14651          835 :                       omp_add_variable (outer_ctx, decl,
   14652              :                                         GOVD_SEEN | GOVD_SHARED);
   14653          835 :                       if (outer_ctx->outer_context)
   14654          235 :                         omp_notice_variable (outer_ctx->outer_context, decl,
   14655              :                                              true);
   14656              :                     }
   14657              :                 }
   14658              :             }
   14659        78662 :           if (outer_ctx)
   14660        29585 :             omp_notice_variable (outer_ctx, decl, true);
   14661        79262 :           if (check_non_private
   14662        26779 :               && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
   14663         4747 :               && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
   14664         1641 :                   || decl == OMP_CLAUSE_DECL (c)
   14665          224 :                   || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
   14666          224 :                       && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
   14667              :                           == ADDR_EXPR
   14668          103 :                           || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
   14669              :                               == POINTER_PLUS_EXPR
   14670           22 :                               && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
   14671              :                                                 (OMP_CLAUSE_DECL (c), 0), 0))
   14672              :                                   == ADDR_EXPR)))))
   14673        83921 :               && omp_check_private (ctx, decl, false))
   14674              :             {
   14675           58 :               error ("%s variable %qE is private in outer context",
   14676           29 :                      check_non_private, DECL_NAME (decl));
   14677           29 :               remove = true;
   14678              :             }
   14679              :           break;
   14680              : 
   14681          190 :         case OMP_CLAUSE_DETACH:
   14682          190 :           flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
   14683          190 :           goto do_add;
   14684              : 
   14685         4108 :         case OMP_CLAUSE_IF:
   14686         4108 :           if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
   14687         4108 :               && OMP_CLAUSE_IF_MODIFIER (c) != code)
   14688              :             {
   14689              :               const char *p[2];
   14690          168 :               for (int i = 0; i < 2; i++)
   14691          112 :                 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
   14692              :                   {
   14693            8 :                   case VOID_CST: p[i] = "cancel"; break;
   14694           24 :                   case OMP_PARALLEL: p[i] = "parallel"; break;
   14695            4 :                   case OMP_SIMD: p[i] = "simd"; break;
   14696           12 :                   case OMP_TASK: p[i] = "task"; break;
   14697           12 :                   case OMP_TASKLOOP: p[i] = "taskloop"; break;
   14698            8 :                   case OMP_TARGET_DATA: p[i] = "target data"; break;
   14699           12 :                   case OMP_TARGET: p[i] = "target"; break;
   14700           12 :                   case OMP_TARGET_UPDATE: p[i] = "target update"; break;
   14701            8 :                   case OMP_TARGET_ENTER_DATA:
   14702            8 :                     p[i] = "target enter data"; break;
   14703           12 :                   case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
   14704            0 :                   default: gcc_unreachable ();
   14705              :                   }
   14706           56 :               error_at (OMP_CLAUSE_LOCATION (c),
   14707              :                         "expected %qs %<if%> clause modifier rather than %qs",
   14708              :                         p[0], p[1]);
   14709           56 :               remove = true;
   14710              :             }
   14711              :           /* Fall through.  */
   14712              : 
   14713         4818 :         case OMP_CLAUSE_SELF:
   14714         4818 :         case OMP_CLAUSE_FINAL:
   14715         4818 :           OMP_CLAUSE_OPERAND (c, 0)
   14716         9636 :             = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
   14717              :           /* Fall through.  */
   14718              : 
   14719         5721 :         case OMP_CLAUSE_NUM_TEAMS:
   14720         5721 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
   14721          903 :               && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
   14722         5966 :               && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
   14723              :             {
   14724          208 :               if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
   14725              :                 {
   14726              :                   remove = true;
   14727              :                   break;
   14728              :                 }
   14729          208 :               OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
   14730          416 :                 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
   14731              :                                            pre_p, NULL, true);
   14732              :             }
   14733              :           /* Fall through.  */
   14734              : 
   14735        21802 :         case OMP_CLAUSE_SCHEDULE:
   14736        21802 :         case OMP_CLAUSE_NUM_THREADS:
   14737        21802 :         case OMP_CLAUSE_THREAD_LIMIT:
   14738        21802 :         case OMP_CLAUSE_DIST_SCHEDULE:
   14739        21802 :         case OMP_CLAUSE_DEVICE:
   14740        21802 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
   14741        21802 :               && OMP_CLAUSE_DEVICE_ANCESTOR (c))
   14742              :             {
   14743          125 :               if (code != OMP_TARGET)
   14744              :                 {
   14745           20 :                   error_at (OMP_CLAUSE_LOCATION (c),
   14746              :                             "%<device%> clause with %<ancestor%> is only "
   14747              :                             "allowed on %<target%> construct");
   14748           20 :                   remove = true;
   14749           20 :                   break;
   14750              :                 }
   14751              : 
   14752          105 :               tree clauses = *orig_list_p;
   14753          330 :               for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
   14754          236 :                 if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
   14755              :                     && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
   14756              :                     && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
   14757              :                     && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
   14758              :                     && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
   14759              :                    )
   14760              :                   {
   14761           11 :                     error_at (OMP_CLAUSE_LOCATION (c),
   14762              :                               "with %<ancestor%>, only the %<device%>, "
   14763              :                               "%<firstprivate%>, %<private%>, %<defaultmap%>, "
   14764              :                               "and %<map%> clauses may appear on the "
   14765              :                               "construct");
   14766           11 :                     remove = true;
   14767           11 :                     break;
   14768              :                   }
   14769              :             }
   14770        21677 :           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
   14771        21677 :                    && code == OMP_DISPATCH)
   14772              :             {
   14773          272 :               bool saved_into_ssa = gimplify_ctxp->into_ssa;
   14774          272 :               gimplify_ctxp->into_ssa = false;
   14775          272 :               if (gimplify_expr (&OMP_CLAUSE_DEVICE_ID (c), pre_p, NULL,
   14776              :                                  is_gimple_val, fb_rvalue)
   14777              :                   == GS_ERROR)
   14778              :                 remove = true;
   14779          272 :               else if (DECL_P (OMP_CLAUSE_DEVICE_ID (c)))
   14780           55 :                 omp_add_variable (ctx, OMP_CLAUSE_DEVICE_ID (c),
   14781              :                                   GOVD_SHARED | GOVD_SEEN);
   14782          272 :               gimplify_ctxp->into_ssa = saved_into_ssa;
   14783          272 :               break;
   14784              :             }
   14785              :           /* Fall through.  */
   14786              : 
   14787        31251 :         case OMP_CLAUSE_PRIORITY:
   14788        31251 :         case OMP_CLAUSE_GRAINSIZE:
   14789        31251 :         case OMP_CLAUSE_NUM_TASKS:
   14790        31251 :         case OMP_CLAUSE_FILTER:
   14791        31251 :         case OMP_CLAUSE_HINT:
   14792        31251 :         case OMP_CLAUSE_ASYNC:
   14793        31251 :         case OMP_CLAUSE_WAIT:
   14794        31251 :         case OMP_CLAUSE_NUM_GANGS:
   14795        31251 :         case OMP_CLAUSE_NUM_WORKERS:
   14796        31251 :         case OMP_CLAUSE_VECTOR_LENGTH:
   14797        31251 :         case OMP_CLAUSE_WORKER:
   14798        31251 :         case OMP_CLAUSE_VECTOR:
   14799        31251 :           if (OMP_CLAUSE_OPERAND (c, 0)
   14800        31251 :               && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
   14801              :             {
   14802         7774 :               if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
   14803              :                 {
   14804              :                   remove = true;
   14805              :                   break;
   14806              :                 }
   14807              :               /* All these clauses care about value, not a particular decl,
   14808              :                  so try to force it into a SSA_NAME or fresh temporary.  */
   14809         7767 :               OMP_CLAUSE_OPERAND (c, 0)
   14810        15534 :                 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
   14811              :                                            pre_p, NULL, true);
   14812              :             }
   14813              :           break;
   14814              : 
   14815         2332 :         case OMP_CLAUSE_GANG:
   14816         2332 :           if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
   14817              :                              is_gimple_val, fb_rvalue) == GS_ERROR)
   14818            0 :             remove = true;
   14819         2332 :           if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
   14820              :                              is_gimple_val, fb_rvalue) == GS_ERROR)
   14821            0 :             remove = true;
   14822              :           break;
   14823              : 
   14824        13095 :         case OMP_CLAUSE_NOWAIT:
   14825        13095 :           nowait = 1;
   14826        13095 :           break;
   14827              : 
   14828           72 :         case OMP_CLAUSE_USES_ALLOCATORS:
   14829           72 :           sorry_at (OMP_CLAUSE_LOCATION (c), "%<uses_allocators%> clause");
   14830           72 :           remove = 1;
   14831           72 :           break;
   14832              : 
   14833              :         case OMP_CLAUSE_ORDERED:
   14834              :         case OMP_CLAUSE_UNTIED:
   14835              :         case OMP_CLAUSE_COLLAPSE:
   14836              :         case OMP_CLAUSE_TILE:
   14837              :         case OMP_CLAUSE_AUTO:
   14838              :         case OMP_CLAUSE_SEQ:
   14839              :         case OMP_CLAUSE_INDEPENDENT:
   14840              :         case OMP_CLAUSE_MERGEABLE:
   14841              :         case OMP_CLAUSE_PROC_BIND:
   14842              :         case OMP_CLAUSE_SAFELEN:
   14843              :         case OMP_CLAUSE_SIMDLEN:
   14844              :         case OMP_CLAUSE_NOGROUP:
   14845              :         case OMP_CLAUSE_THREADS:
   14846              :         case OMP_CLAUSE_SIMD:
   14847              :         case OMP_CLAUSE_BIND:
   14848              :         case OMP_CLAUSE_IF_PRESENT:
   14849              :         case OMP_CLAUSE_FINALIZE:
   14850              :         case OMP_CLAUSE_INTEROP:
   14851              :         case OMP_CLAUSE_INIT:
   14852              :         case OMP_CLAUSE_USE:
   14853              :         case OMP_CLAUSE_DESTROY:
   14854              :         case OMP_CLAUSE_DEVICE_TYPE:
   14855              :           break;
   14856              : 
   14857           52 :         case OMP_CLAUSE_DYN_GROUPPRIVATE:
   14858           52 :           remove = true;
   14859           52 :           sorry_at (OMP_CLAUSE_LOCATION (c),"%<dyn_groupprivate%> clause");
   14860           52 :           break;
   14861              : 
   14862         3976 :         case OMP_CLAUSE_ORDER:
   14863         3976 :           ctx->order_concurrent = true;
   14864         3976 :           break;
   14865              : 
   14866         1010 :         case OMP_CLAUSE_DEFAULTMAP:
   14867         1010 :           enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
   14868         1010 :           switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
   14869              :             {
   14870              :             case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
   14871              :             case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
   14872              :               gdmkmin = GDMK_SCALAR;
   14873              :               gdmkmax = GDMK_POINTER;
   14874              :               break;
   14875              :             case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
   14876              :               gdmkmin = GDMK_SCALAR;
   14877              :               gdmkmax = GDMK_SCALAR_TARGET;
   14878              :               break;
   14879              :             case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
   14880              :               gdmkmin = gdmkmax = GDMK_AGGREGATE;
   14881              :               break;
   14882              :             case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
   14883              :               gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
   14884              :               break;
   14885              :             case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
   14886              :               gdmkmin = gdmkmax = GDMK_POINTER;
   14887              :               break;
   14888            0 :             default:
   14889            0 :               gcc_unreachable ();
   14890              :             }
   14891         4471 :           for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
   14892         3461 :             switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
   14893              :               {
   14894           91 :               case OMP_CLAUSE_DEFAULTMAP_ALLOC:
   14895           91 :                 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
   14896           91 :                 break;
   14897           96 :               case OMP_CLAUSE_DEFAULTMAP_TO:
   14898           96 :                 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
   14899           96 :                 break;
   14900           28 :               case OMP_CLAUSE_DEFAULTMAP_FROM:
   14901           28 :                 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
   14902           28 :                 break;
   14903          671 :               case OMP_CLAUSE_DEFAULTMAP_TOFROM:
   14904          671 :                 ctx->defaultmap[gdmk] = GOVD_MAP;
   14905          671 :                 break;
   14906          380 :               case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
   14907          380 :                 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
   14908          380 :                 break;
   14909         2094 :               case OMP_CLAUSE_DEFAULTMAP_NONE:
   14910         2094 :                 ctx->defaultmap[gdmk] = 0;
   14911         2094 :                 break;
   14912           45 :               case OMP_CLAUSE_DEFAULTMAP_PRESENT:
   14913           45 :                 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
   14914           45 :                 break;
   14915           56 :               case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
   14916           56 :                 switch (gdmk)
   14917              :                   {
   14918           11 :                   case GDMK_SCALAR:
   14919           11 :                     ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
   14920           11 :                     break;
   14921           11 :                   case GDMK_SCALAR_TARGET:
   14922           11 :                     ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
   14923           11 :                                              ? GOVD_MAP : GOVD_FIRSTPRIVATE);
   14924           11 :                     break;
   14925           14 :                   case GDMK_AGGREGATE:
   14926           14 :                   case GDMK_ALLOCATABLE:
   14927           14 :                     ctx->defaultmap[gdmk] = GOVD_MAP;
   14928           14 :                     break;
   14929           20 :                   case GDMK_POINTER:
   14930           20 :                     ctx->defaultmap[gdmk] = GOVD_MAP;
   14931           20 :                     if (!lang_GNU_Fortran ())
   14932           12 :                       ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
   14933              :                     break;
   14934              :                   default:
   14935              :                     gcc_unreachable ();
   14936              :                   }
   14937              :                 break;
   14938            0 :               default:
   14939            0 :                 gcc_unreachable ();
   14940              :               }
   14941              :           break;
   14942              : 
   14943          824 :         case OMP_CLAUSE_ALIGNED:
   14944          824 :           decl = OMP_CLAUSE_DECL (c);
   14945          824 :           if (error_operand_p (decl))
   14946              :             {
   14947              :               remove = true;
   14948              :               break;
   14949              :             }
   14950          824 :           if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
   14951              :                              is_gimple_val, fb_rvalue) == GS_ERROR)
   14952              :             {
   14953              :               remove = true;
   14954              :               break;
   14955              :             }
   14956          824 :           if (!is_global_var (decl)
   14957          824 :               && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
   14958          592 :             omp_add_variable (ctx, decl, GOVD_ALIGNED);
   14959              :           break;
   14960              : 
   14961          489 :         case OMP_CLAUSE_NONTEMPORAL:
   14962          489 :           decl = OMP_CLAUSE_DECL (c);
   14963          489 :           if (error_operand_p (decl))
   14964              :             {
   14965              :               remove = true;
   14966              :               break;
   14967              :             }
   14968          489 :           omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
   14969          489 :           break;
   14970              : 
   14971         3541 :         case OMP_CLAUSE_ALLOCATE:
   14972         3541 :           decl = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
   14973         3541 :           if (decl
   14974         1700 :               && TREE_CODE (decl) == INTEGER_CST
   14975         3570 :               && wi::eq_p (wi::to_widest (decl), GOMP_OMP_PREDEF_ALLOC_THREAD)
   14976         3570 :               && (code == OMP_TARGET || code == OMP_TASK || code == OMP_TASKLOOP))
   14977           35 :             warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
   14978              :                         "allocator with access trait set to %<thread%> "
   14979              :                         "results in undefined behavior for %qs directive",
   14980              :                         code == OMP_TARGET ? "target"
   14981              :                                            : (code == OMP_TASK
   14982           15 :                                               ? "task" : "taskloop"));
   14983         3541 :           decl = OMP_CLAUSE_DECL (c);
   14984         3541 :           if (error_operand_p (decl))
   14985              :             {
   14986              :               remove = true;
   14987              :               break;
   14988              :             }
   14989         3541 :           if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
   14990              :                              is_gimple_val, fb_rvalue) == GS_ERROR)
   14991              :             {
   14992              :               remove = true;
   14993              :               break;
   14994              :             }
   14995         3541 :           else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
   14996         3541 :                    || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
   14997              :                        == INTEGER_CST))
   14998              :             ;
   14999          503 :           else if (code == OMP_TASKLOOP
   15000          503 :                    || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
   15001           66 :             OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
   15002          132 :               = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
   15003              :                                          pre_p, NULL, false);
   15004              :           break;
   15005              : 
   15006         4365 :         case OMP_CLAUSE_DEFAULT:
   15007         4365 :           ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
   15008         4365 :           break;
   15009              : 
   15010          640 :         case OMP_CLAUSE_INCLUSIVE:
   15011          640 :         case OMP_CLAUSE_EXCLUSIVE:
   15012          640 :           decl = OMP_CLAUSE_DECL (c);
   15013          640 :           {
   15014          640 :             splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
   15015              :                                                    (splay_tree_key) decl);
   15016          640 :             if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
   15017              :               {
   15018            5 :                 error_at (OMP_CLAUSE_LOCATION (c),
   15019              :                           "%qD specified in %qs clause but not in %<inscan%> "
   15020              :                           "%<reduction%> clause on the containing construct",
   15021            5 :                           decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
   15022            5 :                 remove = true;
   15023              :               }
   15024              :             else
   15025              :               {
   15026          635 :                 n->value |= GOVD_REDUCTION_INSCAN;
   15027          635 :                 if (outer_ctx->region_type == ORT_SIMD
   15028          520 :                     && outer_ctx->outer_context
   15029          107 :                     && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
   15030              :                   {
   15031          107 :                     n = splay_tree_lookup (outer_ctx->outer_context->variables,
   15032              :                                            (splay_tree_key) decl);
   15033          107 :                     if (n && (n->value & GOVD_REDUCTION) != 0)
   15034          107 :                       n->value |= GOVD_REDUCTION_INSCAN;
   15035              :                   }
   15036              :               }
   15037              :           }
   15038              :           break;
   15039              : 
   15040          103 :         case OMP_CLAUSE_NOVARIANTS:
   15041          103 :           OMP_CLAUSE_NOVARIANTS_EXPR (c)
   15042          103 :             = gimple_boolify (OMP_CLAUSE_NOVARIANTS_EXPR (c));
   15043          103 :           break;
   15044          115 :         case OMP_CLAUSE_NOCONTEXT:
   15045          115 :           OMP_CLAUSE_NOCONTEXT_EXPR (c)
   15046          115 :             = gimple_boolify (OMP_CLAUSE_NOCONTEXT_EXPR (c));
   15047          115 :           break;
   15048            0 :         case OMP_CLAUSE_NOHOST:
   15049            0 :         default:
   15050            0 :           gcc_unreachable ();
   15051              :         }
   15052              : 
   15053         1401 :       if (code == OACC_DATA
   15054         5123 :           && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   15055       208820 :           && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   15056         4504 :               || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   15057              :         remove = true;
   15058       205103 :       if (remove)
   15059         1105 :         *list_p = OMP_CLAUSE_CHAIN (c);
   15060              :       else
   15061       204305 :         list_p = &OMP_CLAUSE_CHAIN (c);
   15062       205410 :     }
   15063              : 
   15064       130565 :   if (groups)
   15065              :     {
   15066        36356 :       delete grpmap;
   15067        18178 :       delete groups;
   15068              :     }
   15069              : 
   15070       130565 :   ctx->clauses = *orig_list_p;
   15071       130565 :   gimplify_omp_ctxp = ctx;
   15072       130565 : }
   15073              : 
   15074              : /* Return true if DECL is a candidate for shared to firstprivate
   15075              :    optimization.  We only consider non-addressable scalars, not
   15076              :    too big, and not references.  */
   15077              : 
   15078              : static bool
   15079       405487 : omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
   15080              : {
   15081       405487 :   if (TREE_ADDRESSABLE (decl))
   15082              :     return false;
   15083       356370 :   tree type = TREE_TYPE (decl);
   15084       356370 :   if (!is_gimple_reg_type (type)
   15085       331606 :       || TREE_CODE (type) == REFERENCE_TYPE
   15086       683711 :       || TREE_ADDRESSABLE (type))
   15087              :     return false;
   15088              :   /* Don't optimize too large decls, as each thread/task will have
   15089              :      its own.  */
   15090       327341 :   HOST_WIDE_INT len = int_size_in_bytes (type);
   15091       327341 :   if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
   15092              :     return false;
   15093       327324 :   if (omp_privatize_by_reference (decl))
   15094              :     return false;
   15095              :   return true;
   15096              : }
   15097              : 
   15098              : /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
   15099              :    For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
   15100              :    GOVD_WRITTEN in outer contexts.  */
   15101              : 
   15102              : static void
   15103       304428 : omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
   15104              : {
   15105       466623 :   for (; ctx; ctx = ctx->outer_context)
   15106              :     {
   15107       449617 :       splay_tree_node n = splay_tree_lookup (ctx->variables,
   15108              :                                              (splay_tree_key) decl);
   15109       449617 :       if (n == NULL)
   15110       158616 :         continue;
   15111       291001 :       else if (n->value & GOVD_SHARED)
   15112              :         {
   15113         9121 :           n->value |= GOVD_WRITTEN;
   15114         9121 :           return;
   15115              :         }
   15116       281880 :       else if (n->value & GOVD_DATA_SHARE_CLASS)
   15117              :         return;
   15118              :     }
   15119              : }
   15120              : 
   15121              : /* Helper callback for walk_gimple_seq to discover possible stores
   15122              :    to omp_shared_to_firstprivate_optimizable_decl_p decls and set
   15123              :    GOVD_WRITTEN if they are GOVD_SHARED in some outer context
   15124              :    for those.  */
   15125              : 
   15126              : static tree
   15127      1128238 : omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
   15128              : {
   15129      1128238 :   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
   15130              : 
   15131      1128238 :   *walk_subtrees = 0;
   15132      1128238 :   if (!wi->is_lhs)
   15133              :     return NULL_TREE;
   15134              : 
   15135       322238 :   tree op = *tp;
   15136       401032 :   do
   15137              :     {
   15138       401032 :       if (handled_component_p (op))
   15139        78794 :         op = TREE_OPERAND (op, 0);
   15140       322238 :       else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
   15141       322238 :                && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
   15142            0 :         op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
   15143              :       else
   15144              :         break;
   15145              :     }
   15146              :   while (1);
   15147       322238 :   if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
   15148        58119 :     return NULL_TREE;
   15149              : 
   15150       264119 :   omp_mark_stores (gimplify_omp_ctxp, op);
   15151       264119 :   return NULL_TREE;
   15152              : }
   15153              : 
   15154              : /* Helper callback for walk_gimple_seq to discover possible stores
   15155              :    to omp_shared_to_firstprivate_optimizable_decl_p decls and set
   15156              :    GOVD_WRITTEN if they are GOVD_SHARED in some outer context
   15157              :    for those.  */
   15158              : 
   15159              : static tree
   15160       627182 : omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
   15161              :                       bool *handled_ops_p,
   15162              :                       struct walk_stmt_info *wi)
   15163              : {
   15164       627182 :   gimple *stmt = gsi_stmt (*gsi_p);
   15165       627182 :   switch (gimple_code (stmt))
   15166              :     {
   15167              :     /* Don't recurse on OpenMP constructs for which
   15168              :        gimplify_adjust_omp_clauses already handled the bodies,
   15169              :        except handle gimple_omp_for_pre_body.  */
   15170        26691 :     case GIMPLE_OMP_FOR:
   15171        26691 :       *handled_ops_p = true;
   15172        26691 :       if (gimple_omp_for_pre_body (stmt))
   15173         1780 :         walk_gimple_seq (gimple_omp_for_pre_body (stmt),
   15174              :                          omp_find_stores_stmt, omp_find_stores_op, wi);
   15175              :       break;
   15176         8562 :     case GIMPLE_OMP_PARALLEL:
   15177         8562 :     case GIMPLE_OMP_TASK:
   15178         8562 :     case GIMPLE_OMP_SECTIONS:
   15179         8562 :     case GIMPLE_OMP_SINGLE:
   15180         8562 :     case GIMPLE_OMP_SCOPE:
   15181         8562 :     case GIMPLE_OMP_TARGET:
   15182         8562 :     case GIMPLE_OMP_TEAMS:
   15183         8562 :     case GIMPLE_OMP_CRITICAL:
   15184         8562 :       *handled_ops_p = true;
   15185         8562 :       break;
   15186              :     default:
   15187              :       break;
   15188              :     }
   15189       627182 :   return NULL_TREE;
   15190              : }
   15191              : 
   15192              : struct gimplify_adjust_omp_clauses_data
   15193              : {
   15194              :   tree *list_p;
   15195              :   gimple_seq *pre_p;
   15196              : };
   15197              : 
   15198              : /* For all variables that were not actually used within the context,
   15199              :    remove PRIVATE, SHARED, and FIRSTPRIVATE clauses.  */
   15200              : 
   15201              : static int
   15202       677178 : gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
   15203              : {
   15204       677178 :   tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
   15205       677178 :   gimple_seq *pre_p
   15206              :     = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
   15207       677178 :   tree decl = (tree) n->key;
   15208       677178 :   unsigned flags = n->value;
   15209       677178 :   enum omp_clause_code code;
   15210       677178 :   tree clause;
   15211       677178 :   bool private_debug;
   15212              : 
   15213       677178 :   if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
   15214       132809 :       && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
   15215              :     flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
   15216       677053 :   if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
   15217              :     return 0;
   15218       178684 :   if ((flags & GOVD_SEEN) == 0)
   15219              :     return 0;
   15220       157593 :   if (flags & GOVD_DEBUG_PRIVATE)
   15221              :     {
   15222          260 :       gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
   15223              :       private_debug = true;
   15224              :     }
   15225       157333 :   else if (flags & GOVD_MAP)
   15226              :     private_debug = false;
   15227              :   else
   15228       139151 :     private_debug
   15229       139151 :       = lang_hooks.decls.omp_private_debug_clause (decl,
   15230       139151 :                                                    !!(flags & GOVD_SHARED));
   15231       139151 :   if (private_debug)
   15232              :     code = OMP_CLAUSE_PRIVATE;
   15233       157211 :   else if (flags & GOVD_MAP)
   15234              :     {
   15235        18182 :       code = OMP_CLAUSE_MAP;
   15236        18182 :       if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
   15237        18182 :           && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
   15238              :         {
   15239            2 :           error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
   15240            2 :           return 0;
   15241              :         }
   15242        18180 :       if (VAR_P (decl)
   15243        16242 :           && DECL_IN_CONSTANT_POOL (decl)
   15244        18181 :           && !lookup_attribute ("omp declare target",
   15245            1 :                                 DECL_ATTRIBUTES (decl)))
   15246              :         {
   15247            1 :           tree id = get_identifier ("omp declare target");
   15248            1 :           DECL_ATTRIBUTES (decl)
   15249            1 :             = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
   15250            1 :           varpool_node *node = varpool_node::get (decl);
   15251            1 :           if (node)
   15252              :             {
   15253            1 :               node->offloadable = 1;
   15254            1 :               if (ENABLE_OFFLOADING)
   15255              :                 g->have_offload = true;
   15256              :             }
   15257              :         }
   15258              :     }
   15259       139029 :   else if (flags & GOVD_SHARED)
   15260              :     {
   15261        49059 :       if (is_global_var (decl))
   15262              :         {
   15263        16138 :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
   15264        25325 :           while (ctx != NULL)
   15265              :             {
   15266        17604 :               splay_tree_node on
   15267        17604 :                 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15268        17604 :               if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
   15269              :                                       | GOVD_PRIVATE | GOVD_REDUCTION
   15270              :                                       | GOVD_LINEAR | GOVD_MAP)) != 0)
   15271              :                 break;
   15272         9187 :               ctx = ctx->outer_context;
   15273              :             }
   15274        16138 :           if (ctx == NULL)
   15275              :             return 0;
   15276              :         }
   15277        41338 :       code = OMP_CLAUSE_SHARED;
   15278              :       /* Don't optimize shared into firstprivate for read-only vars
   15279              :          on tasks with depend clause, we shouldn't try to copy them
   15280              :          until the dependencies are satisfied.  */
   15281        41338 :       if (gimplify_omp_ctxp->has_depend)
   15282          350 :         flags |= GOVD_WRITTEN;
   15283              :     }
   15284        89970 :   else if (flags & GOVD_PRIVATE)
   15285              :     code = OMP_CLAUSE_PRIVATE;
   15286        31499 :   else if (flags & GOVD_FIRSTPRIVATE)
   15287              :     {
   15288        22098 :       code = OMP_CLAUSE_FIRSTPRIVATE;
   15289        22098 :       if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
   15290        14027 :           && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
   15291        32444 :           && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
   15292              :         {
   15293            1 :           error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
   15294              :                  "%<target%> construct", decl);
   15295            1 :           return 0;
   15296              :         }
   15297              :     }
   15298         9401 :   else if (flags & GOVD_LASTPRIVATE)
   15299              :     code = OMP_CLAUSE_LASTPRIVATE;
   15300          241 :   else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
   15301              :     return 0;
   15302          118 :   else if (flags & GOVD_CONDTEMP)
   15303              :     {
   15304          118 :       code = OMP_CLAUSE__CONDTEMP_;
   15305          118 :       gimple_add_tmp_var (decl);
   15306              :     }
   15307              :   else
   15308            0 :     gcc_unreachable ();
   15309              : 
   15310       140586 :   if (((flags & GOVD_LASTPRIVATE)
   15311       139896 :        || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
   15312       155805 :       && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   15313        15205 :     omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   15314              : 
   15315       149746 :   tree chain = *list_p;
   15316       149746 :   clause = build_omp_clause (input_location, code);
   15317       149746 :   OMP_CLAUSE_DECL (clause) = decl;
   15318       149746 :   OMP_CLAUSE_CHAIN (clause) = chain;
   15319       149746 :   if (private_debug)
   15320          382 :     OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
   15321       149364 :   else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
   15322            6 :     OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
   15323       149358 :   else if (code == OMP_CLAUSE_SHARED
   15324        41338 :            && (flags & GOVD_WRITTEN) == 0
   15325       184637 :            && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   15326        21046 :     OMP_CLAUSE_SHARED_READONLY (clause) = 1;
   15327       128312 :   else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
   15328        22097 :     OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
   15329       106215 :   else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
   15330              :     {
   15331          626 :       tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
   15332          626 :       OMP_CLAUSE_DECL (nc) = decl;
   15333          626 :       if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   15334          626 :           && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
   15335           15 :         OMP_CLAUSE_DECL (clause)
   15336           30 :           = build_fold_indirect_ref_loc (input_location, decl);
   15337          626 :       OMP_CLAUSE_DECL (clause)
   15338          626 :         = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
   15339              :                   build_int_cst (build_pointer_type (char_type_node), 0));
   15340          626 :       OMP_CLAUSE_SIZE (clause) = size_zero_node;
   15341          626 :       OMP_CLAUSE_SIZE (nc) = size_zero_node;
   15342          626 :       OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
   15343          626 :       OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
   15344          626 :       tree dtype = TREE_TYPE (decl);
   15345          626 :       if (TREE_CODE (dtype) == REFERENCE_TYPE)
   15346           15 :         dtype = TREE_TYPE (dtype);
   15347              :       /* FIRSTPRIVATE_POINTER doesn't work well if we have a
   15348              :          multiply-indirected pointer.  If we have a reference to a pointer to
   15349              :          a pointer, it's possible that this should really be
   15350              :          GOMP_MAP_FIRSTPRIVATE_REFERENCE -- but that also doesn't work at the
   15351              :          moment, so stick with this.  (See PR113279 and testcases
   15352              :          baseptrs-{4,6}.C:ref2ptrptr_offset_decl_member_slice).  */
   15353          626 :       if (TREE_CODE (dtype) == POINTER_TYPE
   15354          626 :           && TREE_CODE (TREE_TYPE (dtype)) == POINTER_TYPE)
   15355           19 :         OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
   15356              :       else
   15357          607 :         OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
   15358          626 :       OMP_CLAUSE_CHAIN (nc) = chain;
   15359          626 :       OMP_CLAUSE_CHAIN (clause) = nc;
   15360          626 :       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15361          626 :       gimplify_omp_ctxp = ctx->outer_context;
   15362          626 :       gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
   15363              :                      pre_p, NULL, is_gimple_val, fb_rvalue);
   15364          626 :       gimplify_omp_ctxp = ctx;
   15365          626 :     }
   15366        17554 :   else if (code == OMP_CLAUSE_MAP)
   15367              :     {
   15368        17554 :       int kind;
   15369              :       /* Not all combinations of these GOVD_MAP flags are actually valid.  */
   15370        17554 :       switch (flags & (GOVD_MAP_TO_ONLY
   15371              :                        | GOVD_MAP_FORCE
   15372              :                        | GOVD_MAP_FORCE_PRESENT
   15373              :                        | GOVD_MAP_ALLOC_ONLY
   15374              :                        | GOVD_MAP_FROM_ONLY))
   15375              :         {
   15376              :         case 0:
   15377              :           kind = GOMP_MAP_TOFROM;
   15378              :           break;
   15379         1042 :         case GOVD_MAP_FORCE:
   15380         1042 :           kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
   15381         1042 :           break;
   15382         1015 :         case GOVD_MAP_TO_ONLY:
   15383         1015 :           kind = GOMP_MAP_TO;
   15384         1015 :           break;
   15385           16 :         case GOVD_MAP_FROM_ONLY:
   15386           16 :           kind = GOMP_MAP_FROM;
   15387           16 :           break;
   15388           37 :         case GOVD_MAP_ALLOC_ONLY:
   15389           37 :           kind = GOMP_MAP_ALLOC;
   15390           37 :           break;
   15391            3 :         case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
   15392            3 :           kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
   15393            3 :           break;
   15394              :         case GOVD_MAP_FORCE_PRESENT:
   15395          326 :           kind = GOMP_MAP_FORCE_PRESENT;
   15396              :           break;
   15397              :         case GOVD_MAP_FORCE_PRESENT | GOVD_MAP_ALLOC_ONLY:
   15398          326 :           kind = GOMP_MAP_FORCE_PRESENT;
   15399              :           break;
   15400            0 :         default:
   15401            0 :           gcc_unreachable ();
   15402              :         }
   15403        17554 :       OMP_CLAUSE_SET_MAP_KIND (clause, kind);
   15404              :       /* Setting of the implicit flag for the runtime is currently disabled for
   15405              :          OpenACC.  */
   15406        17554 :       if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
   15407        10020 :         OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
   15408        17554 :       if (DECL_SIZE (decl)
   15409        17554 :           && !poly_int_tree_p (DECL_SIZE (decl)))
   15410              :         {
   15411          535 :           tree decl2 = DECL_VALUE_EXPR (decl);
   15412          535 :           gcc_assert (INDIRECT_REF_P (decl2));
   15413          535 :           decl2 = TREE_OPERAND (decl2, 0);
   15414          535 :           gcc_assert (DECL_P (decl2));
   15415          535 :           tree mem = build_simple_mem_ref (decl2);
   15416          535 :           OMP_CLAUSE_DECL (clause) = mem;
   15417          535 :           OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
   15418          535 :           if (gimplify_omp_ctxp->outer_context)
   15419              :             {
   15420          446 :               struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
   15421          446 :               omp_notice_variable (ctx, decl2, true);
   15422          446 :               omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
   15423              :             }
   15424          535 :           tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
   15425              :                                       OMP_CLAUSE_MAP);
   15426          535 :           OMP_CLAUSE_DECL (nc) = decl;
   15427          535 :           OMP_CLAUSE_SIZE (nc) = size_zero_node;
   15428          535 :           if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
   15429          535 :             OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
   15430              :           else
   15431            0 :             OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
   15432          535 :           OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
   15433          535 :           OMP_CLAUSE_CHAIN (clause) = nc;
   15434              :         }
   15435        17019 :       else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
   15436        17019 :                && omp_privatize_by_reference (decl))
   15437              :         {
   15438           28 :           OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
   15439           28 :           OMP_CLAUSE_SIZE (clause)
   15440           28 :             = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
   15441           28 :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15442           28 :           gimplify_omp_ctxp = ctx->outer_context;
   15443           28 :           gimplify_expr (&OMP_CLAUSE_SIZE (clause),
   15444              :                          pre_p, NULL, is_gimple_val, fb_rvalue);
   15445           28 :           gimplify_omp_ctxp = ctx;
   15446           28 :           tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
   15447              :                                       OMP_CLAUSE_MAP);
   15448           28 :           OMP_CLAUSE_DECL (nc) = decl;
   15449           28 :           OMP_CLAUSE_SIZE (nc) = size_zero_node;
   15450           28 :           OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
   15451           28 :           OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
   15452           28 :           OMP_CLAUSE_CHAIN (clause) = nc;
   15453              :         }
   15454              :       else
   15455        16991 :         OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
   15456              :     }
   15457       149746 :   if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
   15458              :     {
   15459          690 :       tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
   15460          690 :       OMP_CLAUSE_DECL (nc) = decl;
   15461          690 :       OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
   15462          690 :       OMP_CLAUSE_CHAIN (nc) = chain;
   15463          690 :       OMP_CLAUSE_CHAIN (clause) = nc;
   15464          690 :       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15465          690 :       gimplify_omp_ctxp = ctx->outer_context;
   15466          690 :       lang_hooks.decls.omp_finish_clause (nc, pre_p,
   15467          690 :                                           (ctx->region_type & ORT_ACC) != 0);
   15468          690 :       gimplify_omp_ctxp = ctx;
   15469              :     }
   15470       149746 :   *list_p = clause;
   15471       149746 :   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15472       149746 :   gimplify_omp_ctxp = ctx->outer_context;
   15473              :   /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
   15474              :      in simd.  Those are only added for the local vars inside of simd body
   15475              :      and they don't need to be e.g. default constructible.  */
   15476       149746 :   if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
   15477       141696 :     lang_hooks.decls.omp_finish_clause (clause, pre_p,
   15478       141696 :                                         (ctx->region_type & ORT_ACC) != 0);
   15479       149746 :   if (gimplify_omp_ctxp)
   15480       184145 :     for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
   15481        93485 :       if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
   15482        93485 :           && DECL_P (OMP_CLAUSE_SIZE (clause)))
   15483         1241 :         omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
   15484              :                              true);
   15485       149746 :   gimplify_omp_ctxp = ctx;
   15486       149746 :   return 0;
   15487              : }
   15488              : 
   15489              : static void
   15490       129101 : gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
   15491              :                              enum tree_code code,
   15492              :                              gimple_seq *loops_seq_p = NULL)
   15493              : {
   15494       129101 :   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15495       129101 :   tree *orig_list_p = list_p;
   15496       129101 :   tree c, decl;
   15497       129101 :   bool has_inscan_reductions = false;
   15498              : 
   15499       129101 :   if (body)
   15500              :     {
   15501              :       struct gimplify_omp_ctx *octx;
   15502       224958 :       for (octx = ctx; octx; octx = octx->outer_context)
   15503       173645 :         if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
   15504              :           break;
   15505       111523 :       if (octx)
   15506              :         {
   15507        60210 :           struct walk_stmt_info wi;
   15508        60210 :           memset (&wi, 0, sizeof (wi));
   15509        60210 :           walk_gimple_seq (body, omp_find_stores_stmt,
   15510              :                            omp_find_stores_op, &wi);
   15511              :         }
   15512              :     }
   15513              : 
   15514       129101 :   if (ctx->add_safelen1)
   15515              :     {
   15516              :       /* If there are VLAs in the body of simd loop, prevent
   15517              :          vectorization.  */
   15518            2 :       gcc_assert (ctx->region_type == ORT_SIMD);
   15519            2 :       c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
   15520            2 :       OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
   15521            2 :       OMP_CLAUSE_CHAIN (c) = *list_p;
   15522            2 :       *list_p = c;
   15523            2 :       list_p = &OMP_CLAUSE_CHAIN (c);
   15524              :     }
   15525              : 
   15526       129101 :   if (ctx->region_type == ORT_WORKSHARE
   15527        39685 :       && ctx->outer_context
   15528        27891 :       && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
   15529              :     {
   15530        24921 :       for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
   15531        12570 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   15532        12570 :             && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   15533              :           {
   15534          125 :             decl = OMP_CLAUSE_DECL (c);
   15535          125 :             splay_tree_node n
   15536          125 :               = splay_tree_lookup (ctx->outer_context->variables,
   15537              :                                    (splay_tree_key) decl);
   15538          125 :             gcc_checking_assert (!splay_tree_lookup (ctx->variables,
   15539              :                                                      (splay_tree_key) decl));
   15540          125 :             omp_add_variable (ctx, decl, n->value);
   15541          125 :             tree c2 = copy_node (c);
   15542          125 :             OMP_CLAUSE_CHAIN (c2) = *list_p;
   15543          125 :             *list_p = c2;
   15544          125 :             if ((n->value & GOVD_FIRSTPRIVATE) == 0)
   15545          103 :               continue;
   15546           22 :             c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   15547              :                                    OMP_CLAUSE_FIRSTPRIVATE);
   15548           22 :             OMP_CLAUSE_DECL (c2) = decl;
   15549           22 :             OMP_CLAUSE_CHAIN (c2) = *list_p;
   15550           22 :             *list_p = c2;
   15551              :           }
   15552              :     }
   15553              : 
   15554       129101 :   if (code == OMP_TARGET
   15555       129101 :       || code == OMP_TARGET_DATA
   15556       129101 :       || code == OMP_TARGET_ENTER_DATA
   15557       112791 :       || code == OMP_TARGET_EXIT_DATA)
   15558              :     {
   15559        17096 :       tree mapper_clauses = NULL_TREE;
   15560        17096 :       instantiate_mapper_info im_info;
   15561              : 
   15562        17096 :       im_info.mapper_clauses_p = &mapper_clauses;
   15563        17096 :       im_info.omp_ctx = ctx;
   15564        17096 :       im_info.pre_p = pre_p;
   15565              : 
   15566        17096 :       splay_tree_foreach (ctx->variables,
   15567              :                           omp_instantiate_implicit_mappers,
   15568              :                           (void *) &im_info);
   15569              : 
   15570        17096 :       if (mapper_clauses)
   15571              :         {
   15572           53 :           mapper_clauses
   15573           53 :             = lang_hooks.decls.omp_finish_mapper_clauses (mapper_clauses);
   15574              : 
   15575              :           /* Stick the implicitly-expanded mapper clauses at the end of the
   15576              :              clause list.  */
   15577           53 :           tree *tail = list_p;
   15578          163 :           while (*tail)
   15579          110 :             tail = &OMP_CLAUSE_CHAIN (*tail);
   15580           53 :           *tail = mapper_clauses;
   15581              :         }
   15582              : 
   15583        17096 :       vec<omp_mapping_group> *groups;
   15584        17096 :       groups = omp_gather_mapping_groups (list_p);
   15585        17096 :       hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL;
   15586              : 
   15587        17096 :       if (groups)
   15588              :         {
   15589         8515 :           grpmap = omp_index_mapping_groups (groups);
   15590              : 
   15591         8515 :           omp_resolve_clause_dependencies (code, groups, grpmap);
   15592         8515 :           omp_build_struct_sibling_lists (code, ctx->region_type, groups,
   15593              :                                           &grpmap, list_p);
   15594              : 
   15595         8515 :           omp_mapping_group *outlist = NULL;
   15596              : 
   15597        17030 :           delete grpmap;
   15598         8515 :           delete groups;
   15599              : 
   15600              :           /* Rebuild now we have struct sibling lists.  */
   15601         8515 :           groups = omp_gather_mapping_groups (list_p);
   15602         8515 :           grpmap = omp_index_mapping_groups (groups);
   15603              : 
   15604         8515 :           bool enter_exit = (code == OMP_TARGET_ENTER_DATA
   15605         8515 :                              || code == OMP_TARGET_EXIT_DATA);
   15606              : 
   15607         8515 :           outlist = omp_tsort_mapping_groups (groups, grpmap, enter_exit);
   15608         8515 :           outlist = omp_segregate_mapping_groups (outlist);
   15609         8515 :           list_p = omp_reorder_mapping_groups (groups, outlist, list_p);
   15610              : 
   15611         8515 :           delete grpmap;
   15612         8515 :           delete groups;
   15613              :         }
   15614        17096 :     }
   15615       112005 :   else if (ctx->region_type & ORT_ACC)
   15616              :     {
   15617        29847 :       vec<omp_mapping_group> *groups;
   15618        29847 :       groups = omp_gather_mapping_groups (list_p);
   15619        29847 :       if (groups)
   15620              :         {
   15621         9462 :           hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap;
   15622         9462 :           grpmap = omp_index_mapping_groups (groups);
   15623              : 
   15624         9462 :           oacc_resolve_clause_dependencies (groups, grpmap);
   15625         9462 :           omp_build_struct_sibling_lists (code, ctx->region_type, groups,
   15626              :                                           &grpmap, list_p);
   15627              : 
   15628         9462 :           delete groups;
   15629        18924 :           delete grpmap;
   15630              :         }
   15631              :     }
   15632              : 
   15633       129101 :   tree attach_list = NULL_TREE;
   15634       129101 :   tree *attach_tail = &attach_list;
   15635              : 
   15636       129101 :   tree *grp_start_p = NULL, grp_end = NULL_TREE;
   15637              : 
   15638       377941 :   while ((c = *list_p) != NULL)
   15639              :     {
   15640       248840 :       splay_tree_node n;
   15641       248840 :       bool remove = false;
   15642       248840 :       bool move_attach = false;
   15643              : 
   15644       291425 :       if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end))
   15645              :         grp_end = NULL_TREE;
   15646              : 
   15647       248840 :       switch (OMP_CLAUSE_CODE (c))
   15648              :         {
   15649         8039 :         case OMP_CLAUSE_FIRSTPRIVATE:
   15650         8039 :           if ((ctx->region_type & ORT_TARGET)
   15651         1968 :               && (ctx->region_type & ORT_ACC) == 0
   15652         9401 :               && TYPE_ATOMIC (strip_array_types
   15653              :                                         (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
   15654              :             {
   15655            4 :               error_at (OMP_CLAUSE_LOCATION (c),
   15656              :                         "%<_Atomic%> %qD in %<firstprivate%> clause on "
   15657            2 :                         "%<target%> construct", OMP_CLAUSE_DECL (c));
   15658            2 :               remove = true;
   15659            2 :               break;
   15660              :             }
   15661         8037 :           if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   15662              :             {
   15663          380 :               decl = OMP_CLAUSE_DECL (c);
   15664          380 :               n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15665          380 :               if ((n->value & GOVD_MAP) != 0)
   15666              :                 {
   15667              :                   remove = true;
   15668              :                   break;
   15669              :                 }
   15670          368 :               OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
   15671          368 :               OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
   15672              :             }
   15673              :           /* FALLTHRU */
   15674        36839 :         case OMP_CLAUSE_PRIVATE:
   15675        36839 :         case OMP_CLAUSE_SHARED:
   15676        36839 :         case OMP_CLAUSE_LINEAR:
   15677        36839 :           decl = OMP_CLAUSE_DECL (c);
   15678        36839 :           n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15679        36839 :           remove = !(n->value & GOVD_SEEN);
   15680        36839 :           if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
   15681           48 :               && code == OMP_PARALLEL
   15682        36861 :               && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   15683              :             remove = true;
   15684        36817 :           if (! remove)
   15685              :             {
   15686        32215 :               bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
   15687        32215 :               if ((n->value & GOVD_DEBUG_PRIVATE)
   15688        32215 :                   || lang_hooks.decls.omp_private_debug_clause (decl, shared))
   15689              :                 {
   15690           87 :                   gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
   15691              :                               || ((n->value & GOVD_DATA_SHARE_CLASS)
   15692              :                                   == GOVD_SHARED));
   15693           87 :                   OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
   15694           87 :                   OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
   15695              :                 }
   15696        32215 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
   15697         4159 :                   && ctx->has_depend
   15698        32773 :                   && DECL_P (decl))
   15699          558 :                 n->value |= GOVD_WRITTEN;
   15700        32215 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
   15701         4159 :                   && (n->value & GOVD_WRITTEN) == 0
   15702         3042 :                   && DECL_P (decl)
   15703        35257 :                   && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   15704          526 :                 OMP_CLAUSE_SHARED_READONLY (c) = 1;
   15705        31689 :               else if (DECL_P (decl)
   15706        31689 :                        && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
   15707         3633 :                             && (n->value & GOVD_WRITTEN) != 0)
   15708        30572 :                            || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   15709         9032 :                                && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
   15710        38727 :                        && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   15711         5734 :                 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   15712              :             }
   15713              :           else
   15714         4624 :             n->value &= ~GOVD_EXPLICIT;
   15715              :           break;
   15716              : 
   15717        13004 :         case OMP_CLAUSE_LASTPRIVATE:
   15718              :           /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
   15719              :              accurately reflect the presence of a FIRSTPRIVATE clause.  */
   15720        13004 :           decl = OMP_CLAUSE_DECL (c);
   15721        13004 :           n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15722        13004 :           OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
   15723        13004 :             = (n->value & GOVD_FIRSTPRIVATE) != 0;
   15724        13004 :           if (code == OMP_DISTRIBUTE
   15725        13004 :               && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
   15726              :             {
   15727            4 :               remove = true;
   15728            4 :               error_at (OMP_CLAUSE_LOCATION (c),
   15729              :                         "same variable used in %<firstprivate%> and "
   15730              :                         "%<lastprivate%> clauses on %<distribute%> "
   15731              :                         "construct");
   15732              :             }
   15733        13004 :           if (!remove
   15734        13000 :               && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   15735        13000 :               && DECL_P (decl)
   15736        13000 :               && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   15737        11407 :             omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   15738        13004 :           if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
   15739              :             remove = true;
   15740              :           break;
   15741              : 
   15742          824 :         case OMP_CLAUSE_ALIGNED:
   15743          824 :           decl = OMP_CLAUSE_DECL (c);
   15744          824 :           if (!is_global_var (decl))
   15745              :             {
   15746          738 :               n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15747          738 :               remove = n == NULL || !(n->value & GOVD_SEEN);
   15748           88 :               if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
   15749              :                 {
   15750           88 :                   struct gimplify_omp_ctx *octx;
   15751           88 :                   if (n != NULL
   15752           88 :                       && (n->value & (GOVD_DATA_SHARE_CLASS
   15753              :                                       & ~GOVD_FIRSTPRIVATE)))
   15754              :                     remove = true;
   15755              :                   else
   15756          100 :                     for (octx = ctx->outer_context; octx;
   15757           12 :                          octx = octx->outer_context)
   15758              :                       {
   15759           24 :                         n = splay_tree_lookup (octx->variables,
   15760              :                                                (splay_tree_key) decl);
   15761           24 :                         if (n == NULL)
   15762           12 :                           continue;
   15763           12 :                         if (n->value & GOVD_LOCAL)
   15764              :                           break;
   15765              :                         /* We have to avoid assigning a shared variable
   15766              :                            to itself when trying to add
   15767              :                            __builtin_assume_aligned.  */
   15768           12 :                         if (n->value & GOVD_SHARED)
   15769              :                           {
   15770              :                             remove = true;
   15771              :                             break;
   15772              :                           }
   15773              :                       }
   15774              :                 }
   15775              :             }
   15776           86 :           else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
   15777              :             {
   15778           86 :               n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15779           86 :               if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
   15780              :                 remove = true;
   15781              :             }
   15782              :           break;
   15783              : 
   15784          552 :         case OMP_CLAUSE_HAS_DEVICE_ADDR:
   15785          552 :           decl = OMP_CLAUSE_DECL (c);
   15786          552 :           while (INDIRECT_REF_P (decl)
   15787          601 :                  || TREE_CODE (decl) == ARRAY_REF)
   15788           49 :             decl = TREE_OPERAND (decl, 0);
   15789          552 :           n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15790          552 :           remove = n == NULL || !(n->value & GOVD_SEEN);
   15791              :           break;
   15792              : 
   15793          900 :         case OMP_CLAUSE_IS_DEVICE_PTR:
   15794          900 :         case OMP_CLAUSE_NONTEMPORAL:
   15795          900 :           decl = OMP_CLAUSE_DECL (c);
   15796          900 :           n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15797          900 :           remove = n == NULL || !(n->value & GOVD_SEEN);
   15798              :           break;
   15799              : 
   15800        56661 :         case OMP_CLAUSE_MAP:
   15801        56661 :           if (OMP_CLAUSE_MAP_GIMPLE_ONLY (c))
   15802              :             {
   15803           90 :               remove = true;
   15804           90 :               goto end_adjust_omp_map_clause;
   15805              :             }
   15806        56571 :           decl = OMP_CLAUSE_DECL (c);
   15807        56571 :           if (!grp_end)
   15808              :             {
   15809        31684 :               grp_start_p = list_p;
   15810        31684 :               grp_end = *omp_group_last (grp_start_p);
   15811              :             }
   15812        56571 :           switch (OMP_CLAUSE_MAP_KIND (c))
   15813              :             {
   15814          181 :             case GOMP_MAP_PRESENT_ALLOC:
   15815          181 :             case GOMP_MAP_PRESENT_TO:
   15816          181 :             case GOMP_MAP_PRESENT_FROM:
   15817          181 :             case GOMP_MAP_PRESENT_TOFROM:
   15818          181 :               OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_PRESENT);
   15819          181 :               break;
   15820              :             default:
   15821              :               break;
   15822              :             }
   15823        56571 :           switch (code)
   15824              :             {
   15825         4563 :             case OACC_DATA:
   15826         4563 :               if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
   15827              :                 break;
   15828              :               /* Fallthrough.  */
   15829        19219 :             case OACC_HOST_DATA:
   15830        19219 :             case OACC_ENTER_DATA:
   15831        19219 :             case OACC_EXIT_DATA:
   15832        19219 :             case OMP_TARGET_DATA:
   15833        19219 :             case OMP_TARGET_ENTER_DATA:
   15834        19219 :             case OMP_TARGET_EXIT_DATA:
   15835        19219 :               if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   15836        19219 :                   || (OMP_CLAUSE_MAP_KIND (c)
   15837              :                       == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   15838              :                 /* For target {,enter ,exit }data only the array slice is
   15839              :                    mapped, but not the pointer to it.  */
   15840              :                 remove = true;
   15841        19219 :               if (code == OMP_TARGET_EXIT_DATA
   15842        19219 :                   && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
   15843         2794 :                       || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER))
   15844              :                 remove = true;
   15845              :               break;
   15846              :             case OMP_TARGET:
   15847              :               break;
   15848              :             default:
   15849              :               break;
   15850              :             }
   15851        19217 :           if (remove)
   15852              :             break;
   15853        56236 :           if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   15854              :             {
   15855              :               /* Sanity check: attach/detach map kinds use the size as a bias,
   15856              :                  and it's never right to use the decl size for such
   15857              :                  mappings.  */
   15858        17706 :               gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
   15859              :                           && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
   15860              :                           && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DETACH
   15861              :                           && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
   15862              :                           && (OMP_CLAUSE_MAP_KIND (c)
   15863              :                               != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION));
   15864        21762 :               OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
   15865         4056 :                                     : TYPE_SIZE_UNIT (TREE_TYPE (decl));
   15866              :             }
   15867        56236 :           gimplify_omp_ctxp = ctx->outer_context;
   15868        56236 :           gimple_seq *seq_p;
   15869        56236 :           seq_p = enter_omp_iterator_loop_context (c, loops_seq_p, pre_p);
   15870        56236 :           if (gimplify_expr (&OMP_CLAUSE_SIZE (c), seq_p, NULL,
   15871              :                                   is_gimple_val, fb_rvalue) == GS_ERROR)
   15872              :             {
   15873            0 :               gimplify_omp_ctxp = ctx;
   15874            0 :               remove = true;
   15875            0 :               goto end_adjust_omp_map_clause;
   15876              :             }
   15877        56236 :           else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   15878        53341 :                     || (OMP_CLAUSE_MAP_KIND (c)
   15879              :                         == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   15880        52928 :                     || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   15881        62848 :                    && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
   15882              :             {
   15883          912 :               OMP_CLAUSE_SIZE (c)
   15884          912 :                 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), seq_p, NULL,
   15885              :                                            false);
   15886          912 :               if ((ctx->region_type & ORT_TARGET) != 0)
   15887          703 :                 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
   15888              :                                   GOVD_FIRSTPRIVATE | GOVD_SEEN);
   15889              :             }
   15890        56236 :           gimplify_omp_ctxp = ctx;
   15891              :           /* Data clauses associated with reductions must be
   15892              :              compatible with present_or_copy.  Warn and adjust the clause
   15893              :              if that is not the case.  */
   15894        56236 :           if (ctx->region_type == ORT_ACC_PARALLEL
   15895        47257 :               || ctx->region_type == ORT_ACC_SERIAL)
   15896              :             {
   15897         9535 :               tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
   15898         9535 :               n = NULL;
   15899              : 
   15900         9535 :               if (DECL_P (t))
   15901         7770 :                 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
   15902              : 
   15903         7770 :               if (n && (n->value & GOVD_REDUCTION))
   15904              :                 {
   15905          809 :                   enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
   15906              : 
   15907          809 :                   OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
   15908          809 :                   if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
   15909          159 :                       && kind != GOMP_MAP_FORCE_PRESENT
   15910          159 :                       && kind != GOMP_MAP_POINTER)
   15911              :                     {
   15912          120 :                       warning_at (OMP_CLAUSE_LOCATION (c), 0,
   15913              :                                   "incompatible data clause with reduction "
   15914              :                                   "on %qE; promoting to %<present_or_copy%>",
   15915          120 :                                   DECL_NAME (t));
   15916          120 :                       OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
   15917              :                     }
   15918              :                 }
   15919              :             }
   15920        56236 :           if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
   15921        53452 :                || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD)
   15922        56510 :               && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA))
   15923              :             {
   15924          534 :               remove = true;
   15925          534 :               goto end_adjust_omp_map_clause;
   15926              :             }
   15927              :           /* If we have a DECL_VALUE_EXPR (e.g. this is a class member and/or
   15928              :              a variable captured in a lambda closure), look through that now
   15929              :              before the DECL_P check below.  (A code other than COMPONENT_REF,
   15930              :              i.e. INDIRECT_REF, will be a VLA/variable-length array
   15931              :              section.  A global var may be a variable in a common block.  We
   15932              :              don't want to do this here for either of those.)  */
   15933        55702 :           if ((ctx->region_type & ORT_ACC) == 0
   15934        29495 :               && DECL_P (decl)
   15935        12608 :               && !is_global_var (decl)
   15936        11216 :               && DECL_HAS_VALUE_EXPR_P (decl)
   15937        55892 :               && TREE_CODE (DECL_VALUE_EXPR (decl)) == COMPONENT_REF)
   15938            0 :             decl = OMP_CLAUSE_DECL (c) = DECL_VALUE_EXPR (decl);
   15939        55702 :           if (TREE_CODE (decl) == TARGET_EXPR)
   15940              :             {
   15941            0 :               if (gimplify_expr (&OMP_CLAUSE_DECL (c), seq_p, NULL,
   15942              :                                  is_gimple_lvalue, fb_lvalue) == GS_ERROR)
   15943        26167 :                 remove = true;
   15944              :             }
   15945        55702 :           else if (!DECL_P (decl))
   15946              :             {
   15947        29535 :               if ((ctx->region_type & ORT_TARGET) != 0
   15948        29535 :                   && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
   15949              :                 {
   15950           24 :                   if (INDIRECT_REF_P (decl)
   15951            0 :                       && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   15952           24 :                       && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   15953              :                           == REFERENCE_TYPE))
   15954            0 :                     decl = TREE_OPERAND (decl, 0);
   15955           24 :                   if (TREE_CODE (decl) == COMPONENT_REF)
   15956              :                     {
   15957            0 :                       while (TREE_CODE (decl) == COMPONENT_REF)
   15958            0 :                         decl = TREE_OPERAND (decl, 0);
   15959            0 :                       if (DECL_P (decl))
   15960              :                         {
   15961            0 :                           n = splay_tree_lookup (ctx->variables,
   15962              :                                                  (splay_tree_key) decl);
   15963            0 :                           if (!(n->value & GOVD_SEEN))
   15964        29535 :                             remove = true;
   15965              :                         }
   15966              :                     }
   15967              :                 }
   15968              : 
   15969        29535 :               tree d = decl, *pd;
   15970        29535 :               if (TREE_CODE (d) == ARRAY_REF)
   15971              :                 {
   15972         5726 :                   while (TREE_CODE (d) == ARRAY_REF)
   15973         2923 :                     d = TREE_OPERAND (d, 0);
   15974         2803 :                   if (TREE_CODE (d) == COMPONENT_REF
   15975         2803 :                       && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
   15976              :                     decl = d;
   15977              :                 }
   15978        29535 :               pd = &OMP_CLAUSE_DECL (c);
   15979        29535 :               if (d == decl
   15980        27089 :                   && TREE_CODE (decl) == INDIRECT_REF
   15981        15450 :                   && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   15982         1470 :                   && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   15983              :                       == REFERENCE_TYPE)
   15984        30335 :                   && (OMP_CLAUSE_MAP_KIND (c)
   15985              :                       != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
   15986              :                 {
   15987          796 :                   pd = &TREE_OPERAND (decl, 0);
   15988          796 :                   decl = TREE_OPERAND (decl, 0);
   15989              :                 }
   15990              : 
   15991        29535 :               if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   15992         3066 :                 switch (code)
   15993              :                   {
   15994          427 :                   case OACC_ENTER_DATA:
   15995          427 :                   case OACC_EXIT_DATA:
   15996          427 :                     if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
   15997              :                         == ARRAY_TYPE)
   15998              :                       remove = true;
   15999          417 :                     else if (code == OACC_ENTER_DATA)
   16000          263 :                       goto change_to_attach;
   16001              :                     /* Fallthrough.  */
   16002          605 :                   case OMP_TARGET_EXIT_DATA:
   16003          605 :                     OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DETACH);
   16004          605 :                     OMP_CLAUSE_MAP_SIZE_NEEDS_ADJUSTMENT (c) = 0;
   16005          605 :                     break;
   16006           71 :                   case OACC_UPDATE:
   16007              :                     /* An "attach/detach" operation on an update directive
   16008              :                        should behave as a GOMP_MAP_ALWAYS_POINTER.  Note that
   16009              :                        both GOMP_MAP_ATTACH_DETACH and GOMP_MAP_ALWAYS_POINTER
   16010              :                        kinds depend on the previous mapping (for non-TARGET
   16011              :                        regions).  */
   16012           71 :                     OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
   16013           71 :                     break;
   16014         2390 :                   default:
   16015         2390 :                   change_to_attach:
   16016         2390 :                     gcc_assert (!OMP_CLAUSE_MAP_SIZE_NEEDS_ADJUSTMENT (c));
   16017         2390 :                     OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ATTACH);
   16018         2390 :                     if ((ctx->region_type & ORT_TARGET) != 0)
   16019         1803 :                       move_attach = true;
   16020              :                   }
   16021        26469 :               else if ((ctx->region_type & ORT_TARGET) != 0
   16022        26469 :                        && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   16023        11798 :                            || (OMP_CLAUSE_MAP_KIND (c)
   16024              :                                == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)))
   16025              :                 move_attach = true;
   16026              : 
   16027              :               /* If we have e.g. map(struct: *var), don't gimplify the
   16028              :                  argument since omp-low.cc wants to see the decl itself.  */
   16029        29535 :               if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
   16030         1136 :                 goto end_adjust_omp_map_clause;
   16031              : 
   16032              :               /* We've already partly gimplified this in
   16033              :                  gimplify_scan_omp_clauses.  Don't do any more.  */
   16034        28399 :               if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
   16035           88 :                 goto end_adjust_omp_map_clause;
   16036              : 
   16037        28311 :               gimplify_omp_ctxp = ctx->outer_context;
   16038        28311 :               if (gimplify_expr (pd, seq_p, NULL, is_gimple_lvalue,
   16039              :                                  fb_lvalue) == GS_ERROR)
   16040            0 :                 remove = true;
   16041        28311 :               gimplify_omp_ctxp = ctx;
   16042        28311 :               goto end_adjust_omp_map_clause;
   16043              :             }
   16044              : 
   16045        26167 :          if ((code == OMP_TARGET
   16046              :               || code == OMP_TARGET_DATA
   16047              :               || code == OMP_TARGET_ENTER_DATA
   16048        14448 :               || code == OMP_TARGET_EXIT_DATA)
   16049        26794 :              && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   16050              :            {
   16051          238 :              bool firstprivatize = false;
   16052              : 
   16053          243 :              for (struct gimplify_omp_ctx *octx = ctx->outer_context; octx;
   16054            5 :                   octx = octx->outer_context)
   16055              :                {
   16056            6 :                  splay_tree_node n
   16057           12 :                    = splay_tree_lookup (octx->variables,
   16058            6 :                                         (splay_tree_key) OMP_CLAUSE_DECL (c));
   16059              :                  /* If this is contained in an outer OpenMP region as a
   16060              :                     firstprivate value, remove the attach/detach.  */
   16061            6 :                  if (n && (n->value & GOVD_FIRSTPRIVATE))
   16062              :                    {
   16063              :                      firstprivatize = true;
   16064              :                      break;
   16065              :                    }
   16066              :                }
   16067              : 
   16068          238 :              enum gomp_map_kind map_kind;
   16069          238 :              if (firstprivatize)
   16070              :                map_kind = GOMP_MAP_FIRSTPRIVATE_POINTER;
   16071          237 :              else if (code == OMP_TARGET_EXIT_DATA)
   16072              :                map_kind = GOMP_MAP_DETACH;
   16073              :              else
   16074          186 :                map_kind = GOMP_MAP_ATTACH;
   16075          238 :              OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
   16076              :            }
   16077        25929 :          else if ((ctx->region_type & ORT_ACC) != 0
   16078        25929 :                   && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   16079              :            {
   16080            0 :              enum gomp_map_kind map_kind = (code == OACC_EXIT_DATA
   16081            0 :                                             ? GOMP_MAP_DETACH
   16082              :                                             : GOMP_MAP_ATTACH);
   16083            0 :              OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
   16084              :            }
   16085              : 
   16086        26167 :           n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   16087        26167 :           if ((ctx->region_type & ORT_TARGET) != 0
   16088        16254 :               && !(n->value & GOVD_SEEN)
   16089         1487 :               && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
   16090        27407 :               && (!is_global_var (decl)
   16091           75 :                   || !lookup_attribute ("omp declare target link",
   16092           75 :                                         DECL_ATTRIBUTES (decl))))
   16093              :             {
   16094         1228 :               remove = true;
   16095              :               /* For struct element mapping, if struct is never referenced
   16096              :                  in target block and none of the mapping has always modifier,
   16097              :                  remove all the struct element mappings, which immediately
   16098              :                  follow the GOMP_MAP_STRUCT map clause.  */
   16099         1228 :               if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
   16100         1228 :                   || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD)
   16101              :                 {
   16102           30 :                   HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
   16103           80 :                   while (cnt--)
   16104           50 :                     OMP_CLAUSE_CHAIN (c)
   16105           50 :                       = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
   16106              :                 }
   16107              :             }
   16108        24939 :           else if (DECL_SIZE (decl)
   16109        24915 :                    && !poly_int_tree_p (DECL_SIZE (decl))
   16110          199 :                    && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
   16111          199 :                    && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
   16112        24990 :                    && (OMP_CLAUSE_MAP_KIND (c)
   16113              :                        != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   16114              :             {
   16115              :               /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
   16116              :                  for these, TREE_CODE (DECL_SIZE (decl)) will always be
   16117              :                  INTEGER_CST.  */
   16118           51 :               gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
   16119              : 
   16120           51 :               tree decl2 = DECL_VALUE_EXPR (decl);
   16121           51 :               gcc_assert (INDIRECT_REF_P (decl2));
   16122           51 :               decl2 = TREE_OPERAND (decl2, 0);
   16123           51 :               gcc_assert (DECL_P (decl2));
   16124           51 :               tree mem = build_simple_mem_ref (decl2);
   16125           51 :               OMP_CLAUSE_DECL (c) = mem;
   16126           51 :               OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
   16127           51 :               if (ctx->outer_context)
   16128              :                 {
   16129           15 :                   omp_notice_variable (ctx->outer_context, decl2, true);
   16130           30 :                   omp_notice_variable (ctx->outer_context,
   16131           15 :                                        OMP_CLAUSE_SIZE (c), true);
   16132              :                 }
   16133           51 :               if (((ctx->region_type & ORT_TARGET) != 0
   16134           24 :                    || !ctx->target_firstprivatize_array_bases)
   16135           34 :                   && ((n->value & GOVD_SEEN) == 0
   16136           30 :                       || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
   16137              :                 {
   16138           34 :                   tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   16139              :                                               OMP_CLAUSE_MAP);
   16140           34 :                   OMP_CLAUSE_DECL (nc) = decl;
   16141           34 :                   OMP_CLAUSE_SIZE (nc) = size_zero_node;
   16142           34 :                   if (ctx->target_firstprivatize_array_bases)
   16143           27 :                     OMP_CLAUSE_SET_MAP_KIND (nc,
   16144              :                                              GOMP_MAP_FIRSTPRIVATE_POINTER);
   16145              :                   else
   16146            7 :                     OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
   16147           34 :                   OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
   16148           34 :                   OMP_CLAUSE_CHAIN (c) = nc;
   16149           34 :                   c = nc;
   16150              :                 }
   16151              :             }
   16152              :           else
   16153              :             {
   16154        24888 :               if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   16155            0 :                 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
   16156        24888 :               gcc_assert ((n->value & GOVD_SEEN) == 0
   16157              :                           || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
   16158              :                               == 0));
   16159              :             }
   16160              : 
   16161              :           /* If we have a target region, we can push all the attaches to the
   16162              :              end of the list (we may have standalone "attach" operations
   16163              :              synthesized for GOMP_MAP_STRUCT nodes that must be processed after
   16164              :              the attachment point AND the pointed-to block have been mapped).
   16165              :              If we have something else, e.g. "enter data", we need to keep
   16166              :              "attach" nodes together with the previous node they attach to so
   16167              :              that separate "exit data" operations work properly (see
   16168              :              libgomp/target.c).  */
   16169        26167 :           if ((ctx->region_type & ORT_TARGET) != 0
   16170        26167 :               && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   16171        16138 :                   || (OMP_CLAUSE_MAP_KIND (c)
   16172              :                       == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)))
   16173              :             move_attach = true;
   16174              : 
   16175        56326 : end_adjust_omp_map_clause:
   16176        56326 :           exit_omp_iterator_loop_context (c);
   16177        56326 :           break;
   16178              : 
   16179         8333 :         case OMP_CLAUSE_TO:
   16180         8333 :         case OMP_CLAUSE_FROM:
   16181         8333 :         case OMP_CLAUSE__CACHE_:
   16182         8333 :           decl = OMP_CLAUSE_DECL (c);
   16183         8333 :           if (!DECL_P (decl))
   16184              :             break;
   16185         6189 :           if (DECL_SIZE (decl)
   16186         6189 :               && !poly_int_tree_p (DECL_SIZE (decl)))
   16187              :             {
   16188            4 :               tree decl2 = DECL_VALUE_EXPR (decl);
   16189            4 :               gcc_assert (INDIRECT_REF_P (decl2));
   16190            4 :               decl2 = TREE_OPERAND (decl2, 0);
   16191            4 :               gcc_assert (DECL_P (decl2));
   16192            4 :               tree mem = build_simple_mem_ref (decl2);
   16193            4 :               OMP_CLAUSE_DECL (c) = mem;
   16194            4 :               OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
   16195            4 :               if (ctx->outer_context)
   16196              :                 {
   16197            4 :                   omp_notice_variable (ctx->outer_context, decl2, true);
   16198            4 :                   omp_notice_variable (ctx->outer_context,
   16199            4 :                                        OMP_CLAUSE_SIZE (c), true);
   16200              :                 }
   16201              :             }
   16202         6185 :           else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   16203            0 :             OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
   16204              :           break;
   16205              : 
   16206        15215 :         case OMP_CLAUSE_REDUCTION:
   16207        15215 :           if (OMP_CLAUSE_REDUCTION_INSCAN (c))
   16208              :             {
   16209          811 :               decl = OMP_CLAUSE_DECL (c);
   16210          811 :               n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   16211          811 :               if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
   16212              :                 {
   16213           69 :                   remove = true;
   16214           69 :                   error_at (OMP_CLAUSE_LOCATION (c),
   16215              :                             "%qD specified in %<inscan%> %<reduction%> clause "
   16216              :                             "but not in %<scan%> directive clause", decl);
   16217           69 :                   break;
   16218              :                 }
   16219              :               has_inscan_reductions = true;
   16220              :             }
   16221              :           /* FALLTHRU */
   16222        17750 :         case OMP_CLAUSE_IN_REDUCTION:
   16223        17750 :         case OMP_CLAUSE_TASK_REDUCTION:
   16224        17750 :           decl = OMP_CLAUSE_DECL (c);
   16225              :           /* OpenACC reductions need a present_or_copy data clause.
   16226              :              Add one if necessary.  Emit error when the reduction is private.  */
   16227        17750 :           if (ctx->region_type == ORT_ACC_PARALLEL
   16228        17218 :               || ctx->region_type == ORT_ACC_SERIAL)
   16229              :             {
   16230          803 :               n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   16231          803 :               if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
   16232              :                 {
   16233           13 :                   remove = true;
   16234           13 :                   error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
   16235           13 :                             "reduction on %qE", DECL_NAME (decl));
   16236              :                 }
   16237          790 :               else if ((n->value & GOVD_MAP) == 0)
   16238              :                 {
   16239          524 :                   tree next = OMP_CLAUSE_CHAIN (c);
   16240          524 :                   tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
   16241          524 :                   OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
   16242          524 :                   OMP_CLAUSE_DECL (nc) = decl;
   16243          524 :                   OMP_CLAUSE_CHAIN (c) = nc;
   16244          524 :                   lang_hooks.decls.omp_finish_clause (nc, pre_p,
   16245          524 :                                                       (ctx->region_type
   16246              :                                                        & ORT_ACC) != 0);
   16247          550 :                   while (1)
   16248              :                     {
   16249          537 :                       OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
   16250          537 :                       if (OMP_CLAUSE_CHAIN (nc) == NULL)
   16251              :                         break;
   16252           13 :                       nc = OMP_CLAUSE_CHAIN (nc);
   16253              :                     }
   16254          524 :                   OMP_CLAUSE_CHAIN (nc) = next;
   16255          524 :                   n->value |= GOVD_MAP;
   16256              :                 }
   16257              :             }
   16258        17750 :           if (DECL_P (decl)
   16259        17750 :               && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   16260         7963 :             omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   16261              :           break;
   16262              : 
   16263         3541 :         case OMP_CLAUSE_ALLOCATE:
   16264         3541 :           decl = OMP_CLAUSE_DECL (c);
   16265         3541 :           n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   16266         3541 :           if (n != NULL && !(n->value & GOVD_SEEN))
   16267              :             {
   16268         1176 :               if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
   16269              :                   != 0
   16270         1176 :                   && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
   16271              :                 remove = true;
   16272              :             }
   16273              :           if (!remove
   16274         2365 :               && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
   16275         1273 :               && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
   16276          483 :               && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
   16277          347 :                   || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
   16278          287 :                   || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
   16279              :             {
   16280          214 :               tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
   16281          214 :               n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
   16282          214 :               if (n == NULL)
   16283              :                 {
   16284           92 :                   enum omp_clause_default_kind default_kind
   16285              :                     = ctx->default_kind;
   16286           92 :                   ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
   16287           92 :                   omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
   16288              :                                        true);
   16289           92 :                   ctx->default_kind = default_kind;
   16290              :                 }
   16291              :               else
   16292          122 :                 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
   16293              :                                      true);
   16294              :             }
   16295              :           break;
   16296              : 
   16297              :         case OMP_CLAUSE_COPYIN:
   16298              :         case OMP_CLAUSE_COPYPRIVATE:
   16299              :         case OMP_CLAUSE_IF:
   16300              :         case OMP_CLAUSE_SELF:
   16301              :         case OMP_CLAUSE_NUM_THREADS:
   16302              :         case OMP_CLAUSE_NUM_TEAMS:
   16303              :         case OMP_CLAUSE_THREAD_LIMIT:
   16304              :         case OMP_CLAUSE_DIST_SCHEDULE:
   16305              :         case OMP_CLAUSE_DEVICE:
   16306              :         case OMP_CLAUSE_SCHEDULE:
   16307              :         case OMP_CLAUSE_NOWAIT:
   16308              :         case OMP_CLAUSE_ORDERED:
   16309              :         case OMP_CLAUSE_DEFAULT:
   16310              :         case OMP_CLAUSE_UNTIED:
   16311              :         case OMP_CLAUSE_COLLAPSE:
   16312              :         case OMP_CLAUSE_FINAL:
   16313              :         case OMP_CLAUSE_MERGEABLE:
   16314              :         case OMP_CLAUSE_PROC_BIND:
   16315              :         case OMP_CLAUSE_SAFELEN:
   16316              :         case OMP_CLAUSE_SIMDLEN:
   16317              :         case OMP_CLAUSE_DEPEND:
   16318              :         case OMP_CLAUSE_DOACROSS:
   16319              :         case OMP_CLAUSE_PRIORITY:
   16320              :         case OMP_CLAUSE_GRAINSIZE:
   16321              :         case OMP_CLAUSE_NUM_TASKS:
   16322              :         case OMP_CLAUSE_NOGROUP:
   16323              :         case OMP_CLAUSE_THREADS:
   16324              :         case OMP_CLAUSE_SIMD:
   16325              :         case OMP_CLAUSE_FILTER:
   16326              :         case OMP_CLAUSE_HINT:
   16327              :         case OMP_CLAUSE_DEFAULTMAP:
   16328              :         case OMP_CLAUSE_ORDER:
   16329              :         case OMP_CLAUSE_BIND:
   16330              :         case OMP_CLAUSE_DETACH:
   16331              :         case OMP_CLAUSE_USE_DEVICE_PTR:
   16332              :         case OMP_CLAUSE_USE_DEVICE_ADDR:
   16333              :         case OMP_CLAUSE_ASYNC:
   16334              :         case OMP_CLAUSE_WAIT:
   16335              :         case OMP_CLAUSE_INDEPENDENT:
   16336              :         case OMP_CLAUSE_NUM_GANGS:
   16337              :         case OMP_CLAUSE_NUM_WORKERS:
   16338              :         case OMP_CLAUSE_VECTOR_LENGTH:
   16339              :         case OMP_CLAUSE_GANG:
   16340              :         case OMP_CLAUSE_WORKER:
   16341              :         case OMP_CLAUSE_VECTOR:
   16342              :         case OMP_CLAUSE_AUTO:
   16343              :         case OMP_CLAUSE_SEQ:
   16344              :         case OMP_CLAUSE_TILE:
   16345              :         case OMP_CLAUSE_IF_PRESENT:
   16346              :         case OMP_CLAUSE_FINALIZE:
   16347              :         case OMP_CLAUSE_INCLUSIVE:
   16348              :         case OMP_CLAUSE_EXCLUSIVE:
   16349              :         case OMP_CLAUSE_USES_ALLOCATORS:
   16350              :         case OMP_CLAUSE_DEVICE_TYPE:
   16351              :           break;
   16352              : 
   16353            0 :         case OMP_CLAUSE_NOHOST:
   16354            0 :         default:
   16355            0 :           gcc_unreachable ();
   16356              :         }
   16357              : 
   16358       129600 :       if (remove)
   16359         9911 :         *list_p = OMP_CLAUSE_CHAIN (c);
   16360       238929 :       else if (move_attach)
   16361              :         {
   16362              :           /* Remove attach node from here, separate out into its own list.  */
   16363         2360 :           *attach_tail = c;
   16364         2360 :           *list_p = OMP_CLAUSE_CHAIN (c);
   16365         2360 :           OMP_CLAUSE_CHAIN (c) = NULL_TREE;
   16366         2360 :           attach_tail = &OMP_CLAUSE_CHAIN (c);
   16367              :         }
   16368              :       else
   16369       236569 :         list_p = &OMP_CLAUSE_CHAIN (c);
   16370              :     }
   16371              : 
   16372              :   /* Splice attach nodes at the end of the list.  */
   16373       129101 :   if (attach_list)
   16374              :     {
   16375         1127 :       *list_p = attach_list;
   16376         1127 :       list_p = attach_tail;
   16377              :     }
   16378              : 
   16379              :   /* Add in any implicit data sharing.  */
   16380       129101 :   struct gimplify_adjust_omp_clauses_data data;
   16381       129101 :   if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
   16382              :     {
   16383              :       /* OpenMP.  Implicit clauses are added at the start of the clause list,
   16384              :          but after any non-map clauses.  */
   16385              :       tree *implicit_add_list_p = orig_list_p;
   16386       252488 :       while (*implicit_add_list_p
   16387       252488 :              && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
   16388       153234 :         implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
   16389        99254 :       data.list_p = implicit_add_list_p;
   16390              :     }
   16391              :   else
   16392              :     /* OpenACC.  */
   16393        29847 :     data.list_p = list_p;
   16394       129101 :   data.pre_p = pre_p;
   16395       129101 :   splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
   16396              : 
   16397       129101 :   if (has_inscan_reductions)
   16398         2431 :     for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
   16399         1822 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   16400         1822 :           && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   16401              :         {
   16402            5 :           error_at (OMP_CLAUSE_LOCATION (c),
   16403              :                     "%<inscan%> %<reduction%> clause used together with "
   16404              :                     "%<linear%> clause for a variable other than loop "
   16405              :                     "iterator");
   16406            5 :           break;
   16407              :         }
   16408              : 
   16409       129101 :   gimplify_omp_ctxp = ctx->outer_context;
   16410       129101 :   delete_omp_context (ctx);
   16411       129101 : }
   16412              : 
   16413              : /* Try to evaluate a novariants clause. Return 1 if true, 0 if false or absent,
   16414              :  * -1 if run-time evaluation is needed. */
   16415              : 
   16416              : int
   16417       250896 : omp_has_novariants (void)
   16418              : {
   16419       250896 :   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   16420       250896 :   if (ctx != NULL && ctx->code == OMP_DISPATCH && !ctx->in_call_args)
   16421              :     {
   16422         3290 :       tree c = omp_find_clause (ctx->clauses, OMP_CLAUSE_NOVARIANTS);
   16423         3290 :       if (c != NULL_TREE)
   16424              :         {
   16425          299 :           if (integer_nonzerop (OMP_CLAUSE_NOVARIANTS_EXPR (c)))
   16426              :             return 1;
   16427          171 :           else if (integer_zerop (OMP_CLAUSE_NOVARIANTS_EXPR (c)))
   16428              :             return 0;
   16429              :           else
   16430              :             return -1;
   16431              :         }
   16432              :       return 0;
   16433              :     }
   16434              :   return 0;
   16435              : }
   16436              : 
   16437              : /* Try to evaluate a nocontext clause. Return 1 if true, 0 if false or absent,
   16438              :  * -1 if run-time evaluation is needed. */
   16439              : 
   16440              : static int
   16441         1903 : omp_has_nocontext (void)
   16442              : {
   16443         1903 :   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   16444         1903 :   if (ctx != NULL && ctx->code == OMP_DISPATCH)
   16445              :     {
   16446         1903 :       tree c = omp_find_clause (ctx->clauses, OMP_CLAUSE_NOCONTEXT);
   16447         1903 :       if (c != NULL_TREE)
   16448              :         {
   16449          256 :           if (integer_nonzerop (OMP_CLAUSE_NOCONTEXT_EXPR (c)))
   16450              :             return 1;
   16451           94 :           else if (integer_zerop (OMP_CLAUSE_NOCONTEXT_EXPR (c)))
   16452              :             return 0;
   16453              :           else
   16454              :             return -1;
   16455              :         }
   16456              :       return 0;
   16457              :     }
   16458              :   return 0;
   16459              : }
   16460              : 
   16461              : /* Collect a list of traits for enclosing constructs in the current
   16462              :    OpenMP context.  The list is in the same format as the trait selector
   16463              :    list of construct trait sets built by the front ends.
   16464              : 
   16465              :    Per the OpenMP specification, the construct trait set includes constructs
   16466              :    up to an enclosing "target" construct.  If there is no "target" construct,
   16467              :    then additional things may be added to the construct trait set (simd for
   16468              :    simd clones, additional constructs associated with "declare variant",
   16469              :    the target trait for "declare target"); those are not handled here.
   16470              :    In particular simd clones are not known during gimplification so
   16471              :    matching/scoring of context selectors that might involve them needs
   16472              :    to be deferred to the omp_device_lower pass.  */
   16473              : 
   16474              : tree
   16475         2213 : omp_get_construct_context (void)
   16476              : {
   16477         2213 :   tree result = NULL_TREE;
   16478         4184 :   for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
   16479              :     {
   16480         2092 :       if (((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
   16481              :                 == ORT_TARGET)
   16482          121 :                && ctx->code == OMP_TARGET)
   16483              :         {
   16484          121 :           result = make_trait_selector (OMP_TRAIT_CONSTRUCT_TARGET,
   16485              :                                         NULL_TREE, NULL_TREE, result);
   16486              :           /* We're not interested in any outer constructs.  */
   16487          121 :           break;
   16488              :         }
   16489         1971 :       else if ((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
   16490          214 :         result = make_trait_selector (OMP_TRAIT_CONSTRUCT_PARALLEL,
   16491              :                                       NULL_TREE, NULL_TREE, result);
   16492         1757 :       else if ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
   16493           75 :         result = make_trait_selector (OMP_TRAIT_CONSTRUCT_TEAMS,
   16494              :                                       NULL_TREE, NULL_TREE, result);
   16495         1682 :       else if (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
   16496          164 :         result = make_trait_selector (OMP_TRAIT_CONSTRUCT_FOR,
   16497              :                                       NULL_TREE, NULL_TREE, result);
   16498         1518 :       else if (ctx->code == OMP_DISPATCH && omp_has_nocontext () != 1)
   16499         1279 :         result = make_trait_selector (OMP_TRAIT_CONSTRUCT_DISPATCH,
   16500              :                                       NULL_TREE, NULL_TREE, result);
   16501          239 :       else if (ctx->region_type == ORT_SIMD
   16502           32 :                && ctx->code == OMP_SIMD
   16503          271 :                && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND))
   16504              :         {
   16505           32 :           tree props = NULL_TREE;
   16506           32 :           tree *last = &props;
   16507           72 :           for (tree c = ctx->clauses; c; c = OMP_CLAUSE_CHAIN (c))
   16508           40 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SIMDLEN
   16509           32 :                 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INBRANCH
   16510           72 :                 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOTINBRANCH)
   16511              :               {
   16512            8 :                 *last = unshare_expr (c);
   16513            8 :                 last = &(OMP_CLAUSE_CHAIN (c));
   16514              :               }
   16515           32 :           result = make_trait_selector (OMP_TRAIT_CONSTRUCT_SIMD,
   16516              :                                         NULL_TREE, props, result);
   16517              :         }
   16518          207 :       else if (ctx->region_type == ORT_WORKSHARE
   16519            5 :                && ctx->code == OMP_LOOP
   16520            0 :                && ctx->outer_context
   16521            0 :                && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
   16522            0 :                && ctx->outer_context->outer_context
   16523            0 :                && ctx->outer_context->outer_context->code == OMP_LOOP
   16524            0 :                && ctx->outer_context->outer_context->distribute)
   16525         1971 :         ctx = ctx->outer_context->outer_context;
   16526         1971 :       ctx = ctx->outer_context;
   16527              :     }
   16528              : 
   16529         2213 :   return result;
   16530              : }
   16531              : 
   16532              : /* Gimplify OACC_CACHE.  */
   16533              : 
   16534              : static void
   16535          665 : gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
   16536              : {
   16537          665 :   tree expr = *expr_p;
   16538              : 
   16539          665 :   gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
   16540              :                              OACC_CACHE);
   16541          665 :   gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
   16542              :                                OACC_CACHE);
   16543              : 
   16544              :   /* TODO: Do something sensible with this information.  */
   16545              : 
   16546          665 :   *expr_p = NULL_TREE;
   16547          665 : }
   16548              : 
   16549              : /* Helper function of gimplify_oacc_declare.  The helper's purpose is to,
   16550              :    if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
   16551              :    kind.  The entry kind will replace the one in CLAUSE, while the exit
   16552              :    kind will be used in a new omp_clause and returned to the caller.  */
   16553              : 
   16554              : static tree
   16555          190 : gimplify_oacc_declare_1 (tree clause)
   16556              : {
   16557          190 :   HOST_WIDE_INT kind, new_op;
   16558          190 :   bool ret = false;
   16559          190 :   tree c = NULL;
   16560              : 
   16561          190 :   kind = OMP_CLAUSE_MAP_KIND (clause);
   16562              : 
   16563          190 :   switch (kind)
   16564              :     {
   16565              :       case GOMP_MAP_ALLOC:
   16566              :         new_op = GOMP_MAP_RELEASE;
   16567              :         ret = true;
   16568              :         break;
   16569              : 
   16570           29 :       case GOMP_MAP_FROM:
   16571           29 :         OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
   16572           29 :         new_op = GOMP_MAP_FROM;
   16573           29 :         ret = true;
   16574           29 :         break;
   16575              : 
   16576           40 :       case GOMP_MAP_TOFROM:
   16577           40 :         OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
   16578           40 :         new_op = GOMP_MAP_FROM;
   16579           40 :         ret = true;
   16580           40 :         break;
   16581              : 
   16582              :       case GOMP_MAP_DEVICE_RESIDENT:
   16583              :       case GOMP_MAP_FORCE_DEVICEPTR:
   16584              :       case GOMP_MAP_FORCE_PRESENT:
   16585              :       case GOMP_MAP_LINK:
   16586              :       case GOMP_MAP_POINTER:
   16587              :       case GOMP_MAP_TO:
   16588              :         break;
   16589              : 
   16590            0 :       default:
   16591            0 :         gcc_unreachable ();
   16592           69 :         break;
   16593              :     }
   16594              : 
   16595           69 :   if (ret)
   16596              :     {
   16597          116 :       c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
   16598          116 :       OMP_CLAUSE_SET_MAP_KIND (c, new_op);
   16599          116 :       OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
   16600              :     }
   16601              : 
   16602          190 :   return c;
   16603              : }
   16604              : 
   16605              : /* Gimplify OACC_DECLARE.  */
   16606              : 
   16607              : static void
   16608          254 : gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
   16609              : {
   16610          254 :   tree expr = *expr_p;
   16611          254 :   gomp_target *stmt;
   16612          254 :   tree clauses, t, decl;
   16613              : 
   16614          254 :   clauses = OACC_DECLARE_CLAUSES (expr);
   16615              : 
   16616          254 :   gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
   16617          254 :   gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
   16618              : 
   16619          516 :   for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
   16620              :     {
   16621          262 :       decl = OMP_CLAUSE_DECL (t);
   16622              : 
   16623          262 :       if (TREE_CODE (decl) == MEM_REF)
   16624            8 :         decl = TREE_OPERAND (decl, 0);
   16625              : 
   16626          262 :       if (VAR_P (decl) && !is_oacc_declared (decl))
   16627              :         {
   16628          262 :           tree attr = get_identifier ("oacc declare target");
   16629          262 :           DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
   16630          262 :                                               DECL_ATTRIBUTES (decl));
   16631              :         }
   16632              : 
   16633          262 :       if (VAR_P (decl)
   16634          262 :           && !is_global_var (decl)
   16635          452 :           && DECL_CONTEXT (decl) == current_function_decl)
   16636              :         {
   16637          190 :           tree c = gimplify_oacc_declare_1 (t);
   16638          190 :           if (c)
   16639              :             {
   16640          116 :               if (oacc_declare_returns == NULL)
   16641           40 :                 oacc_declare_returns = new hash_map<tree, tree>;
   16642              : 
   16643          116 :               oacc_declare_returns->put (decl, c);
   16644              :             }
   16645              :         }
   16646              : 
   16647          262 :       if (gimplify_omp_ctxp)
   16648           72 :         omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
   16649              :     }
   16650              : 
   16651          254 :   stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
   16652              :                                   clauses);
   16653              : 
   16654          254 :   gimplify_seq_add_stmt (pre_p, stmt);
   16655              : 
   16656          254 :   *expr_p = NULL_TREE;
   16657          254 : }
   16658              : 
   16659              : /* Gimplify the contents of an OMP_PARALLEL statement.  This involves
   16660              :    gimplification of the body, as well as scanning the body for used
   16661              :    variables.  We need to do this scan now, because variable-sized
   16662              :    decls will be decomposed during gimplification.  */
   16663              : 
   16664              : static void
   16665        18244 : gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
   16666              : {
   16667        18244 :   tree expr = *expr_p;
   16668        18244 :   gimple *g;
   16669        18244 :   gimple_seq body = NULL;
   16670              : 
   16671        36488 :   gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
   16672        18244 :                              OMP_PARALLEL_COMBINED (expr)
   16673              :                              ? ORT_COMBINED_PARALLEL
   16674              :                              : ORT_PARALLEL, OMP_PARALLEL);
   16675              : 
   16676        18244 :   push_gimplify_context ();
   16677              : 
   16678        18244 :   g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
   16679        18244 :   if (gimple_code (g) == GIMPLE_BIND)
   16680        18244 :     pop_gimplify_context (g);
   16681              :   else
   16682            0 :     pop_gimplify_context (NULL);
   16683              : 
   16684        18244 :   gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
   16685              :                                OMP_PARALLEL);
   16686              : 
   16687        36488 :   g = gimple_build_omp_parallel (body,
   16688        18244 :                                  OMP_PARALLEL_CLAUSES (expr),
   16689              :                                  NULL_TREE, NULL_TREE);
   16690        18244 :   if (OMP_PARALLEL_COMBINED (expr))
   16691        12538 :     gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
   16692        18244 :   gimplify_seq_add_stmt (pre_p, g);
   16693        18244 :   *expr_p = NULL_TREE;
   16694        18244 : }
   16695              : 
   16696              : /* Gimplify the contents of an OMP_TASK statement.  This involves
   16697              :    gimplification of the body, as well as scanning the body for used
   16698              :    variables.  We need to do this scan now, because variable-sized
   16699              :    decls will be decomposed during gimplification.  */
   16700              : 
   16701              : static void
   16702         3855 : gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
   16703              : {
   16704         3855 :   tree expr = *expr_p;
   16705         3855 :   gimple *g;
   16706         3855 :   gimple_seq body = NULL;
   16707         3855 :   bool nowait = false;
   16708         3855 :   bool has_depend = false;
   16709              : 
   16710         3855 :   if (OMP_TASK_BODY (expr) == NULL_TREE)
   16711              :     {
   16712          242 :       for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   16713          153 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   16714              :           {
   16715          111 :             has_depend = true;
   16716          111 :             if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
   16717              :               {
   16718            9 :                 error_at (OMP_CLAUSE_LOCATION (c),
   16719              :                           "%<mutexinoutset%> kind in %<depend%> clause on a "
   16720              :                           "%<taskwait%> construct");
   16721            9 :                 break;
   16722              :               }
   16723              :           }
   16724           42 :         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOWAIT)
   16725           42 :           nowait = true;
   16726           98 :       if (nowait && !has_depend)
   16727              :         {
   16728            5 :           error_at (EXPR_LOCATION (expr),
   16729              :                     "%<taskwait%> construct with %<nowait%> clause but no "
   16730              :                     "%<depend%> clauses");
   16731            5 :           *expr_p = NULL_TREE;
   16732            5 :           return;
   16733              :         }
   16734              :     }
   16735              : 
   16736        11550 :   gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
   16737         3850 :                              omp_find_clause (OMP_TASK_CLAUSES (expr),
   16738              :                                               OMP_CLAUSE_UNTIED)
   16739              :                              ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
   16740              : 
   16741         3850 :   if (OMP_TASK_BODY (expr))
   16742              :     {
   16743         3757 :       push_gimplify_context ();
   16744              : 
   16745         3757 :       g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
   16746         3757 :       if (gimple_code (g) == GIMPLE_BIND)
   16747         3757 :         pop_gimplify_context (g);
   16748              :       else
   16749            0 :         pop_gimplify_context (NULL);
   16750              :     }
   16751              : 
   16752         3850 :   gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
   16753              :                                OMP_TASK);
   16754              : 
   16755         7700 :   g = gimple_build_omp_task (body,
   16756         3850 :                              OMP_TASK_CLAUSES (expr),
   16757              :                              NULL_TREE, NULL_TREE,
   16758              :                              NULL_TREE, NULL_TREE, NULL_TREE);
   16759         3850 :   if (OMP_TASK_BODY (expr) == NULL_TREE)
   16760           93 :     gimple_omp_task_set_taskwait_p (g, true);
   16761         3850 :   gimplify_seq_add_stmt (pre_p, g);
   16762         3850 :   *expr_p = NULL_TREE;
   16763              : }
   16764              : 
   16765              : /* Helper function for gimplify_omp_for.  If *TP is not a gimple constant,
   16766              :    force it into a temporary initialized in PRE_P and add firstprivate clause
   16767              :    to ORIG_FOR_STMT.  */
   16768              : 
   16769              : static void
   16770         4399 : gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
   16771              :                             tree orig_for_stmt)
   16772              : {
   16773         4399 :   if (*tp == NULL || is_gimple_constant (*tp))
   16774              :     return;
   16775              : 
   16776          779 :   if (TREE_CODE (*tp) == SAVE_EXPR)
   16777          135 :     gimplify_save_expr (tp, pre_p, NULL);
   16778              :   else
   16779          644 :     *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
   16780              :   /* Reference to pointer conversion is considered useless,
   16781              :      but is significant for firstprivate clause.  Force it
   16782              :      here.  */
   16783          779 :   if (type
   16784          687 :       && TREE_CODE (type) == POINTER_TYPE
   16785          869 :       && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
   16786              :     {
   16787            2 :       tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
   16788            2 :       tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
   16789            2 :       gimplify_and_add (m, pre_p);
   16790            2 :       *tp = v;
   16791              :     }
   16792              : 
   16793          779 :   tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
   16794          779 :   OMP_CLAUSE_DECL (c) = *tp;
   16795          779 :   OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
   16796          779 :   OMP_FOR_CLAUSES (orig_for_stmt) = c;
   16797              : }
   16798              : 
   16799              : /* Helper function of gimplify_omp_for, find OMP_ORDERED with
   16800              :    null OMP_ORDERED_BODY inside of OMP_FOR's body.  */
   16801              : 
   16802              : static tree
   16803        16496 : find_standalone_omp_ordered (tree *tp, int *walk_subtrees, void *)
   16804              : {
   16805        16496 :   switch (TREE_CODE (*tp))
   16806              :     {
   16807          901 :     case OMP_ORDERED:
   16808          901 :       if (OMP_ORDERED_BODY (*tp) == NULL_TREE)
   16809              :         return *tp;
   16810              :       break;
   16811           23 :     case OMP_SIMD:
   16812           23 :     case OMP_PARALLEL:
   16813           23 :     case OMP_TARGET:
   16814           23 :       *walk_subtrees = 0;
   16815           23 :       break;
   16816              :     default:
   16817              :       break;
   16818              :     }
   16819              :   return NULL_TREE;
   16820              : }
   16821              : 
   16822              : /* Gimplify standalone loop transforming directive which has the
   16823              :    transformations applied already.  So, all that is needed is gimplify
   16824              :    the remaining loops as normal loops.  */
   16825              : 
   16826              : static enum gimplify_status
   16827         2264 : gimplify_omp_loop_xform (tree *expr_p, gimple_seq *pre_p)
   16828              : {
   16829         2264 :   tree for_stmt = *expr_p;
   16830              : 
   16831         2264 :   if (OMP_FOR_PRE_BODY (for_stmt))
   16832          759 :     gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), pre_p);
   16833              : 
   16834         2264 :   gimple_seq pre_body = NULL, post_body = NULL;
   16835         5203 :   for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   16836              :     {
   16837         2939 :       if (TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i) == NULL_TREE)
   16838         1707 :         continue;
   16839         1283 :       tree iters = NULL_TREE;
   16840         1283 :       if (i == 0
   16841          826 :           && TREE_CODE (for_stmt) == OMP_UNROLL
   16842         1771 :           && !omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_PARTIAL))
   16843              :         {
   16844          311 :           if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_FULL))
   16845          269 :             iters = omp_loop_number_of_iterations (for_stmt, 0, NULL);
   16846              :           else
   16847           42 :             iters = build_int_cst (integer_type_node, 8);
   16848              :         }
   16849         1283 :       tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   16850         1283 :       gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   16851         1283 :       tree decl = TREE_OPERAND (t, 0);
   16852         1283 :       gcc_assert (DECL_P (decl));
   16853         1283 :       gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
   16854              :                   || POINTER_TYPE_P (TREE_TYPE (decl)));
   16855         1283 :       if (DECL_ARTIFICIAL (decl)
   16856          876 :           && TREE_PRIVATE (t)
   16857          867 :           && gimplify_omp_ctxp
   16858         1613 :           && gimplify_omp_ctxp->region_type != ORT_NONE)
   16859              :         {
   16860              :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   16861          504 :           do
   16862              :             {
   16863          504 :               splay_tree_node n
   16864          504 :                 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   16865          504 :               if (n != NULL)
   16866              :                 break;
   16867          346 :               else if (ctx->region_type != ORT_WORKSHARE
   16868              :                        && ctx->region_type != ORT_TASKGROUP
   16869           62 :                        && ctx->region_type != ORT_SIMD
   16870           38 :                        && ctx->region_type != ORT_ACC
   16871           38 :                        && !(ctx->region_type & ORT_TARGET_DATA))
   16872              :                 {
   16873           38 :                   omp_add_variable (ctx, decl, GOVD_PRIVATE);
   16874           38 :                   break;
   16875              :                 }
   16876          308 :               ctx = ctx->outer_context;
   16877              :             }
   16878          308 :           while (ctx);
   16879              :         }
   16880         1283 :       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   16881              :         {
   16882           23 :           gcc_assert (seen_error ());
   16883           23 :           continue;
   16884              :         }
   16885         1260 :       gimplify_expr (&TREE_OPERAND (t, 1), pre_p, NULL, is_gimple_val,
   16886              :                      fb_rvalue);
   16887         1260 :       gimplify_and_add (t, &pre_body);
   16888         1260 :       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   16889         1260 :       gcc_assert (TREE_OPERAND (t, 0) == decl);
   16890         1260 :       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   16891              :         {
   16892           28 :           gcc_assert (seen_error ());
   16893           28 :           continue;
   16894              :         }
   16895         1232 :       gimplify_expr (&TREE_OPERAND (t, 1), pre_p, NULL, is_gimple_val,
   16896              :                      fb_rvalue);
   16897         1232 :       tree l1 = create_artificial_label (UNKNOWN_LOCATION);
   16898         1232 :       tree l2 = create_artificial_label (UNKNOWN_LOCATION);
   16899         1232 :       tree l3 = create_artificial_label (UNKNOWN_LOCATION);
   16900         1232 :       gimplify_seq_add_stmt (&pre_body, gimple_build_goto (l2));
   16901         1232 :       gimplify_seq_add_stmt (&pre_body, gimple_build_label (l1));
   16902         1232 :       gimple_seq this_post_body = NULL;
   16903         1232 :       t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   16904         1232 :       if (TREE_CODE (t) == MODIFY_EXPR)
   16905              :         {
   16906          975 :           t = TREE_OPERAND (t, 1);
   16907          975 :           if (TREE_CODE (t) == PLUS_EXPR
   16908          975 :               && TREE_OPERAND (t, 1) == decl)
   16909              :             {
   16910            0 :               TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
   16911            0 :               TREE_OPERAND (t, 0) = decl;
   16912              :             }
   16913          975 :           gimplify_expr (&TREE_OPERAND (t, 1), pre_p, NULL, is_gimple_val,
   16914              :                          fb_rvalue);
   16915              :         }
   16916         1232 :       gimplify_and_add (TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i),
   16917              :                         &this_post_body);
   16918         1232 :       gimplify_seq_add_stmt (&this_post_body, gimple_build_label (l2));
   16919         1232 :       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   16920         1232 :       gcond *cond = NULL;
   16921         1232 :       tree d = decl;
   16922         1232 :       gimplify_expr (&d, &this_post_body, NULL, is_gimple_val, fb_rvalue);
   16923         1232 :       if (iters && tree_fits_uhwi_p (iters))
   16924              :         {
   16925          299 :           unsigned HOST_WIDE_INT niters = tree_to_uhwi (iters);
   16926          299 :           if ((unsigned HOST_WIDE_INT) (int) niters == niters
   16927          299 :               && (int) niters > 0)
   16928              :             {
   16929          299 :               t = build2 (TREE_CODE (t), boolean_type_node, d,
   16930          299 :                           TREE_OPERAND (t, 1));
   16931          299 :               t = build3 (ANNOTATE_EXPR, TREE_TYPE (t), t,
   16932              :                           build_int_cst (integer_type_node,
   16933              :                                          annot_expr_unroll_kind),
   16934          299 :                           build_int_cst (integer_type_node, niters));
   16935          299 :               gimplify_expr (&t, &this_post_body, NULL, is_gimple_val,
   16936              :                              fb_rvalue);
   16937          299 :               cond = gimple_build_cond (NE_EXPR, t, boolean_false_node,
   16938              :                                         l1, l3);
   16939              :             }
   16940              :         }
   16941          299 :       if (cond == NULL)
   16942          933 :         cond = gimple_build_cond (TREE_CODE (t), d, TREE_OPERAND (t, 1),
   16943              :                                   l1, l3);
   16944         1232 :       gimplify_seq_add_stmt (&this_post_body, cond);
   16945         1232 :       gimplify_seq_add_stmt (&this_post_body, gimple_build_label (l3));
   16946         1232 :       gimplify_seq_add_seq (&this_post_body, post_body);
   16947         1232 :       post_body = this_post_body;
   16948              :     }
   16949         2264 :   gimplify_seq_add_seq (pre_p, pre_body);
   16950         2264 :   gimplify_and_add (OMP_FOR_BODY (for_stmt), pre_p);
   16951         2264 :   gimplify_seq_add_seq (pre_p, post_body);
   16952              : 
   16953         2264 :   *expr_p = NULL_TREE;
   16954         2264 :   return GS_ALL_DONE;
   16955              : }
   16956              : 
   16957              : /* Gimplify the gross structure of an OMP_FOR statement.  */
   16958              : 
   16959              : static enum gimplify_status
   16960        58086 : gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
   16961              : {
   16962        58086 :   tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
   16963        58086 :   enum gimplify_status ret = GS_ALL_DONE;
   16964        58086 :   enum gimplify_status tret;
   16965        58086 :   gomp_for *gfor;
   16966        58086 :   gimple_seq for_body, for_pre_body;
   16967        58086 :   int i;
   16968        58086 :   bitmap has_decl_expr = NULL;
   16969        58086 :   enum omp_region_type ort = ORT_WORKSHARE;
   16970        58086 :   bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
   16971              : 
   16972        58086 :   orig_for_stmt = for_stmt = *expr_p;
   16973              : 
   16974        58086 :   bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
   16975        58086 :                  != NULL_TREE);
   16976        58157 :   while (OMP_FOR_INIT (for_stmt) == NULL_TREE)
   16977              :     {
   16978        17738 :       tree *data[4] = { NULL, NULL, NULL, NULL };
   16979        17738 :       gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
   16980        17738 :       inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
   16981              :                                   find_combined_omp_for, data, NULL);
   16982        17738 :       if (inner_for_stmt == NULL_TREE)
   16983              :         {
   16984           36 :           gcc_assert (seen_error ());
   16985           36 :           *expr_p = NULL_TREE;
   16986         3741 :           return GS_ERROR;
   16987              :         }
   16988        17702 :       gcc_assert (inner_for_stmt == *data[3]);
   16989        17702 :       omp_maybe_apply_loop_xforms (data[3],
   16990        17702 :                                    data[2]
   16991         4279 :                                    ? OMP_FOR_CLAUSES (*data[2])
   16992        13423 :                                    : TREE_CODE (for_stmt) == OMP_FOR
   16993        13423 :                                    ? OMP_FOR_CLAUSES (for_stmt)
   16994              :                                    : NULL_TREE);
   16995        17702 :       if (inner_for_stmt != *data[3])
   16996           71 :         continue;
   16997        17631 :       if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
   16998              :         {
   16999            2 :           append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
   17000              :                                           &OMP_FOR_PRE_BODY (for_stmt));
   17001            2 :           OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
   17002              :         }
   17003        17631 :       if (OMP_FOR_PRE_BODY (inner_for_stmt))
   17004              :         {
   17005         7193 :           append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
   17006              :                                           &OMP_FOR_PRE_BODY (for_stmt));
   17007         7193 :           OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
   17008              :         }
   17009              : 
   17010        17631 :       if (data[0])
   17011              :         {
   17012              :           /* We have some statements or variable declarations in between
   17013              :              the composite construct directives.  Move them around the
   17014              :              inner_for_stmt.  */
   17015         3705 :           data[0] = expr_p;
   17016        14820 :           for (i = 0; i < 3; i++)
   17017        11115 :             if (data[i])
   17018              :               {
   17019         7028 :                 tree t = *data[i];
   17020         7028 :                 if (i < 2 && data[i + 1] == &OMP_BODY (t))
   17021         1005 :                   data[i + 1] = data[i];
   17022         7028 :                 *data[i] = OMP_BODY (t);
   17023         7028 :                 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
   17024              :                                     NULL_TREE, make_node (BLOCK));
   17025         7028 :                 OMP_BODY (t) = body;
   17026         7028 :                 append_to_statement_list_force (inner_for_stmt,
   17027              :                                                 &BIND_EXPR_BODY (body));
   17028         7028 :                 *data[3] = t;
   17029         7028 :                 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
   17030         7028 :                 gcc_assert (*data[3] == inner_for_stmt);
   17031              :               }
   17032              :           return GS_OK;
   17033              :         }
   17034              : 
   17035        36734 :       for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
   17036        22808 :         if (!loop_p
   17037        21927 :             && OMP_FOR_ORIG_DECLS (inner_for_stmt)
   17038        11098 :             && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   17039              :                                         i)) == TREE_LIST
   17040        22876 :             && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   17041              :                                            i)))
   17042              :           {
   17043           40 :             tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
   17044              :             /* Class iterators aren't allowed on OMP_SIMD, so the only
   17045              :                case we need to solve is distribute parallel for.  They are
   17046              :                allowed on the loop construct, but that is already handled
   17047              :                in gimplify_omp_loop.  */
   17048           40 :             gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
   17049              :                         && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
   17050              :                         && data[1]);
   17051           40 :             tree orig_decl = TREE_PURPOSE (orig);
   17052           40 :             tree last = TREE_VALUE (orig);
   17053           40 :             tree *pc;
   17054           40 :             for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
   17055           74 :                  *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
   17056           42 :               if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
   17057           35 :                    || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
   17058           43 :                   && OMP_CLAUSE_DECL (*pc) == orig_decl)
   17059              :                 break;
   17060           40 :             if (*pc == NULL_TREE)
   17061              :               {
   17062           32 :                 tree *spc;
   17063           32 :                 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
   17064           98 :                      *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
   17065           67 :                   if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
   17066           67 :                       && OMP_CLAUSE_DECL (*spc) == orig_decl)
   17067              :                     break;
   17068           32 :                 if (*spc)
   17069              :                   {
   17070            1 :                     tree c = *spc;
   17071            1 :                     *spc = OMP_CLAUSE_CHAIN (c);
   17072            1 :                     OMP_CLAUSE_CHAIN (c) = NULL_TREE;
   17073            1 :                     *pc = c;
   17074              :                   }
   17075              :               }
   17076           40 :             if (*pc == NULL_TREE)
   17077              :               ;
   17078            9 :             else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
   17079              :               {
   17080              :                 /* private clause will appear only on inner_for_stmt.
   17081              :                    Change it into firstprivate, and add private clause
   17082              :                    on for_stmt.  */
   17083            8 :                 tree c = copy_node (*pc);
   17084            8 :                 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
   17085            8 :                 OMP_FOR_CLAUSES (for_stmt) = c;
   17086            8 :                 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
   17087            8 :                 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
   17088              :               }
   17089              :             else
   17090              :               {
   17091              :                 /* lastprivate clause will appear on both inner_for_stmt
   17092              :                    and for_stmt.  Add firstprivate clause to
   17093              :                    inner_for_stmt.  */
   17094            1 :                 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
   17095              :                                            OMP_CLAUSE_FIRSTPRIVATE);
   17096            1 :                 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
   17097            1 :                 OMP_CLAUSE_CHAIN (c) = *pc;
   17098            1 :                 *pc = c;
   17099            1 :                 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
   17100              :               }
   17101           40 :             tree c = build_omp_clause (UNKNOWN_LOCATION,
   17102              :                                        OMP_CLAUSE_FIRSTPRIVATE);
   17103           40 :             OMP_CLAUSE_DECL (c) = last;
   17104           40 :             OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   17105           40 :             OMP_PARALLEL_CLAUSES (*data[1]) = c;
   17106           40 :             c = build_omp_clause (UNKNOWN_LOCATION,
   17107           40 :                                   *pc ? OMP_CLAUSE_SHARED
   17108              :                                       : OMP_CLAUSE_FIRSTPRIVATE);
   17109           40 :             OMP_CLAUSE_DECL (c) = orig_decl;
   17110           40 :             OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   17111           40 :             OMP_PARALLEL_CLAUSES (*data[1]) = c;
   17112              :           }
   17113              :       /* Similarly, take care of C++ range for temporaries, those should
   17114              :          be firstprivate on OMP_PARALLEL if any.  */
   17115        13926 :       if (data[1])
   17116        17503 :         for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
   17117        11108 :           if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
   17118         5733 :               && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   17119              :                                           i)) == TREE_LIST
   17120        11184 :               && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   17121              :                                            i)))
   17122              :             {
   17123           49 :               tree orig
   17124           49 :                 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
   17125           49 :               tree v = TREE_CHAIN (orig);
   17126           49 :               tree c = build_omp_clause (UNKNOWN_LOCATION,
   17127              :                                          OMP_CLAUSE_FIRSTPRIVATE);
   17128              :               /* First add firstprivate clause for the __for_end artificial
   17129              :                  decl.  */
   17130           49 :               OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
   17131           49 :               if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
   17132              :                   == REFERENCE_TYPE)
   17133            0 :                 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
   17134           49 :               OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   17135           49 :               OMP_PARALLEL_CLAUSES (*data[1]) = c;
   17136           49 :               if (TREE_VEC_ELT (v, 0))
   17137              :                 {
   17138              :                   /* And now the same for __for_range artificial decl if it
   17139              :                      exists.  */
   17140           49 :                   c = build_omp_clause (UNKNOWN_LOCATION,
   17141              :                                         OMP_CLAUSE_FIRSTPRIVATE);
   17142           49 :                   OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
   17143           49 :                   if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
   17144              :                       == REFERENCE_TYPE)
   17145           49 :                     OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
   17146           49 :                   OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   17147           49 :                   OMP_PARALLEL_CLAUSES (*data[1]) = c;
   17148              :                 }
   17149              :             }
   17150        13926 :       break;
   17151              :     }
   17152        54345 :   if (OMP_FOR_INIT (for_stmt) != NULL_TREE)
   17153              :     {
   17154        40419 :       omp_maybe_apply_loop_xforms (expr_p, NULL_TREE);
   17155        40419 :       if (*expr_p != for_stmt)
   17156              :         return GS_OK;
   17157              :     }
   17158              : 
   17159        53463 :   switch (TREE_CODE (for_stmt))
   17160              :     {
   17161        18189 :     case OMP_FOR:
   17162        30409 :       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
   17163              :         {
   17164          458 :           if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   17165              :                                OMP_CLAUSE_SCHEDULE))
   17166           47 :             error_at (EXPR_LOCATION (for_stmt),
   17167              :                       "%qs clause may not appear on non-rectangular %qs",
   17168           27 :                       "schedule", lang_GNU_Fortran () ? "do" : "for");
   17169          458 :           if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
   17170           34 :             error_at (EXPR_LOCATION (for_stmt),
   17171              :                       "%qs clause may not appear on non-rectangular %qs",
   17172           18 :                       "ordered", lang_GNU_Fortran () ? "do" : "for");
   17173              :         }
   17174              :       break;
   17175         8219 :     case OMP_DISTRIBUTE:
   17176         9130 :       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
   17177         8219 :           && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   17178              :                               OMP_CLAUSE_DIST_SCHEDULE))
   17179           29 :         error_at (EXPR_LOCATION (for_stmt),
   17180              :                   "%qs clause may not appear on non-rectangular %qs",
   17181              :                   "dist_schedule", "distribute");
   17182              :       break;
   17183              :     case OACC_LOOP:
   17184              :       ort = ORT_ACC;
   17185              :       break;
   17186         1586 :     case OMP_TASKLOOP:
   17187         2523 :       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
   17188              :         {
   17189           36 :           if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   17190              :                                OMP_CLAUSE_GRAINSIZE))
   17191           11 :             error_at (EXPR_LOCATION (for_stmt),
   17192              :                       "%qs clause may not appear on non-rectangular %qs",
   17193              :                       "grainsize", "taskloop");
   17194           36 :           if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   17195              :                                OMP_CLAUSE_NUM_TASKS))
   17196            6 :             error_at (EXPR_LOCATION (for_stmt),
   17197              :                       "%qs clause may not appear on non-rectangular %qs",
   17198              :                       "num_tasks", "taskloop");
   17199              :         }
   17200         1586 :       if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
   17201              :         ort = ORT_UNTIED_TASKLOOP;
   17202              :       else
   17203              :         ort = ORT_TASKLOOP;
   17204              :       break;
   17205        10653 :     case OMP_SIMD:
   17206        10653 :       ort = ORT_SIMD;
   17207        10653 :       break;
   17208         2264 :     case OMP_TILE:
   17209         2264 :     case OMP_UNROLL:
   17210         2264 :       gcc_assert (inner_for_stmt == NULL_TREE);
   17211         2264 :       return gimplify_omp_loop_xform (expr_p, pre_p);
   17212            0 :     default:
   17213            0 :       gcc_unreachable ();
   17214              :     }
   17215              : 
   17216              :   /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
   17217              :      clause for the IV.  */
   17218        10700 :   if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
   17219              :     {
   17220         7825 :       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
   17221         7825 :       gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   17222         7825 :       decl = TREE_OPERAND (t, 0);
   17223        18635 :       for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   17224        11924 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   17225        11924 :             && OMP_CLAUSE_DECL (c) == decl)
   17226              :           {
   17227         1114 :             OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
   17228         1114 :             break;
   17229              :           }
   17230              :     }
   17231              : 
   17232        51199 :   if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
   17233        51523 :     gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
   17234         1910 :                                loop_p && TREE_CODE (for_stmt) != OMP_SIMD
   17235              :                                ? OMP_LOOP : TREE_CODE (for_stmt));
   17236              : 
   17237        51199 :   if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
   17238         8219 :     gimplify_omp_ctxp->distribute = true;
   17239              : 
   17240              :   /* Handle OMP_FOR_INIT.  */
   17241        51199 :   for_pre_body = NULL;
   17242        51199 :   if ((ort == ORT_SIMD
   17243        40546 :        || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
   17244        61939 :       && OMP_FOR_PRE_BODY (for_stmt))
   17245              :     {
   17246         6784 :       has_decl_expr = BITMAP_ALLOC (NULL);
   17247         6784 :       if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
   17248         6784 :           && VAR_P (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt))))
   17249              :         {
   17250           18 :           t = OMP_FOR_PRE_BODY (for_stmt);
   17251           18 :           bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
   17252              :         }
   17253         6766 :       else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
   17254              :         {
   17255         6764 :           tree_stmt_iterator si;
   17256        11234 :           for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
   17257         4470 :                tsi_next (&si))
   17258              :             {
   17259         4470 :               t = tsi_stmt (si);
   17260         4470 :               if (TREE_CODE (t) == DECL_EXPR
   17261         4470 :                   && VAR_P (DECL_EXPR_DECL (t)))
   17262         4397 :                 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
   17263              :             }
   17264              :         }
   17265              :     }
   17266        51199 :   if (OMP_FOR_PRE_BODY (for_stmt))
   17267              :     {
   17268        20979 :       if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
   17269        20254 :         gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
   17270              :       else
   17271              :         {
   17272          725 :           struct gimplify_omp_ctx ctx;
   17273          725 :           memset (&ctx, 0, sizeof (ctx));
   17274          725 :           ctx.region_type = ORT_NONE;
   17275          725 :           gimplify_omp_ctxp = &ctx;
   17276          725 :           gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
   17277          725 :           gimplify_omp_ctxp = NULL;
   17278              :         }
   17279              :     }
   17280        51199 :   OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
   17281              : 
   17282        51199 :   if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
   17283        13926 :     for_stmt = inner_for_stmt;
   17284              : 
   17285              :   /* For taskloop, need to gimplify the start, end and step before the
   17286              :      taskloop, outside of the taskloop omp context.  */
   17287        51199 :   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
   17288              :     {
   17289         3458 :       for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   17290              :         {
   17291         1872 :           t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   17292         1872 :           gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
   17293         1872 :                                    ? pre_p : &for_pre_body);
   17294         1872 :               tree type = TREE_TYPE (TREE_OPERAND (t, 0));
   17295         1872 :           if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   17296              :             {
   17297           34 :               tree v = TREE_OPERAND (t, 1);
   17298           34 :               gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
   17299              :                                           for_pre_p, orig_for_stmt);
   17300           34 :               gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
   17301              :                                           for_pre_p, orig_for_stmt);
   17302              :             }
   17303              :           else
   17304         1838 :             gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
   17305              :                                         orig_for_stmt);
   17306              : 
   17307              :           /* Handle OMP_FOR_COND.  */
   17308         1872 :           t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   17309         1872 :           if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   17310              :             {
   17311           31 :               tree v = TREE_OPERAND (t, 1);
   17312           31 :               gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
   17313              :                                           for_pre_p, orig_for_stmt);
   17314           31 :               gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
   17315              :                                           for_pre_p, orig_for_stmt);
   17316              :             }
   17317              :           else
   17318         1841 :             gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
   17319              :                                         orig_for_stmt);
   17320              : 
   17321              :           /* Handle OMP_FOR_INCR.  */
   17322         1872 :           t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   17323         1872 :           if (TREE_CODE (t) == MODIFY_EXPR)
   17324              :             {
   17325          590 :               decl = TREE_OPERAND (t, 0);
   17326          590 :               t = TREE_OPERAND (t, 1);
   17327          590 :               tree *tp = &TREE_OPERAND (t, 1);
   17328          590 :               if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
   17329           22 :                 tp = &TREE_OPERAND (t, 0);
   17330              : 
   17331          590 :               gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
   17332              :                                           orig_for_stmt);
   17333              :             }
   17334              :         }
   17335              : 
   17336         1586 :       gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
   17337              :                                  OMP_TASKLOOP);
   17338              :     }
   17339              : 
   17340        51199 :   if (orig_for_stmt != for_stmt)
   17341        13926 :     gimplify_omp_ctxp->combined_loop = true;
   17342              : 
   17343        51199 :   for_body = NULL;
   17344        51199 :   gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
   17345              :               == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
   17346        51199 :   gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
   17347              :               == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
   17348              : 
   17349        51199 :   tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
   17350        51199 :   bool is_doacross = false;
   17351        51199 :   if (c && walk_tree_without_duplicates (&OMP_FOR_BODY (for_stmt),
   17352              :                                          find_standalone_omp_ordered, NULL))
   17353              :     {
   17354          531 :       OMP_CLAUSE_ORDERED_DOACROSS (c) = 1;
   17355          531 :       is_doacross = true;
   17356          531 :       int len = TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt));
   17357          531 :       gimplify_omp_ctxp->loop_iter_var.create (len * 2);
   17358         2200 :       for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
   17359         1669 :         if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
   17360              :           {
   17361           10 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   17362              :                       "%<linear%> clause may not be specified together "
   17363              :                       "with %<ordered%> clause if stand-alone %<ordered%> "
   17364              :                       "construct is nested in it");
   17365           10 :             *pc = OMP_CLAUSE_CHAIN (*pc);
   17366              :           }
   17367              :         else
   17368         1659 :           pc = &OMP_CLAUSE_CHAIN (*pc);
   17369              :     }
   17370        51199 :   int collapse = 1, tile = 0;
   17371        51199 :   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
   17372        51199 :   if (c)
   17373        13727 :     collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
   17374        51199 :   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
   17375        51199 :   if (c)
   17376          384 :     tile = list_length (OMP_CLAUSE_TILE_LIST (c));
   17377        51199 :   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
   17378        51199 :   hash_set<tree> *allocate_uids = NULL;
   17379        51199 :   if (c)
   17380              :     {
   17381          275 :       allocate_uids = new hash_set<tree>;
   17382         1682 :       for (; c; c = OMP_CLAUSE_CHAIN (c))
   17383         1132 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
   17384          478 :           allocate_uids->add (OMP_CLAUSE_DECL (c));
   17385              :     }
   17386       124144 :   for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   17387              :     {
   17388        72945 :       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   17389        72945 :       gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   17390        72945 :       decl = TREE_OPERAND (t, 0);
   17391        72945 :       gcc_assert (DECL_P (decl));
   17392        72945 :       gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
   17393              :                   || POINTER_TYPE_P (TREE_TYPE (decl)));
   17394        72945 :       if (is_doacross)
   17395              :         {
   17396         1654 :           if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
   17397              :             {
   17398          960 :               tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   17399          960 :               if (TREE_CODE (orig_decl) == TREE_LIST)
   17400              :                 {
   17401           15 :                   orig_decl = TREE_PURPOSE (orig_decl);
   17402           15 :                   if (!orig_decl)
   17403            0 :                     orig_decl = decl;
   17404              :                 }
   17405          960 :               gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
   17406              :             }
   17407              :           else
   17408          694 :             gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
   17409         1654 :           gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
   17410              :         }
   17411              : 
   17412        72945 :       if (for_stmt == orig_for_stmt)
   17413              :         {
   17414        50137 :           tree orig_decl = decl;
   17415        50137 :           if (OMP_FOR_ORIG_DECLS (for_stmt))
   17416              :             {
   17417        23916 :               tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   17418        23916 :               if (TREE_CODE (orig_decl) == TREE_LIST)
   17419              :                 {
   17420              :                   orig_decl = TREE_PURPOSE (orig_decl);
   17421              :                   if (!orig_decl)
   17422              :                     orig_decl = decl;
   17423              :                 }
   17424              :             }
   17425        50137 :           if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
   17426           36 :             error_at (EXPR_LOCATION (for_stmt),
   17427              :                       "threadprivate iteration variable %qD", orig_decl);
   17428              :         }
   17429              : 
   17430              :       /* Make sure the iteration variable is private.  */
   17431        72945 :       tree c = NULL_TREE;
   17432        72945 :       tree c2 = NULL_TREE;
   17433        72945 :       if (orig_for_stmt != for_stmt)
   17434              :         {
   17435              :           /* Preserve this information until we gimplify the inner simd.  */
   17436        22808 :           if (has_decl_expr
   17437        22808 :               && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
   17438         3413 :             TREE_PRIVATE (t) = 1;
   17439              :         }
   17440        50137 :       else if (ort == ORT_SIMD)
   17441              :         {
   17442        15726 :           splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
   17443              :                                                  (splay_tree_key) decl);
   17444        15726 :           omp_is_private (gimplify_omp_ctxp, decl,
   17445        15726 :                           1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
   17446              :                                != 1));
   17447        15726 :           if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
   17448              :             {
   17449         2518 :               omp_notice_variable (gimplify_omp_ctxp, decl, true);
   17450         2518 :               if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
   17451            0 :                 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   17452              :                                                 OMP_CLAUSE_LASTPRIVATE);
   17453            0 :                      c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
   17454              :                                                OMP_CLAUSE_LASTPRIVATE))
   17455            0 :                   if (OMP_CLAUSE_DECL (c3) == decl)
   17456              :                     {
   17457            0 :                       warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp,
   17458              :                                   "conditional %<lastprivate%> on loop "
   17459              :                                   "iterator %qD ignored", decl);
   17460            0 :                       OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
   17461            0 :                       n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
   17462              :                     }
   17463              :             }
   17464        13208 :           else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
   17465              :             {
   17466         5637 :               c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
   17467         5637 :               OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
   17468         5637 :               unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
   17469         5637 :               if ((has_decl_expr
   17470         1309 :                    && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
   17471         6321 :                   || TREE_PRIVATE (t))
   17472              :                 {
   17473         2281 :                   OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
   17474         2281 :                   flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   17475              :                 }
   17476         5637 :               struct gimplify_omp_ctx *outer
   17477         5637 :                 = gimplify_omp_ctxp->outer_context;
   17478         5637 :               if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   17479              :                 {
   17480         2433 :                   if (outer->region_type == ORT_WORKSHARE
   17481         2193 :                       && outer->combined_loop)
   17482              :                     {
   17483         2142 :                       n = splay_tree_lookup (outer->variables,
   17484              :                                              (splay_tree_key)decl);
   17485         2142 :                       if (n != NULL && (n->value & GOVD_LOCAL) != 0)
   17486              :                         {
   17487            0 :                           OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
   17488            0 :                           flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   17489              :                         }
   17490              :                       else
   17491              :                         {
   17492         2142 :                           struct gimplify_omp_ctx *octx = outer->outer_context;
   17493         2142 :                           if (octx
   17494         1714 :                               && octx->region_type == ORT_COMBINED_PARALLEL
   17495         1476 :                               && octx->outer_context
   17496         1209 :                               && (octx->outer_context->region_type
   17497              :                                   == ORT_WORKSHARE)
   17498         1079 :                               && octx->outer_context->combined_loop)
   17499              :                             {
   17500         1079 :                               octx = octx->outer_context;
   17501         1079 :                               n = splay_tree_lookup (octx->variables,
   17502              :                                                      (splay_tree_key)decl);
   17503         1079 :                               if (n != NULL && (n->value & GOVD_LOCAL) != 0)
   17504              :                                 {
   17505            0 :                                   OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
   17506            0 :                                   flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   17507              :                                 }
   17508              :                             }
   17509              :                         }
   17510              :                     }
   17511              :                 }
   17512              : 
   17513         5637 :               OMP_CLAUSE_DECL (c) = decl;
   17514         5637 :               OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
   17515         5637 :               OMP_FOR_CLAUSES (for_stmt) = c;
   17516         5637 :               omp_add_variable (gimplify_omp_ctxp, decl, flags);
   17517         5637 :               if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   17518         2433 :                 omp_lastprivate_for_combined_outer_constructs (outer, decl,
   17519              :                                                                true);
   17520              :             }
   17521              :           else
   17522              :             {
   17523         7571 :               bool lastprivate
   17524              :                 = (!has_decl_expr
   17525         7571 :                    || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
   17526         7571 :               if (TREE_PRIVATE (t))
   17527         1787 :                 lastprivate = false;
   17528         7571 :               if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
   17529              :                 {
   17530          509 :                   tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   17531          509 :                   if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
   17532              :                     lastprivate = false;
   17533              :                 }
   17534              : 
   17535         7571 :               struct gimplify_omp_ctx *outer
   17536         7571 :                 = gimplify_omp_ctxp->outer_context;
   17537         7571 :               if (outer && lastprivate)
   17538         4887 :                 omp_lastprivate_for_combined_outer_constructs (outer, decl,
   17539              :                                                                true);
   17540              : 
   17541         9577 :               c = build_omp_clause (input_location,
   17542              :                                     lastprivate ? OMP_CLAUSE_LASTPRIVATE
   17543              :                                                 : OMP_CLAUSE_PRIVATE);
   17544         7571 :               OMP_CLAUSE_DECL (c) = decl;
   17545         7571 :               OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
   17546         7571 :               OMP_FOR_CLAUSES (for_stmt) = c;
   17547         7571 :               omp_add_variable (gimplify_omp_ctxp, decl,
   17548              :                                 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
   17549              :                                 | GOVD_EXPLICIT | GOVD_SEEN);
   17550         7571 :               c = NULL_TREE;
   17551              :             }
   17552              :         }
   17553        34411 :       else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
   17554              :         {
   17555         8735 :           omp_notice_variable (gimplify_omp_ctxp, decl, true);
   17556         8735 :           splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
   17557              :                                                  (splay_tree_key) decl);
   17558         8735 :           if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
   17559           80 :             for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   17560              :                                             OMP_CLAUSE_LASTPRIVATE);
   17561           80 :                  c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
   17562              :                                            OMP_CLAUSE_LASTPRIVATE))
   17563           40 :               if (OMP_CLAUSE_DECL (c3) == decl)
   17564              :                 {
   17565           40 :                   warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp,
   17566              :                               "conditional %<lastprivate%> on loop "
   17567              :                               "iterator %qD ignored", decl);
   17568           40 :                   OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
   17569           40 :                   n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
   17570              :                 }
   17571              :         }
   17572              :       else
   17573        25676 :         omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
   17574              : 
   17575              :       /* If DECL is not a gimple register, create a temporary variable to act
   17576              :          as an iteration counter.  This is valid, since DECL cannot be
   17577              :          modified in the body of the loop.  Similarly for any iteration vars
   17578              :          in simd with collapse > 1 where the iterator vars must be
   17579              :          lastprivate.  And similarly for vars mentioned in allocate clauses.  */
   17580        72945 :       if (orig_for_stmt != for_stmt)
   17581        22808 :         var = decl;
   17582        50137 :       else if (!is_gimple_reg (decl)
   17583        46870 :                || (ort == ORT_SIMD
   17584        14125 :                    && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
   17585        89937 :                || (allocate_uids && allocate_uids->contains (decl)))
   17586              :         {
   17587        10369 :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   17588              :           /* Make sure omp_add_variable is not called on it prematurely.
   17589              :              We call it ourselves a few lines later.  */
   17590        10369 :           gimplify_omp_ctxp = NULL;
   17591        10369 :           var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
   17592        10369 :           gimplify_omp_ctxp = ctx;
   17593        10369 :           TREE_OPERAND (t, 0) = var;
   17594              : 
   17595        10369 :           gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
   17596              : 
   17597        10369 :           if (ort == ORT_SIMD
   17598        10369 :               && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
   17599              :             {
   17600          770 :               c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
   17601          770 :               OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
   17602          770 :               OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
   17603          770 :               OMP_CLAUSE_DECL (c2) = var;
   17604          770 :               OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
   17605          770 :               OMP_FOR_CLAUSES (for_stmt) = c2;
   17606          770 :               omp_add_variable (gimplify_omp_ctxp, var,
   17607              :                                 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
   17608          770 :               if (c == NULL_TREE)
   17609              :                 {
   17610          518 :                   c = c2;
   17611          518 :                   c2 = NULL_TREE;
   17612              :                 }
   17613              :             }
   17614              :           else
   17615         9599 :             omp_add_variable (gimplify_omp_ctxp, var,
   17616              :                               GOVD_PRIVATE | GOVD_SEEN);
   17617              :         }
   17618              :       else
   17619              :         var = decl;
   17620              : 
   17621        72945 :       gimplify_omp_ctxp->in_for_exprs = true;
   17622        72945 :       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   17623              :         {
   17624          719 :           tree lb = TREE_OPERAND (t, 1);
   17625          719 :           tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
   17626              :                                 is_gimple_val, fb_rvalue, false);
   17627          719 :           ret = MIN (ret, tret);
   17628          719 :           tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
   17629              :                                 is_gimple_val, fb_rvalue, false);
   17630              :         }
   17631              :       else
   17632        72226 :         tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
   17633              :                               is_gimple_val, fb_rvalue, false);
   17634        72945 :       gimplify_omp_ctxp->in_for_exprs = false;
   17635        72945 :       ret = MIN (ret, tret);
   17636        72945 :       if (ret == GS_ERROR)
   17637              :         return ret;
   17638              : 
   17639              :       /* Handle OMP_FOR_COND.  */
   17640        72945 :       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   17641        72945 :       gcc_assert (COMPARISON_CLASS_P (t));
   17642        72945 :       gcc_assert (TREE_OPERAND (t, 0) == decl);
   17643              : 
   17644        72945 :       gimplify_omp_ctxp->in_for_exprs = true;
   17645        72945 :       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   17646              :         {
   17647          599 :           tree ub = TREE_OPERAND (t, 1);
   17648          599 :           tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
   17649              :                                 is_gimple_val, fb_rvalue, false);
   17650          599 :           ret = MIN (ret, tret);
   17651          599 :           tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
   17652              :                                 is_gimple_val, fb_rvalue, false);
   17653              :         }
   17654              :       else
   17655        72346 :         tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
   17656              :                               is_gimple_val, fb_rvalue, false);
   17657        72945 :       gimplify_omp_ctxp->in_for_exprs = false;
   17658        72945 :       ret = MIN (ret, tret);
   17659              : 
   17660              :       /* Handle OMP_FOR_INCR.  */
   17661        72945 :       t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   17662        72945 :       switch (TREE_CODE (t))
   17663              :         {
   17664        35676 :         case PREINCREMENT_EXPR:
   17665        35676 :         case POSTINCREMENT_EXPR:
   17666        35676 :           {
   17667        35676 :             tree decl = TREE_OPERAND (t, 0);
   17668              :             /* c_omp_for_incr_canonicalize_ptr() should have been
   17669              :                called to massage things appropriately.  */
   17670        35676 :             gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
   17671              : 
   17672        35676 :             if (orig_for_stmt != for_stmt)
   17673              :               break;
   17674        25291 :             t = build_int_cst (TREE_TYPE (decl), 1);
   17675        25291 :             if (c)
   17676         4470 :               OMP_CLAUSE_LINEAR_STEP (c) = t;
   17677        25291 :             t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
   17678        25291 :             t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
   17679        25291 :             TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
   17680        25291 :             break;
   17681              :           }
   17682              : 
   17683         3830 :         case PREDECREMENT_EXPR:
   17684         3830 :         case POSTDECREMENT_EXPR:
   17685              :           /* c_omp_for_incr_canonicalize_ptr() should have been
   17686              :              called to massage things appropriately.  */
   17687         3830 :           gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
   17688         3830 :           if (orig_for_stmt != for_stmt)
   17689              :             break;
   17690         1992 :           t = build_int_cst (TREE_TYPE (decl), -1);
   17691         1992 :           if (c)
   17692          112 :             OMP_CLAUSE_LINEAR_STEP (c) = t;
   17693         1992 :           t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
   17694         1992 :           t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
   17695         1992 :           TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
   17696         1992 :           break;
   17697              : 
   17698        33439 :         case MODIFY_EXPR:
   17699        33439 :           gcc_assert (TREE_OPERAND (t, 0) == decl);
   17700        33439 :           TREE_OPERAND (t, 0) = var;
   17701              : 
   17702        33439 :           t = TREE_OPERAND (t, 1);
   17703        33439 :           switch (TREE_CODE (t))
   17704              :             {
   17705        26507 :             case PLUS_EXPR:
   17706        26507 :               if (TREE_OPERAND (t, 1) == decl)
   17707              :                 {
   17708          215 :                   TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
   17709          215 :                   TREE_OPERAND (t, 0) = var;
   17710          215 :                   break;
   17711              :                 }
   17712              : 
   17713              :               /* Fallthru.  */
   17714        33224 :             case MINUS_EXPR:
   17715        33224 :             case POINTER_PLUS_EXPR:
   17716        33224 :               gcc_assert (TREE_OPERAND (t, 0) == decl);
   17717        33224 :               TREE_OPERAND (t, 0) = var;
   17718        33224 :               break;
   17719            0 :             default:
   17720            0 :               gcc_unreachable ();
   17721              :             }
   17722              : 
   17723        33439 :           gimplify_omp_ctxp->in_for_exprs = true;
   17724        33439 :           tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
   17725              :                                 is_gimple_val, fb_rvalue, false);
   17726        33439 :           ret = MIN (ret, tret);
   17727        33439 :           if (c)
   17728              :             {
   17729         1573 :               tree step = TREE_OPERAND (t, 1);
   17730         1573 :               tree stept = TREE_TYPE (decl);
   17731         1573 :               if (POINTER_TYPE_P (stept))
   17732          280 :                 stept = sizetype;
   17733         1573 :               step = fold_convert (stept, step);
   17734         1573 :               if (TREE_CODE (t) == MINUS_EXPR)
   17735          295 :                 step = fold_build1 (NEGATE_EXPR, stept, step);
   17736         1573 :               OMP_CLAUSE_LINEAR_STEP (c) = step;
   17737         1573 :               if (step != TREE_OPERAND (t, 1))
   17738              :                 {
   17739          295 :                   tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
   17740              :                                         &for_pre_body, NULL,
   17741              :                                         is_gimple_val, fb_rvalue, false);
   17742          295 :                   ret = MIN (ret, tret);
   17743              :                 }
   17744              :             }
   17745        33439 :           gimplify_omp_ctxp->in_for_exprs = false;
   17746        33439 :           break;
   17747              : 
   17748            0 :         default:
   17749            0 :           gcc_unreachable ();
   17750              :         }
   17751              : 
   17752        72945 :       if (c2)
   17753              :         {
   17754          252 :           gcc_assert (c);
   17755          252 :           OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
   17756              :         }
   17757              : 
   17758        72945 :       if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
   17759              :         {
   17760        86698 :           for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
   17761        65136 :             if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   17762        16218 :                   && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
   17763        56127 :                  || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   17764         2159 :                      && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
   17765         1373 :                      && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
   17766        75496 :                 && OMP_CLAUSE_DECL (c) == decl)
   17767              :               {
   17768         7535 :                 if (is_doacross && (collapse == 1 || i >= collapse))
   17769              :                   t = var;
   17770              :                 else
   17771              :                   {
   17772         7462 :                     t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   17773         7462 :                     gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   17774         7462 :                     gcc_assert (TREE_OPERAND (t, 0) == var);
   17775         7462 :                     t = TREE_OPERAND (t, 1);
   17776         7462 :                     gcc_assert (TREE_CODE (t) == PLUS_EXPR
   17777              :                                 || TREE_CODE (t) == MINUS_EXPR
   17778              :                                 || TREE_CODE (t) == POINTER_PLUS_EXPR);
   17779         7462 :                     gcc_assert (TREE_OPERAND (t, 0) == var);
   17780        14822 :                     t = build2 (TREE_CODE (t), TREE_TYPE (decl),
   17781              :                                 is_doacross ? var : decl,
   17782         7462 :                                 TREE_OPERAND (t, 1));
   17783              :                   }
   17784         7535 :                 gimple_seq *seq;
   17785         7535 :                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
   17786         6939 :                   seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
   17787              :                 else
   17788          596 :                   seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
   17789         7535 :                 push_gimplify_context ();
   17790         7535 :                 gimplify_assign (decl, t, seq);
   17791         7535 :                 gimple *bind = NULL;
   17792         7535 :                 if (gimplify_ctxp->temps)
   17793              :                   {
   17794         2072 :                     bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
   17795         2072 :                     *seq = NULL;
   17796         2072 :                     gimplify_seq_add_stmt (seq, bind);
   17797              :                   }
   17798         7535 :                 pop_gimplify_context (bind);
   17799              :               }
   17800              :         }
   17801        72945 :       if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
   17802         2609 :         for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
   17803              :           {
   17804         1197 :             t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
   17805         1197 :             gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   17806         1197 :             if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   17807         1197 :                 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   17808          336 :               TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   17809         1197 :             t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
   17810         1197 :             gcc_assert (COMPARISON_CLASS_P (t));
   17811         1197 :             if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   17812         1197 :                 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   17813          343 :               TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   17814              :           }
   17815              :     }
   17816              : 
   17817        51199 :   BITMAP_FREE (has_decl_expr);
   17818        51474 :   delete allocate_uids;
   17819              : 
   17820        51199 :   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
   17821        49613 :       || (loop_p && orig_for_stmt == for_stmt))
   17822              :     {
   17823         2642 :       push_gimplify_context ();
   17824         2642 :       if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
   17825              :         {
   17826         1891 :           OMP_FOR_BODY (orig_for_stmt)
   17827         1891 :             = build3 (BIND_EXPR, void_type_node, NULL,
   17828         1891 :                       OMP_FOR_BODY (orig_for_stmt), NULL);
   17829         1891 :           TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
   17830              :         }
   17831              :     }
   17832              : 
   17833        51199 :   gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
   17834              :                                          &for_body);
   17835              : 
   17836        51199 :   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
   17837        49613 :       || (loop_p && orig_for_stmt == for_stmt))
   17838              :     {
   17839         2642 :       if (gimple_code (g) == GIMPLE_BIND)
   17840         2642 :         pop_gimplify_context (g);
   17841              :       else
   17842            0 :         pop_gimplify_context (NULL);
   17843              :     }
   17844              : 
   17845        51199 :   if (orig_for_stmt != for_stmt)
   17846        36734 :     for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   17847              :       {
   17848        22808 :         t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   17849        22808 :         decl = TREE_OPERAND (t, 0);
   17850        22808 :         struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   17851        22808 :         if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
   17852          772 :           gimplify_omp_ctxp = ctx->outer_context;
   17853        22808 :         var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
   17854        22808 :         gimplify_omp_ctxp = ctx;
   17855        22808 :         omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
   17856        22808 :         TREE_OPERAND (t, 0) = var;
   17857        22808 :         t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   17858        22808 :         TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
   17859        22808 :         TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
   17860        22808 :         if (OMP_FOR_NON_RECTANGULAR (for_stmt))
   17861          791 :           for (int j = i + 1;
   17862          791 :                j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
   17863              :             {
   17864          377 :               t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
   17865          377 :               gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   17866          377 :               if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   17867          377 :                   && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   17868              :                 {
   17869          133 :                   TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
   17870          133 :                   TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   17871              :                 }
   17872          377 :               t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
   17873          377 :               gcc_assert (COMPARISON_CLASS_P (t));
   17874          377 :               if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   17875          377 :                   && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   17876              :                 {
   17877           67 :                   TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
   17878           67 :                   TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   17879              :                 }
   17880              :           }
   17881              :       }
   17882              : 
   17883        51199 :   gimplify_adjust_omp_clauses (pre_p, for_body,
   17884              :                                &OMP_FOR_CLAUSES (orig_for_stmt),
   17885        51199 :                                TREE_CODE (orig_for_stmt));
   17886              : 
   17887        51199 :   int kind;
   17888        51199 :   switch (TREE_CODE (orig_for_stmt))
   17889              :     {
   17890              :     case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
   17891        10653 :     case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
   17892         8219 :     case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
   17893         1586 :     case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
   17894        12552 :     case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
   17895            0 :     default:
   17896            0 :       gcc_unreachable ();
   17897              :     }
   17898        51199 :   if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
   17899              :     {
   17900         1056 :       gimplify_seq_add_seq (pre_p, for_pre_body);
   17901         1056 :       for_pre_body = NULL;
   17902              :     }
   17903        51199 :   gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
   17904        51199 :                                TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
   17905              :                                for_pre_body);
   17906        51199 :   if (orig_for_stmt != for_stmt)
   17907        13926 :     gimple_omp_for_set_combined_p (gfor, true);
   17908        51199 :   if (gimplify_omp_ctxp
   17909        42571 :       && (gimplify_omp_ctxp->combined_loop
   17910        35040 :           || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
   17911        12301 :               && gimplify_omp_ctxp->outer_context
   17912         7858 :               && gimplify_omp_ctxp->outer_context->combined_loop)))
   17913              :     {
   17914        13926 :       gimple_omp_for_set_combined_into_p (gfor, true);
   17915        13926 :       if (gimplify_omp_ctxp->combined_loop)
   17916         7531 :         gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
   17917              :       else
   17918         6395 :         gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
   17919              :     }
   17920              : 
   17921       124144 :   for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   17922              :     {
   17923        72945 :       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   17924        72945 :       gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
   17925        72945 :       gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
   17926        72945 :       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   17927        72945 :       gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
   17928        72945 :       gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
   17929        72945 :       t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   17930        72945 :       gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
   17931              :     }
   17932              : 
   17933              :   /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
   17934              :      constructs with GIMPLE_OMP_TASK sandwiched in between them.
   17935              :      The outer taskloop stands for computing the number of iterations,
   17936              :      counts for collapsed loops and holding taskloop specific clauses.
   17937              :      The task construct stands for the effect of data sharing on the
   17938              :      explicit task it creates and the inner taskloop stands for expansion
   17939              :      of the static loop inside of the explicit task construct.  */
   17940        51199 :   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
   17941              :     {
   17942         1586 :       tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
   17943         1586 :       tree task_clauses = NULL_TREE;
   17944         1586 :       tree c = *gfor_clauses_ptr;
   17945         1586 :       tree *gtask_clauses_ptr = &task_clauses;
   17946         1586 :       tree outer_for_clauses = NULL_TREE;
   17947         1586 :       tree *gforo_clauses_ptr = &outer_for_clauses;
   17948         1586 :       bitmap lastprivate_uids = NULL;
   17949         1586 :       if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
   17950              :         {
   17951           36 :           c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
   17952           36 :           if (c)
   17953              :             {
   17954           18 :               lastprivate_uids = BITMAP_ALLOC (NULL);
   17955           54 :               for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
   17956              :                                              OMP_CLAUSE_LASTPRIVATE))
   17957           18 :                 bitmap_set_bit (lastprivate_uids,
   17958           18 :                                 DECL_UID (OMP_CLAUSE_DECL (c)));
   17959              :             }
   17960           36 :           c = *gfor_clauses_ptr;
   17961              :         }
   17962        12252 :       for (; c; c = OMP_CLAUSE_CHAIN (c))
   17963        10666 :         switch (OMP_CLAUSE_CODE (c))
   17964              :           {
   17965              :           /* These clauses are allowed on task, move them there.  */
   17966         6228 :           case OMP_CLAUSE_SHARED:
   17967         6228 :           case OMP_CLAUSE_FIRSTPRIVATE:
   17968         6228 :           case OMP_CLAUSE_DEFAULT:
   17969         6228 :           case OMP_CLAUSE_IF:
   17970         6228 :           case OMP_CLAUSE_UNTIED:
   17971         6228 :           case OMP_CLAUSE_FINAL:
   17972         6228 :           case OMP_CLAUSE_MERGEABLE:
   17973         6228 :           case OMP_CLAUSE_PRIORITY:
   17974         6228 :           case OMP_CLAUSE_REDUCTION:
   17975         6228 :           case OMP_CLAUSE_IN_REDUCTION:
   17976         6228 :             *gtask_clauses_ptr = c;
   17977         6228 :             gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   17978         6228 :             break;
   17979         2068 :           case OMP_CLAUSE_PRIVATE:
   17980         2068 :             if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
   17981              :               {
   17982              :                 /* We want private on outer for and firstprivate
   17983              :                    on task.  */
   17984           26 :                 *gtask_clauses_ptr
   17985           26 :                   = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   17986              :                                       OMP_CLAUSE_FIRSTPRIVATE);
   17987           26 :                 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
   17988           26 :                 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
   17989              :                                                     openacc);
   17990           26 :                 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   17991           26 :                 *gforo_clauses_ptr = c;
   17992           26 :                 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   17993              :               }
   17994              :             else
   17995              :               {
   17996         2042 :                 *gtask_clauses_ptr = c;
   17997         2042 :                 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   17998              :               }
   17999              :             break;
   18000              :           /* These clauses go into outer taskloop clauses.  */
   18001          533 :           case OMP_CLAUSE_GRAINSIZE:
   18002          533 :           case OMP_CLAUSE_NUM_TASKS:
   18003          533 :           case OMP_CLAUSE_NOGROUP:
   18004          533 :             *gforo_clauses_ptr = c;
   18005          533 :             gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   18006          533 :             break;
   18007              :           /* Collapse clause we duplicate on both taskloops.  */
   18008          584 :           case OMP_CLAUSE_COLLAPSE:
   18009          584 :             *gfor_clauses_ptr = c;
   18010          584 :             gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   18011          584 :             *gforo_clauses_ptr = copy_node (c);
   18012          584 :             gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
   18013          584 :             break;
   18014              :           /* For lastprivate, keep the clause on inner taskloop, and add
   18015              :              a shared clause on task.  If the same decl is also firstprivate,
   18016              :              add also firstprivate clause on the inner taskloop.  */
   18017         1191 :           case OMP_CLAUSE_LASTPRIVATE:
   18018         1191 :             if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
   18019              :               {
   18020              :                 /* For taskloop C++ lastprivate IVs, we want:
   18021              :                    1) private on outer taskloop
   18022              :                    2) firstprivate and shared on task
   18023              :                    3) lastprivate on inner taskloop  */
   18024           38 :                 *gtask_clauses_ptr
   18025           38 :                   = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   18026              :                                       OMP_CLAUSE_FIRSTPRIVATE);
   18027           38 :                 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
   18028           38 :                 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
   18029              :                                                     openacc);
   18030           38 :                 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   18031           38 :                 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
   18032           38 :                 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   18033              :                                                        OMP_CLAUSE_PRIVATE);
   18034           38 :                 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
   18035           38 :                 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
   18036           38 :                 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
   18037           38 :                 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
   18038              :               }
   18039         1191 :             *gfor_clauses_ptr = c;
   18040         1191 :             gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   18041         1191 :             *gtask_clauses_ptr
   18042         1191 :               = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
   18043         1191 :             OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
   18044         1191 :             if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
   18045          312 :               OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
   18046         1191 :             gtask_clauses_ptr
   18047         1191 :               = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   18048         1191 :             break;
   18049              :           /* Allocate clause we duplicate on task and inner taskloop
   18050              :              if the decl is lastprivate, otherwise just put on task.  */
   18051           62 :           case OMP_CLAUSE_ALLOCATE:
   18052           62 :             if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
   18053           62 :                 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
   18054              :               {
   18055              :                 /* Additionally, put firstprivate clause on task
   18056              :                    for the allocator if it is not constant.  */
   18057           34 :                 *gtask_clauses_ptr
   18058           34 :                   = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   18059              :                                       OMP_CLAUSE_FIRSTPRIVATE);
   18060           34 :                 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
   18061           34 :                   = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
   18062           34 :                 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   18063              :               }
   18064           62 :             if (lastprivate_uids
   18065           97 :                 && bitmap_bit_p (lastprivate_uids,
   18066           35 :                                  DECL_UID (OMP_CLAUSE_DECL (c))))
   18067              :               {
   18068           17 :                 *gfor_clauses_ptr = c;
   18069           17 :                 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   18070           17 :                 *gtask_clauses_ptr = copy_node (c);
   18071           17 :                 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   18072              :               }
   18073              :             else
   18074              :               {
   18075           45 :                 *gtask_clauses_ptr = c;
   18076           45 :                 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   18077              :               }
   18078              :             break;
   18079            0 :           default:
   18080            0 :             gcc_unreachable ();
   18081              :           }
   18082         1586 :       *gfor_clauses_ptr = NULL_TREE;
   18083         1586 :       *gtask_clauses_ptr = NULL_TREE;
   18084         1586 :       *gforo_clauses_ptr = NULL_TREE;
   18085         1586 :       BITMAP_FREE (lastprivate_uids);
   18086         1586 :       gimple_set_location (gfor, input_location);
   18087         1586 :       g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
   18088         1586 :       g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
   18089              :                                  NULL_TREE, NULL_TREE, NULL_TREE);
   18090         1586 :       gimple_set_location (g, input_location);
   18091         1586 :       gimple_omp_task_set_taskloop_p (g, true);
   18092         1586 :       g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
   18093         1586 :       gomp_for *gforo
   18094         1586 :         = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
   18095              :                                 gimple_omp_for_collapse (gfor),
   18096              :                                 gimple_omp_for_pre_body (gfor));
   18097         1586 :       gimple_omp_for_set_pre_body (gfor, NULL);
   18098         1586 :       gimple_omp_for_set_combined_p (gforo, true);
   18099         1586 :       gimple_omp_for_set_combined_into_p (gfor, true);
   18100         3458 :       for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
   18101              :         {
   18102         1872 :           tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
   18103         1872 :           tree v = create_tmp_var (type);
   18104         1872 :           gimple_omp_for_set_index (gforo, i, v);
   18105         1872 :           t = unshare_expr (gimple_omp_for_initial (gfor, i));
   18106         1872 :           gimple_omp_for_set_initial (gforo, i, t);
   18107         1872 :           gimple_omp_for_set_cond (gforo, i,
   18108              :                                    gimple_omp_for_cond (gfor, i));
   18109         1872 :           t = unshare_expr (gimple_omp_for_final (gfor, i));
   18110         1872 :           gimple_omp_for_set_final (gforo, i, t);
   18111         1872 :           t = unshare_expr (gimple_omp_for_incr (gfor, i));
   18112         1872 :           gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
   18113         1872 :           TREE_OPERAND (t, 0) = v;
   18114         1872 :           gimple_omp_for_set_incr (gforo, i, t);
   18115         1872 :           t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
   18116         1872 :           OMP_CLAUSE_DECL (t) = v;
   18117         1872 :           OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
   18118         1872 :           gimple_omp_for_set_clauses (gforo, t);
   18119         1872 :           if (OMP_FOR_NON_RECTANGULAR (for_stmt))
   18120              :             {
   18121           90 :               tree *p1 = NULL, *p2 = NULL;
   18122           90 :               t = gimple_omp_for_initial (gforo, i);
   18123           90 :               if (TREE_CODE (t) == TREE_VEC)
   18124           34 :                 p1 = &TREE_VEC_ELT (t, 0);
   18125           90 :               t = gimple_omp_for_final (gforo, i);
   18126           90 :               if (TREE_CODE (t) == TREE_VEC)
   18127              :                 {
   18128           31 :                   if (p1)
   18129           23 :                     p2 = &TREE_VEC_ELT (t, 0);
   18130              :                   else
   18131            8 :                     p1 = &TREE_VEC_ELT (t, 0);
   18132              :                 }
   18133           90 :               if (p1)
   18134              :                 {
   18135              :                   int j;
   18136           58 :                   for (j = 0; j < i; j++)
   18137           58 :                     if (*p1 == gimple_omp_for_index (gfor, j))
   18138              :                       {
   18139           42 :                         *p1 = gimple_omp_for_index (gforo, j);
   18140           42 :                         if (p2)
   18141           23 :                           *p2 = *p1;
   18142              :                         break;
   18143              :                       }
   18144           42 :                   gcc_assert (j < i);
   18145              :                 }
   18146              :             }
   18147              :         }
   18148         1586 :       gimplify_seq_add_stmt (pre_p, gforo);
   18149              :     }
   18150              :   else
   18151        49613 :     gimplify_seq_add_stmt (pre_p, gfor);
   18152              : 
   18153        51199 :   if (TREE_CODE (orig_for_stmt) == OMP_FOR)
   18154              :     {
   18155        18189 :       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   18156        18189 :       unsigned lastprivate_conditional = 0;
   18157        18189 :       while (ctx
   18158        18225 :              && (ctx->region_type == ORT_TARGET_DATA
   18159        14187 :                  || ctx->region_type == ORT_TASKGROUP))
   18160           36 :         ctx = ctx->outer_context;
   18161        18189 :       if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
   18162        13927 :         for (tree c = gimple_omp_for_clauses (gfor);
   18163        63183 :              c; c = OMP_CLAUSE_CHAIN (c))
   18164        49256 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   18165        49256 :               && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   18166          158 :             ++lastprivate_conditional;
   18167        13927 :       if (lastprivate_conditional)
   18168              :         {
   18169          118 :           struct omp_for_data fd;
   18170          118 :           omp_extract_for_data (gfor, &fd, NULL);
   18171          118 :           tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
   18172          118 :                                               lastprivate_conditional);
   18173          118 :           tree var = create_tmp_var_raw (type);
   18174          118 :           tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
   18175          118 :           OMP_CLAUSE_DECL (c) = var;
   18176          118 :           OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
   18177          118 :           gimple_omp_for_set_clauses (gfor, c);
   18178          118 :           omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
   18179              :         }
   18180              :     }
   18181        33010 :   else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
   18182              :     {
   18183        10653 :       unsigned lastprivate_conditional = 0;
   18184        49159 :       for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
   18185        38506 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   18186        38506 :             && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   18187          119 :           ++lastprivate_conditional;
   18188        10653 :       if (lastprivate_conditional)
   18189              :         {
   18190           91 :           struct omp_for_data fd;
   18191           91 :           omp_extract_for_data (gfor, &fd, NULL);
   18192           91 :           tree type = unsigned_type_for (fd.iter_type);
   18193          301 :           while (lastprivate_conditional--)
   18194              :             {
   18195          119 :               tree c = build_omp_clause (UNKNOWN_LOCATION,
   18196              :                                          OMP_CLAUSE__CONDTEMP_);
   18197          119 :               OMP_CLAUSE_DECL (c) = create_tmp_var (type);
   18198          119 :               OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
   18199          119 :               gimple_omp_for_set_clauses (gfor, c);
   18200              :             }
   18201              :         }
   18202              :     }
   18203              : 
   18204        51199 :   if (ret != GS_ALL_DONE)
   18205              :     return GS_ERROR;
   18206        51199 :   *expr_p = NULL_TREE;
   18207        51199 :   return GS_ALL_DONE;
   18208              : }
   18209              : 
   18210              : /* Helper for gimplify_omp_loop, called through walk_tree.  */
   18211              : 
   18212              : static tree
   18213          294 : note_no_context_vars (tree *tp, int *, void *data)
   18214              : {
   18215          294 :   if (VAR_P (*tp)
   18216           56 :       && DECL_CONTEXT (*tp) == NULL_TREE
   18217          309 :       && !is_global_var (*tp))
   18218              :     {
   18219           15 :       vec<tree> *d = (vec<tree> *) data;
   18220           15 :       d->safe_push (*tp);
   18221           15 :       DECL_CONTEXT (*tp) = current_function_decl;
   18222              :     }
   18223          294 :   return NULL_TREE;
   18224              : }
   18225              : 
   18226              : /* Gimplify the gross structure of an OMP_LOOP statement.  */
   18227              : 
   18228              : static enum gimplify_status
   18229         1056 : gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
   18230              : {
   18231         1056 :   tree for_stmt = *expr_p;
   18232         1056 :   tree clauses = OMP_FOR_CLAUSES (for_stmt);
   18233         1056 :   struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
   18234         1056 :   enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
   18235         1056 :   int i;
   18236              : 
   18237         1056 :   omp_maybe_apply_loop_xforms (expr_p, NULL_TREE);
   18238         1056 :   if (*expr_p != for_stmt)
   18239              :     return GS_OK;
   18240              : 
   18241              :   /* If order is not present, the behavior is as if order(concurrent)
   18242              :      appeared.  */
   18243         1056 :   tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
   18244         1056 :   if (order == NULL_TREE)
   18245              :     {
   18246          799 :       order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
   18247          799 :       OMP_CLAUSE_CHAIN (order) = clauses;
   18248          799 :       OMP_FOR_CLAUSES (for_stmt) = clauses = order;
   18249              :     }
   18250              : 
   18251         1056 :   tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
   18252         1056 :   if (bind == NULL_TREE)
   18253              :     {
   18254          574 :       if (!flag_openmp) /* flag_openmp_simd */
   18255              :         ;
   18256          557 :       else if (octx && (octx->region_type & ORT_TEAMS) != 0)
   18257              :         kind = OMP_CLAUSE_BIND_TEAMS;
   18258          327 :       else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
   18259              :         kind = OMP_CLAUSE_BIND_PARALLEL;
   18260              :       else
   18261              :         {
   18262          187 :           for (; octx; octx = octx->outer_context)
   18263              :             {
   18264           79 :               if ((octx->region_type & ORT_ACC) != 0
   18265           79 :                   || octx->region_type == ORT_NONE
   18266           79 :                   || octx->region_type == ORT_IMPLICIT_TARGET)
   18267            0 :                 continue;
   18268              :               break;
   18269              :             }
   18270          187 :           if (octx == NULL && !in_omp_construct)
   18271            4 :             error_at (EXPR_LOCATION (for_stmt),
   18272              :                       "%<bind%> clause not specified on a %<loop%> "
   18273              :                       "construct not nested inside another OpenMP construct");
   18274              :         }
   18275          574 :       bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
   18276          574 :       OMP_CLAUSE_CHAIN (bind) = clauses;
   18277          574 :       OMP_CLAUSE_BIND_KIND (bind) = kind;
   18278          574 :       OMP_FOR_CLAUSES (for_stmt) = bind;
   18279              :     }
   18280              :   else
   18281          482 :     switch (OMP_CLAUSE_BIND_KIND (bind))
   18282              :       {
   18283              :       case OMP_CLAUSE_BIND_THREAD:
   18284              :         break;
   18285          166 :       case OMP_CLAUSE_BIND_PARALLEL:
   18286          166 :         if (!flag_openmp) /* flag_openmp_simd */
   18287              :           {
   18288            0 :             OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   18289            0 :             break;
   18290              :           }
   18291          240 :         for (; octx; octx = octx->outer_context)
   18292           78 :           if (octx->region_type == ORT_SIMD
   18293           78 :               && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
   18294              :             {
   18295            4 :               error_at (EXPR_LOCATION (for_stmt),
   18296              :                         "%<bind(parallel)%> on a %<loop%> construct nested "
   18297              :                         "inside %<simd%> construct");
   18298            4 :               OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   18299            4 :               break;
   18300              :             }
   18301              :         kind = OMP_CLAUSE_BIND_PARALLEL;
   18302              :         break;
   18303          162 :       case OMP_CLAUSE_BIND_TEAMS:
   18304          162 :         if (!flag_openmp) /* flag_openmp_simd */
   18305              :           {
   18306            0 :             OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   18307            0 :             break;
   18308              :           }
   18309          162 :         if ((octx
   18310          128 :              && octx->region_type != ORT_IMPLICIT_TARGET
   18311          111 :              && octx->region_type != ORT_NONE
   18312          111 :              && (octx->region_type & ORT_TEAMS) == 0)
   18313          110 :             || in_omp_construct)
   18314              :           {
   18315           64 :             error_at (EXPR_LOCATION (for_stmt),
   18316              :                       "%<bind(teams)%> on a %<loop%> region not strictly "
   18317              :                       "nested inside of a %<teams%> region");
   18318           64 :             OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   18319           64 :             break;
   18320              :           }
   18321              :         kind = OMP_CLAUSE_BIND_TEAMS;
   18322              :         break;
   18323            0 :       default:
   18324            0 :         gcc_unreachable ();
   18325              :       }
   18326              : 
   18327         4280 :   for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
   18328         3224 :     switch (OMP_CLAUSE_CODE (*pc))
   18329              :       {
   18330          343 :       case OMP_CLAUSE_REDUCTION:
   18331          343 :         if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
   18332              :           {
   18333            4 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   18334              :                       "%<inscan%> %<reduction%> clause on "
   18335              :                       "%qs construct", "loop");
   18336            4 :             OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
   18337              :           }
   18338          343 :         if (OMP_CLAUSE_REDUCTION_TASK (*pc))
   18339              :           {
   18340            8 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   18341              :                       "invalid %<task%> reduction modifier on construct "
   18342              :                       "other than %<parallel%>, %qs or %<sections%>",
   18343            4 :                       lang_GNU_Fortran () ? "do" : "for");
   18344            4 :             OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
   18345              :           }
   18346          343 :         pc = &OMP_CLAUSE_CHAIN (*pc);
   18347          343 :         break;
   18348              :       case OMP_CLAUSE_LASTPRIVATE:
   18349          293 :         for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   18350              :           {
   18351          289 :             tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   18352          289 :             gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   18353          289 :             if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
   18354              :               break;
   18355           26 :             if (OMP_FOR_ORIG_DECLS (for_stmt)
   18356           25 :                 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
   18357              :                                             i)) == TREE_LIST
   18358           48 :                 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
   18359              :                                                i)))
   18360              :               {
   18361           22 :                 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   18362           22 :                 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
   18363              :                   break;
   18364              :               }
   18365              :           }
   18366          289 :         if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
   18367              :           {
   18368            4 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   18369              :                       "%<lastprivate%> clause on a %<loop%> construct refers "
   18370              :                       "to a variable %qD which is not the loop iterator",
   18371            4 :                       OMP_CLAUSE_DECL (*pc));
   18372            4 :             *pc = OMP_CLAUSE_CHAIN (*pc);
   18373            4 :             break;
   18374              :           }
   18375          285 :         pc = &OMP_CLAUSE_CHAIN (*pc);
   18376          285 :         break;
   18377         2592 :       default:
   18378         2592 :         pc = &OMP_CLAUSE_CHAIN (*pc);
   18379         2592 :         break;
   18380              :     }
   18381              : 
   18382         1056 :   TREE_SET_CODE (for_stmt, OMP_SIMD);
   18383              : 
   18384         1056 :   int last;
   18385         1056 :   switch (kind)
   18386              :     {
   18387              :     case OMP_CLAUSE_BIND_THREAD: last = 0; break;
   18388          414 :     case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
   18389          220 :     case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
   18390              :     }
   18391         1910 :   for (int pass = 1; pass <= last; pass++)
   18392              :     {
   18393          854 :       if (pass == 2)
   18394              :         {
   18395          220 :           tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
   18396              :                               make_node (BLOCK));
   18397          220 :           append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
   18398          220 :           *expr_p = make_node (OMP_PARALLEL);
   18399          220 :           TREE_TYPE (*expr_p) = void_type_node;
   18400          220 :           OMP_PARALLEL_BODY (*expr_p) = bind;
   18401          220 :           OMP_PARALLEL_COMBINED (*expr_p) = 1;
   18402          220 :           SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
   18403          220 :           tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
   18404          452 :           for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   18405          232 :             if (OMP_FOR_ORIG_DECLS (for_stmt)
   18406          232 :                 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
   18407              :                     == TREE_LIST))
   18408              :               {
   18409           16 :                 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   18410           16 :                 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
   18411              :                   {
   18412           13 :                     *pc = build_omp_clause (UNKNOWN_LOCATION,
   18413              :                                             OMP_CLAUSE_FIRSTPRIVATE);
   18414           13 :                     OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
   18415           13 :                     pc = &OMP_CLAUSE_CHAIN (*pc);
   18416              :                   }
   18417              :               }
   18418              :         }
   18419          854 :       tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
   18420          854 :       tree *pc = &OMP_FOR_CLAUSES (t);
   18421          854 :       TREE_TYPE (t) = void_type_node;
   18422          854 :       OMP_FOR_BODY (t) = *expr_p;
   18423          854 :       SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
   18424         3968 :       for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   18425         3114 :         switch (OMP_CLAUSE_CODE (c))
   18426              :           {
   18427         1992 :           case OMP_CLAUSE_BIND:
   18428         1992 :           case OMP_CLAUSE_ORDER:
   18429         1992 :           case OMP_CLAUSE_COLLAPSE:
   18430         1992 :             *pc = copy_node (c);
   18431         1992 :             pc = &OMP_CLAUSE_CHAIN (*pc);
   18432         1992 :             break;
   18433              :           case OMP_CLAUSE_PRIVATE:
   18434              :           case OMP_CLAUSE_FIRSTPRIVATE:
   18435              :             /* Only needed on innermost.  */
   18436              :             break;
   18437          351 :           case OMP_CLAUSE_LASTPRIVATE:
   18438          351 :             if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
   18439              :               {
   18440            7 :                 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   18441              :                                         OMP_CLAUSE_FIRSTPRIVATE);
   18442            7 :                 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
   18443            7 :                 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
   18444            7 :                 pc = &OMP_CLAUSE_CHAIN (*pc);
   18445              :               }
   18446          351 :             *pc = copy_node (c);
   18447          351 :             OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
   18448          351 :             TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
   18449          351 :             if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
   18450              :               {
   18451           22 :                 if (pass != last)
   18452            7 :                   OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
   18453              :                 else
   18454           15 :                   lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
   18455           22 :                 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
   18456              :               }
   18457          351 :             pc = &OMP_CLAUSE_CHAIN (*pc);
   18458          351 :             break;
   18459          463 :           case OMP_CLAUSE_REDUCTION:
   18460          463 :             *pc = copy_node (c);
   18461          463 :             OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
   18462          463 :             TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
   18463          463 :             if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
   18464              :               {
   18465           15 :                 auto_vec<tree> no_context_vars;
   18466           15 :                 int walk_subtrees = 0;
   18467           15 :                 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
   18468              :                                       &walk_subtrees, &no_context_vars);
   18469           15 :                 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
   18470            0 :                   note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
   18471           15 :                 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
   18472              :                                               note_no_context_vars,
   18473              :                                               &no_context_vars);
   18474           15 :                 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
   18475              :                                               note_no_context_vars,
   18476              :                                               &no_context_vars);
   18477              : 
   18478           15 :                 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
   18479           15 :                   = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
   18480           15 :                 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
   18481            0 :                   OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
   18482            0 :                     = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
   18483              : 
   18484           15 :                 hash_map<tree, tree> decl_map;
   18485           15 :                 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
   18486           15 :                 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
   18487           15 :                               OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
   18488           15 :                 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
   18489            0 :                   decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
   18490            0 :                                 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
   18491              : 
   18492           15 :                 copy_body_data id;
   18493           15 :                 memset (&id, 0, sizeof (id));
   18494           15 :                 id.src_fn = current_function_decl;
   18495           15 :                 id.dst_fn = current_function_decl;
   18496           15 :                 id.src_cfun = cfun;
   18497           15 :                 id.decl_map = &decl_map;
   18498           15 :                 id.copy_decl = copy_decl_no_change;
   18499           15 :                 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
   18500           15 :                 id.transform_new_cfg = true;
   18501           15 :                 id.transform_return_to_modify = false;
   18502           15 :                 id.eh_lp_nr = 0;
   18503           15 :                 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
   18504              :                            &id, NULL);
   18505           15 :                 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
   18506              :                            &id, NULL);
   18507              : 
   18508           60 :                 for (tree d : no_context_vars)
   18509              :                   {
   18510           15 :                     DECL_CONTEXT (d) = NULL_TREE;
   18511           15 :                     DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
   18512              :                   }
   18513           15 :               }
   18514              :             else
   18515              :               {
   18516          448 :                 OMP_CLAUSE_REDUCTION_INIT (*pc)
   18517          448 :                   = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
   18518          448 :                 OMP_CLAUSE_REDUCTION_MERGE (*pc)
   18519          896 :                   = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
   18520              :               }
   18521          463 :             pc = &OMP_CLAUSE_CHAIN (*pc);
   18522          463 :             break;
   18523            0 :           default:
   18524            0 :             gcc_unreachable ();
   18525              :           }
   18526          854 :       *pc = NULL_TREE;
   18527          854 :       *expr_p = t;
   18528              :     }
   18529         1056 :   return gimplify_expr (expr_p, pre_p, NULL, is_gimple_stmt, fb_none);
   18530              : }
   18531              : 
   18532              : 
   18533              : /* Helper function of optimize_target_teams, find OMP_TEAMS inside
   18534              :    of OMP_TARGET's body.  */
   18535              : 
   18536              : static tree
   18537        98520 : find_omp_teams (tree *tp, int *walk_subtrees, void *)
   18538              : {
   18539        98520 :   *walk_subtrees = 0;
   18540        98520 :   switch (TREE_CODE (*tp))
   18541              :     {
   18542              :     case OMP_TEAMS:
   18543              :       return *tp;
   18544        27281 :     case BIND_EXPR:
   18545        27281 :     case STATEMENT_LIST:
   18546        27281 :       *walk_subtrees = 1;
   18547        27281 :       break;
   18548              :     default:
   18549              :       break;
   18550              :     }
   18551              :   return NULL_TREE;
   18552              : }
   18553              : 
   18554              : /* Helper function of optimize_target_teams, determine if the expression
   18555              :    can be computed safely before the target construct on the host.  */
   18556              : 
   18557              : static tree
   18558         1311 : computable_teams_clause (tree *tp, int *walk_subtrees, void *)
   18559              : {
   18560         1831 :   splay_tree_node n;
   18561              : 
   18562         1831 :   if (TYPE_P (*tp))
   18563              :     {
   18564            0 :       *walk_subtrees = 0;
   18565            0 :       return NULL_TREE;
   18566              :     }
   18567         1831 :   switch (TREE_CODE (*tp))
   18568              :     {
   18569          990 :     case VAR_DECL:
   18570          990 :     case PARM_DECL:
   18571          990 :     case RESULT_DECL:
   18572          990 :       *walk_subtrees = 0;
   18573          990 :       if (error_operand_p (*tp)
   18574          990 :           || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
   18575          990 :           || DECL_HAS_VALUE_EXPR_P (*tp)
   18576          990 :           || DECL_THREAD_LOCAL_P (*tp)
   18577          990 :           || TREE_SIDE_EFFECTS (*tp)
   18578         1980 :           || TREE_THIS_VOLATILE (*tp))
   18579            0 :         return *tp;
   18580          990 :       if (is_global_var (*tp)
   18581          990 :           && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
   18582            0 :               || lookup_attribute ("omp declare target link",
   18583            0 :                                    DECL_ATTRIBUTES (*tp))))
   18584           16 :         return *tp;
   18585          974 :       if (VAR_P (*tp)
   18586          668 :           && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
   18587           50 :           && !is_global_var (*tp)
   18588         1024 :           && decl_function_context (*tp) == current_function_decl)
   18589           50 :         return *tp;
   18590         1848 :       n = splay_tree_lookup (gimplify_omp_ctxp->variables,
   18591          924 :                              (splay_tree_key) *tp);
   18592          924 :       if (n == NULL)
   18593              :         {
   18594          292 :           if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
   18595              :             return NULL_TREE;
   18596           24 :           return *tp;
   18597              :         }
   18598          632 :       else if (n->value & GOVD_LOCAL)
   18599            0 :         return *tp;
   18600          632 :       else if (n->value & GOVD_FIRSTPRIVATE)
   18601              :         return NULL_TREE;
   18602          112 :       else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
   18603              :                == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
   18604              :         return NULL_TREE;
   18605           96 :       return *tp;
   18606           76 :     case INTEGER_CST:
   18607           76 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
   18608              :         return *tp;
   18609              :       return NULL_TREE;
   18610          520 :     case TARGET_EXPR:
   18611          520 :       if (TARGET_EXPR_INITIAL (*tp)
   18612          520 :           || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
   18613              :         return *tp;
   18614          520 :       return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
   18615          520 :                                       walk_subtrees, NULL);
   18616              :     /* Allow some reasonable subset of integral arithmetics.  */
   18617          193 :     case PLUS_EXPR:
   18618          193 :     case MINUS_EXPR:
   18619          193 :     case MULT_EXPR:
   18620          193 :     case TRUNC_DIV_EXPR:
   18621          193 :     case CEIL_DIV_EXPR:
   18622          193 :     case FLOOR_DIV_EXPR:
   18623          193 :     case ROUND_DIV_EXPR:
   18624          193 :     case TRUNC_MOD_EXPR:
   18625          193 :     case CEIL_MOD_EXPR:
   18626          193 :     case FLOOR_MOD_EXPR:
   18627          193 :     case ROUND_MOD_EXPR:
   18628          193 :     case RDIV_EXPR:
   18629          193 :     case EXACT_DIV_EXPR:
   18630          193 :     case MIN_EXPR:
   18631          193 :     case MAX_EXPR:
   18632          193 :     case LSHIFT_EXPR:
   18633          193 :     case RSHIFT_EXPR:
   18634          193 :     case BIT_IOR_EXPR:
   18635          193 :     case BIT_XOR_EXPR:
   18636          193 :     case BIT_AND_EXPR:
   18637          193 :     case NEGATE_EXPR:
   18638          193 :     case ABS_EXPR:
   18639          193 :     case BIT_NOT_EXPR:
   18640          193 :     case NON_LVALUE_EXPR:
   18641          193 :     CASE_CONVERT:
   18642          193 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
   18643              :         return *tp;
   18644              :       return NULL_TREE;
   18645              :     /* And disallow anything else, except for comparisons.  */
   18646           52 :     default:
   18647           52 :       if (COMPARISON_CLASS_P (*tp))
   18648              :         return NULL_TREE;
   18649              :       return *tp;
   18650              :     }
   18651              : }
   18652              : 
   18653              : /* Try to determine if the num_teams and/or thread_limit expressions
   18654              :    can have their values determined already before entering the
   18655              :    target construct.
   18656              :    INTEGER_CSTs trivially are,
   18657              :    integral decls that are firstprivate (explicitly or implicitly)
   18658              :    or explicitly map(always, to:) or map(always, tofrom:) on the target
   18659              :    region too, and expressions involving simple arithmetics on those
   18660              :    too, function calls are not ok, dereferencing something neither etc.
   18661              :    Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
   18662              :    EXPR based on what we find:
   18663              :    0 stands for clause not specified at all, use implementation default
   18664              :    -1 stands for value that can't be determined easily before entering
   18665              :       the target construct.
   18666              :    -2 means that no explicit teams construct was specified
   18667              :    If teams construct is not present at all, use 1 for num_teams
   18668              :    and 0 for thread_limit (only one team is involved, and the thread
   18669              :    limit is implementation defined.  */
   18670              : 
   18671              : static void
   18672        13492 : optimize_target_teams (tree target, gimple_seq *pre_p)
   18673              : {
   18674        13492 :   tree body = OMP_BODY (target);
   18675        13492 :   tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
   18676        13492 :   tree num_teams_lower = NULL_TREE;
   18677        13492 :   tree num_teams_upper = integer_zero_node;
   18678        13492 :   tree thread_limit = integer_zero_node;
   18679        13492 :   location_t num_teams_loc = EXPR_LOCATION (target);
   18680        13492 :   location_t thread_limit_loc = EXPR_LOCATION (target);
   18681        13492 :   tree c, *p, expr;
   18682        13492 :   struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
   18683              : 
   18684        13492 :   if (teams == NULL_TREE)
   18685         7371 :     num_teams_upper = build_int_cst (integer_type_node, -2);
   18686              :   else
   18687        10587 :     for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
   18688              :       {
   18689         4466 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
   18690              :           {
   18691          617 :             p = &num_teams_upper;
   18692          617 :             num_teams_loc = OMP_CLAUSE_LOCATION (c);
   18693          617 :             if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
   18694              :               {
   18695          148 :                 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
   18696          148 :                 if (TREE_CODE (expr) == INTEGER_CST)
   18697           21 :                   num_teams_lower = expr;
   18698          127 :                 else if (walk_tree (&expr, computable_teams_clause,
   18699              :                                     NULL, NULL))
   18700           19 :                   num_teams_lower = integer_minus_one_node;
   18701              :                 else
   18702              :                   {
   18703          108 :                     num_teams_lower = expr;
   18704          108 :                     gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
   18705          108 :                     if (gimplify_expr (&num_teams_lower, pre_p, NULL,
   18706              :                                        is_gimple_val, fb_rvalue, false)
   18707              :                         == GS_ERROR)
   18708              :                       {
   18709            0 :                         gimplify_omp_ctxp = target_ctx;
   18710            0 :                         num_teams_lower = integer_minus_one_node;
   18711              :                       }
   18712              :                     else
   18713              :                       {
   18714          108 :                         gimplify_omp_ctxp = target_ctx;
   18715          108 :                         if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
   18716           28 :                           OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
   18717           56 :                             = num_teams_lower;
   18718              :                       }
   18719              :                   }
   18720              :               }
   18721              :           }
   18722         3849 :         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
   18723              :           {
   18724          471 :             p = &thread_limit;
   18725          471 :             thread_limit_loc = OMP_CLAUSE_LOCATION (c);
   18726              :           }
   18727              :         else
   18728         3378 :           continue;
   18729         1088 :         expr = OMP_CLAUSE_OPERAND (c, 0);
   18730         1088 :         if (TREE_CODE (expr) == INTEGER_CST)
   18731              :           {
   18732          173 :             *p = expr;
   18733          173 :             continue;
   18734              :           }
   18735          915 :         if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
   18736              :           {
   18737          219 :             *p = integer_minus_one_node;
   18738          219 :             continue;
   18739              :           }
   18740          696 :         *p = expr;
   18741          696 :         gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
   18742          696 :         if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
   18743              :             == GS_ERROR)
   18744              :           {
   18745            0 :             gimplify_omp_ctxp = target_ctx;
   18746            0 :             *p = integer_minus_one_node;
   18747            0 :             continue;
   18748              :           }
   18749          696 :         gimplify_omp_ctxp = target_ctx;
   18750          696 :         if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
   18751           48 :           OMP_CLAUSE_OPERAND (c, 0) = *p;
   18752              :       }
   18753        13492 :   if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
   18754              :     {
   18755        13224 :       c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
   18756        13224 :       OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
   18757        13224 :       OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
   18758        13224 :       OMP_TARGET_CLAUSES (target) = c;
   18759              :     }
   18760        13492 :   c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
   18761        13492 :   OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
   18762        13492 :   OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
   18763        13492 :   OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
   18764        13492 :   OMP_TARGET_CLAUSES (target) = c;
   18765        13492 : }
   18766              : 
   18767              : /* Gimplify the gross structure of several OMP constructs.  */
   18768              : 
   18769              : static void
   18770        39824 : gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
   18771              : {
   18772        39824 :   tree expr = *expr_p;
   18773        39824 :   gimple *stmt;
   18774        39824 :   gimple_seq body = NULL;
   18775        39824 :   enum omp_region_type ort;
   18776              : 
   18777        39824 :   switch (TREE_CODE (expr))
   18778              :     {
   18779              :     case OMP_SECTIONS:
   18780              :     case OMP_SINGLE:
   18781              :       ort = ORT_WORKSHARE;
   18782              :       break;
   18783          214 :     case OMP_SCOPE:
   18784          214 :       ort = ORT_TASKGROUP;
   18785          214 :       break;
   18786        13492 :     case OMP_TARGET:
   18787        13492 :       ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
   18788              :       break;
   18789         2543 :     case OACC_KERNELS:
   18790         2543 :       ort = ORT_ACC_KERNELS;
   18791         2543 :       break;
   18792         7901 :     case OACC_PARALLEL:
   18793         7901 :       ort = ORT_ACC_PARALLEL;
   18794         7901 :       break;
   18795         1040 :     case OACC_SERIAL:
   18796         1040 :       ort = ORT_ACC_SERIAL;
   18797         1040 :       break;
   18798         1950 :     case OACC_DATA:
   18799         1950 :       ort = ORT_ACC_DATA;
   18800         1950 :       break;
   18801         1872 :     case OMP_TARGET_DATA:
   18802         1872 :       ort = ORT_TARGET_DATA;
   18803         1872 :       break;
   18804         8793 :     case OMP_TEAMS:
   18805         8793 :       ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
   18806         8793 :       if (gimplify_omp_ctxp == NULL
   18807         6161 :           || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
   18808         2632 :         ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
   18809              :       break;
   18810          118 :     case OACC_HOST_DATA:
   18811          118 :       ort = ORT_ACC_HOST_DATA;
   18812          118 :       break;
   18813            0 :     default:
   18814            0 :       gcc_unreachable ();
   18815              :     }
   18816              : 
   18817        39824 :   gimple_seq iterator_loops_seq = NULL;
   18818        39824 :   if (TREE_CODE (expr) == OMP_TARGET || TREE_CODE (expr) == OMP_TARGET_DATA)
   18819              :     {
   18820        15364 :       remove_unused_omp_iterator_vars (&OMP_CLAUSES (expr));
   18821        15364 :       build_omp_iterators_loops (&OMP_CLAUSES (expr), &iterator_loops_seq);
   18822              :     }
   18823              : 
   18824        39824 :   bool save_in_omp_construct = in_omp_construct;
   18825        39824 :   if ((ort & ORT_ACC) == 0)
   18826        26272 :     in_omp_construct = false;
   18827        39824 :   gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
   18828        39824 :                              TREE_CODE (expr), &iterator_loops_seq);
   18829        39824 :   if (TREE_CODE (expr) == OMP_TARGET)
   18830        13492 :     optimize_target_teams (expr, pre_p);
   18831        39824 :   if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
   18832        10908 :       || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
   18833              :     {
   18834        31548 :       push_gimplify_context ();
   18835        31548 :       gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
   18836        31548 :       if (gimple_code (g) == GIMPLE_BIND)
   18837        31548 :         pop_gimplify_context (g);
   18838              :       else
   18839            0 :         pop_gimplify_context (NULL);
   18840        31548 :       if ((ort & ORT_TARGET_DATA) != 0)
   18841              :         {
   18842         3940 :           enum built_in_function end_ix;
   18843         3940 :           switch (TREE_CODE (expr))
   18844              :             {
   18845              :             case OACC_DATA:
   18846              :             case OACC_HOST_DATA:
   18847              :               end_ix = BUILT_IN_GOACC_DATA_END;
   18848              :               break;
   18849         1872 :             case OMP_TARGET_DATA:
   18850         1872 :               end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
   18851         1872 :               break;
   18852            0 :             default:
   18853            0 :               gcc_unreachable ();
   18854              :             }
   18855         3940 :           tree fn = builtin_decl_explicit (end_ix);
   18856         3940 :           g = gimple_build_call (fn, 0);
   18857         3940 :           gimple_seq cleanup = NULL;
   18858         3940 :           gimple_seq_add_stmt (&cleanup, g);
   18859         3940 :           g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
   18860         3940 :           body = NULL;
   18861         3940 :           gimple_seq_add_stmt (&body, g);
   18862              :         }
   18863              :     }
   18864              :   else
   18865         8276 :     gimplify_and_add (OMP_BODY (expr), &body);
   18866        39824 :   gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
   18867        39824 :                                TREE_CODE (expr), &iterator_loops_seq);
   18868        39824 :   in_omp_construct = save_in_omp_construct;
   18869              : 
   18870        39824 :   switch (TREE_CODE (expr))
   18871              :     {
   18872         1950 :     case OACC_DATA:
   18873         3900 :       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
   18874         1950 :                                       OMP_CLAUSES (expr));
   18875         1950 :       break;
   18876          118 :     case OACC_HOST_DATA:
   18877          118 :       if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
   18878              :         {
   18879          128 :           for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   18880           95 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
   18881           57 :               OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
   18882              :         }
   18883              : 
   18884          236 :       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
   18885          118 :                                       OMP_CLAUSES (expr));
   18886          118 :       break;
   18887         2543 :     case OACC_KERNELS:
   18888         5086 :       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
   18889         2543 :                                       OMP_CLAUSES (expr));
   18890         2543 :       break;
   18891         7901 :     case OACC_PARALLEL:
   18892        15802 :       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
   18893         7901 :                                       OMP_CLAUSES (expr));
   18894         7901 :       break;
   18895         1040 :     case OACC_SERIAL:
   18896         2080 :       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
   18897         1040 :                                       OMP_CLAUSES (expr));
   18898         1040 :       break;
   18899          626 :     case OMP_SECTIONS:
   18900          626 :       stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
   18901          626 :       break;
   18902         1275 :     case OMP_SINGLE:
   18903         1275 :       stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
   18904         1275 :       break;
   18905          214 :     case OMP_SCOPE:
   18906          214 :       stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
   18907          214 :       break;
   18908        13492 :     case OMP_TARGET:
   18909        26984 :       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
   18910        13492 :                                       OMP_CLAUSES (expr), iterator_loops_seq);
   18911        13492 :       break;
   18912         1872 :     case OMP_TARGET_DATA:
   18913              :       /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
   18914              :          to be evaluated before the use_device_{ptr,addr} clauses if they
   18915              :          refer to the same variables.  */
   18916         1872 :       {
   18917         1872 :         tree use_device_clauses;
   18918         1872 :         tree *pc, *uc = &use_device_clauses;
   18919         9968 :         for (pc = &OMP_CLAUSES (expr); *pc; )
   18920         8096 :           if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
   18921         8096 :               || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
   18922              :             {
   18923         1959 :               *uc = *pc;
   18924         1959 :               *pc = OMP_CLAUSE_CHAIN (*pc);
   18925         1959 :               uc = &OMP_CLAUSE_CHAIN (*uc);
   18926              :             }
   18927              :           else
   18928         6137 :             pc = &OMP_CLAUSE_CHAIN (*pc);
   18929         1872 :         *uc = NULL_TREE;
   18930         1872 :         *pc = use_device_clauses;
   18931         1872 :         stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
   18932         1872 :                                         OMP_CLAUSES (expr), iterator_loops_seq);
   18933              :       }
   18934         1872 :       break;
   18935         8793 :     case OMP_TEAMS:
   18936         8793 :       stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
   18937         8793 :       if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
   18938         2632 :         gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
   18939              :       break;
   18940            0 :     default:
   18941            0 :       gcc_unreachable ();
   18942              :     }
   18943              : 
   18944        39824 :   gimplify_seq_add_stmt (pre_p, stmt);
   18945        39824 :   *expr_p = NULL_TREE;
   18946        39824 : }
   18947              : 
   18948              : /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
   18949              :    target update constructs.  */
   18950              : 
   18951              : static void
   18952        12297 : gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
   18953              : {
   18954        12297 :   tree expr = *expr_p;
   18955        12297 :   int kind;
   18956        12297 :   gomp_target *stmt;
   18957        12297 :   enum omp_region_type ort = ORT_WORKSHARE;
   18958              : 
   18959        12297 :   switch (TREE_CODE (expr))
   18960              :     {
   18961              :     case OACC_ENTER_DATA:
   18962              :       kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
   18963              :       ort = ORT_ACC;
   18964              :       break;
   18965              :     case OACC_EXIT_DATA:
   18966              :       kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
   18967              :       ort = ORT_ACC;
   18968              :       break;
   18969              :     case OACC_UPDATE:
   18970              :       kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
   18971              :       ort = ORT_ACC;
   18972              :       break;
   18973              :     case OMP_TARGET_UPDATE:
   18974              :       kind = GF_OMP_TARGET_KIND_UPDATE;
   18975              :       break;
   18976              :     case OMP_TARGET_ENTER_DATA:
   18977              :       kind = GF_OMP_TARGET_KIND_ENTER_DATA;
   18978              :       break;
   18979              :     case OMP_TARGET_EXIT_DATA:
   18980              :       kind = GF_OMP_TARGET_KIND_EXIT_DATA;
   18981              :       break;
   18982            0 :     default:
   18983            0 :       gcc_unreachable ();
   18984              :     }
   18985              : 
   18986        12297 :   gimple_seq iterator_loops_seq = NULL;
   18987        12297 :   remove_unused_omp_iterator_vars (&OMP_STANDALONE_CLAUSES (expr));
   18988        12297 :   build_omp_iterators_loops (&OMP_STANDALONE_CLAUSES (expr),
   18989              :                              &iterator_loops_seq);
   18990              : 
   18991        12297 :   gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
   18992        12297 :                              ort, TREE_CODE (expr), &iterator_loops_seq);
   18993        12297 :   gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
   18994        12297 :                                TREE_CODE (expr), &iterator_loops_seq);
   18995        12297 :   if (TREE_CODE (expr) == OACC_UPDATE
   18996        12297 :       && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
   18997              :                           OMP_CLAUSE_IF_PRESENT))
   18998              :     {
   18999              :       /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
   19000              :          clause.  */
   19001          123 :       for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   19002           97 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
   19003           47 :           switch (OMP_CLAUSE_MAP_KIND (c))
   19004              :             {
   19005           14 :             case GOMP_MAP_FORCE_TO:
   19006           14 :               OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
   19007           14 :               break;
   19008           24 :             case GOMP_MAP_FORCE_FROM:
   19009           24 :               OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
   19010           24 :               break;
   19011              :             default:
   19012              :               break;
   19013              :             }
   19014              :     }
   19015        12271 :   else if (TREE_CODE (expr) == OACC_EXIT_DATA
   19016        12271 :            && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
   19017              :                                OMP_CLAUSE_FINALIZE))
   19018              :     {
   19019              :       /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
   19020              :          semantics.  */
   19021           75 :       bool have_clause = false;
   19022          275 :       for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   19023          200 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
   19024          117 :           switch (OMP_CLAUSE_MAP_KIND (c))
   19025              :             {
   19026           45 :             case GOMP_MAP_FROM:
   19027           45 :               OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
   19028           45 :               have_clause = true;
   19029           45 :               break;
   19030           47 :             case GOMP_MAP_RELEASE:
   19031           47 :               OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
   19032           47 :               have_clause = true;
   19033           47 :               break;
   19034              :             case GOMP_MAP_TO_PSET:
   19035              :               /* Fortran arrays with descriptors must map that descriptor when
   19036              :                  doing standalone "attach" operations (in OpenACC).  In that
   19037              :                  case GOMP_MAP_TO_PSET appears by itself with no preceding
   19038              :                  clause (see trans-openmp.cc:gfc_trans_omp_clauses).  */
   19039              :               break;
   19040            2 :             case GOMP_MAP_POINTER:
   19041              :               /* TODO PR92929: we may see these here, but they'll always follow
   19042              :                  one of the clauses above, and will be handled by libgomp as
   19043              :                  one group, so no handling required here.  */
   19044            2 :               gcc_assert (have_clause);
   19045              :               break;
   19046           22 :             case GOMP_MAP_DETACH:
   19047           22 :               OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
   19048           22 :               have_clause = false;
   19049           22 :               break;
   19050              :             case GOMP_MAP_STRUCT:
   19051              :             case GOMP_MAP_STRUCT_UNORD:
   19052           22 :               have_clause = false;
   19053              :               break;
   19054            0 :             default:
   19055            0 :               gcc_unreachable ();
   19056              :             }
   19057              :     }
   19058        12297 :   stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr),
   19059              :                                   iterator_loops_seq);
   19060              : 
   19061        12297 :   gimplify_seq_add_stmt (pre_p, stmt);
   19062        12297 :   *expr_p = NULL_TREE;
   19063        12297 : }
   19064              : 
   19065              : /* A subroutine of gimplify_omp_atomic.  The front end is supposed to have
   19066              :    stabilized the lhs of the atomic operation as *ADDR.  Return true if
   19067              :    EXPR is this stabilized form.  */
   19068              : 
   19069              : static bool
   19070        36791 : goa_lhs_expr_p (tree expr, tree addr)
   19071              : {
   19072              :   /* Also include casts to other type variants.  The C front end is fond
   19073              :      of adding these for e.g. volatile variables.  This is like
   19074              :      STRIP_TYPE_NOPS but includes the main variant lookup.  */
   19075        36791 :   STRIP_USELESS_TYPE_CONVERSION (expr);
   19076              : 
   19077        36791 :   if (INDIRECT_REF_P (expr))
   19078              :     {
   19079         5011 :       expr = TREE_OPERAND (expr, 0);
   19080         5011 :       while (expr != addr
   19081           92 :              && (CONVERT_EXPR_P (expr)
   19082           92 :                  || TREE_CODE (expr) == NON_LVALUE_EXPR)
   19083            0 :              && TREE_CODE (expr) == TREE_CODE (addr)
   19084         5011 :              && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
   19085              :         {
   19086            0 :           expr = TREE_OPERAND (expr, 0);
   19087            0 :           addr = TREE_OPERAND (addr, 0);
   19088              :         }
   19089         5011 :       if (expr == addr)
   19090              :         return true;
   19091           92 :       return (TREE_CODE (addr) == ADDR_EXPR
   19092           62 :               && TREE_CODE (expr) == ADDR_EXPR
   19093           92 :               && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
   19094              :     }
   19095        31780 :   if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
   19096              :     return true;
   19097              :   return false;
   19098              : }
   19099              : 
   19100              : /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR.  If an
   19101              :    expression does not involve the lhs, evaluate it into a temporary.
   19102              :    Return 1 if the lhs appeared as a subexpression, 0 if it did not,
   19103              :    or -1 if an error was encountered.  */
   19104              : 
   19105              : static int
   19106        36791 : goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
   19107              :                     tree lhs_var, tree &target_expr, bool rhs, int depth)
   19108              : {
   19109        36791 :   tree expr = *expr_p;
   19110        36791 :   int saw_lhs = 0;
   19111              : 
   19112        36791 :   if (goa_lhs_expr_p (expr, lhs_addr))
   19113              :     {
   19114         9183 :       if (pre_p)
   19115         8525 :         *expr_p = lhs_var;
   19116         9183 :       return 1;
   19117              :     }
   19118        27608 :   if (is_gimple_val (expr))
   19119              :     return 0;
   19120              : 
   19121              :   /* Maximum depth of lhs in expression is for the
   19122              :      __builtin_clear_padding (...), __builtin_clear_padding (...),
   19123              :      __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs;  */
   19124        17276 :   if (++depth > 7)
   19125           16 :     goto finish;
   19126              : 
   19127        17260 :   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
   19128              :     {
   19129         9652 :     case tcc_binary:
   19130         9652 :     case tcc_comparison:
   19131         9652 :       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
   19132              :                                      lhs_var, target_expr, true, depth);
   19133              :       /* FALLTHRU */
   19134        11699 :     case tcc_unary:
   19135        11699 :       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
   19136              :                                      lhs_var, target_expr, true, depth);
   19137        11699 :       break;
   19138         2982 :     case tcc_expression:
   19139         2982 :       switch (TREE_CODE (expr))
   19140              :         {
   19141          836 :         case TRUTH_ANDIF_EXPR:
   19142          836 :         case TRUTH_ORIF_EXPR:
   19143          836 :         case TRUTH_AND_EXPR:
   19144          836 :         case TRUTH_OR_EXPR:
   19145          836 :         case TRUTH_XOR_EXPR:
   19146          836 :         case BIT_INSERT_EXPR:
   19147          836 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
   19148              :                                          lhs_addr, lhs_var, target_expr, true,
   19149              :                                          depth);
   19150              :           /* FALLTHRU */
   19151          888 :         case TRUTH_NOT_EXPR:
   19152          888 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   19153              :                                          lhs_addr, lhs_var, target_expr, true,
   19154              :                                          depth);
   19155          888 :           break;
   19156          550 :         case MODIFY_EXPR:
   19157          550 :           if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
   19158              :                                             target_expr, true, depth))
   19159              :             break;
   19160          544 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
   19161              :                                          lhs_addr, lhs_var, target_expr, true,
   19162              :                                          depth);
   19163          544 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   19164              :                                          lhs_addr, lhs_var, target_expr, false,
   19165              :                                          depth);
   19166          544 :           break;
   19167              :           /* FALLTHRU */
   19168          164 :         case ADDR_EXPR:
   19169          164 :           if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
   19170              :                                             target_expr, true, depth))
   19171              :             break;
   19172          138 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   19173              :                                          lhs_addr, lhs_var, target_expr, false,
   19174              :                                          depth);
   19175          138 :           break;
   19176              :         case COMPOUND_EXPR:
   19177              :           /* Break out any preevaluations from cp_build_modify_expr.  */
   19178           76 :           for (; TREE_CODE (expr) == COMPOUND_EXPR;
   19179           38 :                expr = TREE_OPERAND (expr, 1))
   19180              :             {
   19181              :               /* Special-case __builtin_clear_padding call before
   19182              :                  __builtin_memcmp.  */
   19183           38 :               if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
   19184              :                 {
   19185            2 :                   tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
   19186            2 :                   if (fndecl
   19187            2 :                       && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
   19188            0 :                       && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
   19189            2 :                       && (!pre_p
   19190            0 :                           || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
   19191              :                                                  lhs_addr, lhs_var,
   19192              :                                                  target_expr, true, depth)))
   19193              :                     {
   19194            0 :                       if (pre_p)
   19195            0 :                         *expr_p = expr;
   19196            0 :                       saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
   19197              :                                                     pre_p, lhs_addr, lhs_var,
   19198              :                                                     target_expr, true, depth);
   19199            0 :                       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
   19200              :                                                      pre_p, lhs_addr, lhs_var,
   19201              :                                                      target_expr, rhs, depth);
   19202            0 :                       return saw_lhs;
   19203              :                     }
   19204              :                 }
   19205              : 
   19206           38 :               if (pre_p)
   19207           35 :                 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
   19208              :             }
   19209           38 :           if (!pre_p)
   19210            3 :             return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
   19211            3 :                                        target_expr, rhs, depth);
   19212           35 :           *expr_p = expr;
   19213           35 :           return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
   19214           35 :                                      target_expr, rhs, depth);
   19215          441 :         case COND_EXPR:
   19216          441 :           if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
   19217              :                                    lhs_var, target_expr, true, depth))
   19218              :             break;
   19219          428 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   19220              :                                          lhs_addr, lhs_var, target_expr, true,
   19221              :                                          depth);
   19222          428 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
   19223              :                                          lhs_addr, lhs_var, target_expr, true,
   19224              :                                          depth);
   19225          428 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
   19226              :                                          lhs_addr, lhs_var, target_expr, true,
   19227              :                                          depth);
   19228          428 :           break;
   19229          880 :         case TARGET_EXPR:
   19230          880 :           if (TARGET_EXPR_INITIAL (expr))
   19231              :             {
   19232          880 :               if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
   19233              :                                                 lhs_var, target_expr, true,
   19234              :                                                 depth))
   19235              :                 break;
   19236          702 :               if (expr == target_expr)
   19237              :                 saw_lhs = 1;
   19238              :               else
   19239              :                 {
   19240          702 :                   saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
   19241              :                                                 pre_p, lhs_addr, lhs_var,
   19242              :                                                 target_expr, true, depth);
   19243          702 :                   if (saw_lhs && target_expr == NULL_TREE && pre_p)
   19244           26 :                     target_expr = expr;
   19245              :                 }
   19246              :             }
   19247              :           break;
   19248              :         default:
   19249              :           break;
   19250              :         }
   19251              :       break;
   19252          556 :     case tcc_reference:
   19253          556 :       if (TREE_CODE (expr) == BIT_FIELD_REF
   19254          490 :           || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
   19255          362 :         saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   19256              :                                        lhs_addr, lhs_var, target_expr, true,
   19257              :                                        depth);
   19258              :       break;
   19259           58 :     case tcc_vl_exp:
   19260           58 :       if (TREE_CODE (expr) == CALL_EXPR)
   19261              :         {
   19262           58 :           if (tree fndecl = get_callee_fndecl (expr))
   19263           58 :             if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING,
   19264              :                                            BUILT_IN_MEMCMP))
   19265              :               {
   19266           56 :                 int nargs = call_expr_nargs (expr);
   19267          224 :                 for (int i = 0; i < nargs; i++)
   19268          168 :                   saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
   19269              :                                                  pre_p, lhs_addr, lhs_var,
   19270              :                                                  target_expr, true, depth);
   19271              :               }
   19272              :         }
   19273              :       break;
   19274              :     default:
   19275              :       break;
   19276              :     }
   19277              : 
   19278        17238 :  finish:
   19279        17238 :   if (saw_lhs == 0 && pre_p)
   19280              :     {
   19281         3485 :       enum gimplify_status gs;
   19282         3485 :       if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
   19283              :         {
   19284            0 :           gimplify_stmt (&expr, pre_p);
   19285            0 :           return saw_lhs;
   19286              :         }
   19287         3485 :       else if (rhs)
   19288         3307 :         gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
   19289              :       else
   19290          178 :         gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
   19291         3485 :       if (gs != GS_ALL_DONE)
   19292        36791 :         saw_lhs = -1;
   19293              :     }
   19294              : 
   19295              :   return saw_lhs;
   19296              : }
   19297              : 
   19298              : /* Gimplify an OMP_ATOMIC statement.  */
   19299              : 
   19300              : static enum gimplify_status
   19301        10236 : gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
   19302              : {
   19303        10236 :   tree addr = TREE_OPERAND (*expr_p, 0);
   19304        10236 :   tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
   19305        10236 :              ? NULL : TREE_OPERAND (*expr_p, 1);
   19306        10236 :   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
   19307        10236 :   tree tmp_load;
   19308        10236 :   gomp_atomic_load *loadstmt;
   19309        10236 :   gomp_atomic_store *storestmt;
   19310        10236 :   tree target_expr = NULL_TREE;
   19311              : 
   19312        10236 :   tmp_load = create_tmp_reg (type);
   19313        10236 :   if (rhs
   19314        10236 :       && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
   19315              :                              true, 0) < 0)
   19316              :     return GS_ERROR;
   19317              : 
   19318        10236 :   if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
   19319              :       != GS_ALL_DONE)
   19320              :     return GS_ERROR;
   19321              : 
   19322        10236 :   loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
   19323        10236 :                                            OMP_ATOMIC_MEMORY_ORDER (*expr_p));
   19324        10236 :   gimplify_seq_add_stmt (pre_p, loadstmt);
   19325        10236 :   if (rhs)
   19326              :     {
   19327              :       /* BIT_INSERT_EXPR is not valid for non-integral bitfield
   19328              :          representatives.  Use BIT_FIELD_REF on the lhs instead.  */
   19329         9055 :       tree rhsarg = rhs;
   19330         9055 :       if (TREE_CODE (rhs) == COND_EXPR)
   19331          428 :         rhsarg = TREE_OPERAND (rhs, 1);
   19332         9055 :       if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
   19333         9055 :           && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
   19334              :         {
   19335           32 :           tree bitpos = TREE_OPERAND (rhsarg, 2);
   19336           32 :           tree op1 = TREE_OPERAND (rhsarg, 1);
   19337           32 :           tree bitsize;
   19338           32 :           tree tmp_store = tmp_load;
   19339           32 :           if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
   19340           12 :             tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
   19341           32 :           if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
   19342           32 :             bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
   19343              :           else
   19344            0 :             bitsize = TYPE_SIZE (TREE_TYPE (op1));
   19345           32 :           gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
   19346           32 :           tree t = build2_loc (EXPR_LOCATION (rhsarg),
   19347              :                                MODIFY_EXPR, void_type_node,
   19348           32 :                                build3_loc (EXPR_LOCATION (rhsarg),
   19349           32 :                                            BIT_FIELD_REF, TREE_TYPE (op1),
   19350              :                                            tmp_store, bitsize, bitpos), op1);
   19351           32 :           if (TREE_CODE (rhs) == COND_EXPR)
   19352           16 :             t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
   19353           16 :                             TREE_OPERAND (rhs, 0), t, void_node);
   19354           32 :           gimplify_and_add (t, pre_p);
   19355           32 :           rhs = tmp_store;
   19356              :         }
   19357         9055 :       bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
   19358         9055 :       if (TREE_CODE (rhs) == COND_EXPR)
   19359          412 :         gimplify_ctxp->allow_rhs_cond_expr = true;
   19360         9055 :       enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
   19361              :                                                is_gimple_val, fb_rvalue);
   19362         9055 :       gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
   19363         9055 :       if (gs != GS_ALL_DONE)
   19364              :         return GS_ERROR;
   19365              :     }
   19366              : 
   19367        10236 :   if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
   19368         1181 :     rhs = tmp_load;
   19369        10236 :   storestmt
   19370        10236 :     = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
   19371        10236 :   if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
   19372              :     {
   19373           37 :       gimple_omp_atomic_set_weak (loadstmt);
   19374           37 :       gimple_omp_atomic_set_weak (storestmt);
   19375              :     }
   19376        10236 :   gimplify_seq_add_stmt (pre_p, storestmt);
   19377        10236 :   switch (TREE_CODE (*expr_p))
   19378              :     {
   19379         2065 :     case OMP_ATOMIC_READ:
   19380         2065 :     case OMP_ATOMIC_CAPTURE_OLD:
   19381         2065 :       *expr_p = tmp_load;
   19382         2065 :       gimple_omp_atomic_set_need_value (loadstmt);
   19383         2065 :       break;
   19384          868 :     case OMP_ATOMIC_CAPTURE_NEW:
   19385          868 :       *expr_p = rhs;
   19386          868 :       gimple_omp_atomic_set_need_value (storestmt);
   19387          868 :       break;
   19388         7303 :     default:
   19389         7303 :       *expr_p = NULL;
   19390         7303 :       break;
   19391              :     }
   19392              : 
   19393              :   return GS_ALL_DONE;
   19394              : }
   19395              : 
   19396              : /* Gimplify a TRANSACTION_EXPR.  This involves gimplification of the
   19397              :    body, and adding some EH bits.  */
   19398              : 
   19399              : static enum gimplify_status
   19400          478 : gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
   19401              : {
   19402          478 :   tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
   19403          478 :   gimple *body_stmt;
   19404          478 :   gtransaction *trans_stmt;
   19405          478 :   gimple_seq body = NULL;
   19406          478 :   int subcode = 0;
   19407              : 
   19408              :   /* Wrap the transaction body in a BIND_EXPR so we have a context
   19409              :      where to put decls for OMP.  */
   19410          478 :   if (TREE_CODE (tbody) != BIND_EXPR)
   19411              :     {
   19412          439 :       tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
   19413          439 :       TREE_SIDE_EFFECTS (bind) = 1;
   19414          439 :       SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
   19415          439 :       TRANSACTION_EXPR_BODY (expr) = bind;
   19416              :     }
   19417              : 
   19418          478 :   push_gimplify_context ();
   19419          478 :   temp = voidify_wrapper_expr (*expr_p, NULL);
   19420              : 
   19421          478 :   body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
   19422          478 :   pop_gimplify_context (body_stmt);
   19423              : 
   19424          478 :   trans_stmt = gimple_build_transaction (body);
   19425          478 :   if (TRANSACTION_EXPR_OUTER (expr))
   19426              :     subcode = GTMA_IS_OUTER;
   19427          447 :   else if (TRANSACTION_EXPR_RELAXED (expr))
   19428           81 :     subcode = GTMA_IS_RELAXED;
   19429          478 :   gimple_transaction_set_subcode (trans_stmt, subcode);
   19430              : 
   19431          478 :   gimplify_seq_add_stmt (pre_p, trans_stmt);
   19432              : 
   19433          478 :   if (temp)
   19434              :     {
   19435           76 :       *expr_p = temp;
   19436           76 :       return GS_OK;
   19437              :     }
   19438              : 
   19439          402 :   *expr_p = NULL_TREE;
   19440          402 :   return GS_ALL_DONE;
   19441              : }
   19442              : 
   19443              : /* Gimplify an OMP_ORDERED construct.  EXPR is the tree version.  BODY
   19444              :    is the OMP_BODY of the original EXPR (which has already been
   19445              :    gimplified so it's not present in the EXPR).
   19446              : 
   19447              :    Return the gimplified GIMPLE_OMP_ORDERED tuple.  */
   19448              : 
   19449              : static gimple *
   19450         1950 : gimplify_omp_ordered (tree expr, gimple_seq body)
   19451              : {
   19452         1950 :   tree c, decls;
   19453         1950 :   int failures = 0;
   19454         1950 :   unsigned int i;
   19455         1950 :   tree source_c = NULL_TREE;
   19456         1950 :   tree sink_c = NULL_TREE;
   19457              : 
   19458         1950 :   if (gimplify_omp_ctxp)
   19459              :     {
   19460         3291 :       for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   19461         1515 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
   19462         1515 :             && gimplify_omp_ctxp->loop_iter_var.is_empty ())
   19463              :           {
   19464           74 :             error_at (OMP_CLAUSE_LOCATION (c),
   19465              :                       "%<ordered%> construct with %qs clause must be "
   19466              :                       "closely nested inside a loop with %<ordered%> clause",
   19467           74 :                       OMP_CLAUSE_DOACROSS_DEPEND (c) ? "depend" : "doacross");
   19468           74 :             failures++;
   19469              :           }
   19470         1441 :         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
   19471         1441 :                  && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
   19472              :           {
   19473          642 :             bool fail = false;
   19474          642 :             sink_c = c;
   19475          642 :             if (OMP_CLAUSE_DECL (c) == NULL_TREE)
   19476           72 :               continue;  /* omp_cur_iteration - 1 */
   19477          570 :             for (decls = OMP_CLAUSE_DECL (c), i = 0;
   19478         3201 :                  decls && TREE_CODE (decls) == TREE_LIST;
   19479         2631 :                  decls = TREE_CHAIN (decls), ++i)
   19480         2631 :               if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
   19481            4 :                 continue;
   19482         5254 :               else if (TREE_VALUE (decls)
   19483         2627 :                        != gimplify_omp_ctxp->loop_iter_var[2 * i])
   19484              :                 {
   19485            8 :                   error_at (OMP_CLAUSE_LOCATION (c),
   19486              :                             "variable %qE is not an iteration "
   19487              :                             "of outermost loop %d, expected %qE",
   19488            8 :                             TREE_VALUE (decls), i + 1,
   19489            8 :                             gimplify_omp_ctxp->loop_iter_var[2 * i]);
   19490            8 :                   fail = true;
   19491            8 :                   failures++;
   19492              :                 }
   19493              :               else
   19494         5238 :                 TREE_VALUE (decls)
   19495         2619 :                   = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
   19496         1136 :             if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
   19497              :               {
   19498           16 :                 error_at (OMP_CLAUSE_LOCATION (c),
   19499              :                           "number of variables in %qs clause with "
   19500              :                           "%<sink%> modifier does not match number of "
   19501              :                           "iteration variables",
   19502           16 :                           OMP_CLAUSE_DOACROSS_DEPEND (c)
   19503              :                           ? "depend" : "doacross");
   19504           16 :                 failures++;
   19505              :               }
   19506              :           }
   19507          799 :         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
   19508          799 :                  && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SOURCE)
   19509              :           {
   19510          475 :             if (source_c)
   19511              :               {
   19512            4 :                 error_at (OMP_CLAUSE_LOCATION (c),
   19513              :                           "more than one %qs clause with %<source%> "
   19514              :                           "modifier on an %<ordered%> construct",
   19515            4 :                           OMP_CLAUSE_DOACROSS_DEPEND (source_c)
   19516              :                           ? "depend" : "doacross");
   19517            4 :                 failures++;
   19518              :               }
   19519              :             else
   19520              :               source_c = c;
   19521              :           }
   19522              :     }
   19523         1950 :   if (source_c && sink_c)
   19524              :     {
   19525            4 :       error_at (OMP_CLAUSE_LOCATION (source_c),
   19526              :                 "%qs clause with %<source%> modifier specified "
   19527              :                 "together with %qs clauses with %<sink%> modifier "
   19528              :                 "on the same construct",
   19529            4 :                 OMP_CLAUSE_DOACROSS_DEPEND (source_c) ? "depend" : "doacross",
   19530            4 :                 OMP_CLAUSE_DOACROSS_DEPEND (sink_c) ? "depend" : "doacross");
   19531            4 :       failures++;
   19532              :     }
   19533              : 
   19534         1950 :   if (failures)
   19535          102 :     return gimple_build_nop ();
   19536         1848 :   return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
   19537              : }
   19538              : 
   19539              : /* Gimplify an OMP_INTEROP statement.  */
   19540              : 
   19541              : static enum gimplify_status
   19542          612 : gimplify_omp_interop (tree *expr_p, gimple_seq *pre_p)
   19543              : {
   19544          612 :   tree expr = *expr_p;
   19545              : 
   19546          612 :   gimplify_scan_omp_clauses (&OMP_INTEROP_CLAUSES (expr), pre_p, ORT_TASK,
   19547              :                              OMP_INTEROP);
   19548          612 :   gimple *stmt = gimple_build_omp_interop (OMP_INTEROP_CLAUSES (expr));
   19549          612 :   gimplify_seq_add_stmt (pre_p, stmt);
   19550          612 :   *expr_p = NULL_TREE;
   19551          612 :   return GS_ALL_DONE;
   19552              : }
   19553              : 
   19554              : /* Callback for walk_tree to find an IFN_GOMP_DISPATCH.  */
   19555              : 
   19556              : static tree
   19557         3100 : find_ifn_gomp_dispatch (tree *tp, int *, void *modify)
   19558              : {
   19559         3100 :   tree t = *tp;
   19560              : 
   19561         3100 :   if (TREE_CODE (t) == CALL_EXPR && CALL_EXPR_IFN (t) == IFN_GOMP_DISPATCH)
   19562         1414 :     return *(tree *) modify ? *(tree *) modify : *tp;
   19563              : 
   19564         2248 :   if (TREE_CODE (t) == MODIFY_EXPR)
   19565          513 :     *(tree *) modify = *tp;
   19566              : 
   19567              :   return NULL_TREE;
   19568              : }
   19569              : 
   19570              : /* Gimplify an OMP_DISPATCH construct.  */
   19571              : 
   19572              : static enum gimplify_status
   19573          852 : gimplify_omp_dispatch (tree *expr_p, gimple_seq *pre_p)
   19574              : {
   19575          852 :   tree expr = *expr_p;
   19576          852 :   gimple_seq body = NULL;
   19577              : 
   19578          852 :   gimplify_scan_omp_clauses (&OMP_DISPATCH_CLAUSES (expr), pre_p, ORT_DISPATCH,
   19579              :                              OMP_DISPATCH);
   19580          852 :   push_gimplify_context ();
   19581              : 
   19582              :   // If device clause, adjust ICV
   19583          852 :   tree device
   19584          852 :     = omp_find_clause (OMP_DISPATCH_CLAUSES (expr), OMP_CLAUSE_DEVICE);
   19585              :   // If no device clause exists but an interop clause with a single list
   19586              :   // item, use it to obtain the device number.
   19587          852 :   if (device)
   19588          272 :     device = OMP_CLAUSE_DEVICE_ID (device);
   19589              :   else
   19590              :     {
   19591          580 :       tree first_interop_obj
   19592          580 :         = omp_find_clause (OMP_DISPATCH_CLAUSES (expr), OMP_CLAUSE_INTEROP);
   19593          580 :       if (first_interop_obj)
   19594           96 :         for (tree c = TREE_CHAIN (first_interop_obj); c; c = TREE_CHAIN (c))
   19595            8 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INTEROP)
   19596              :             {
   19597              :               first_interop_obj = NULL_TREE;
   19598              :               break;
   19599              :             }
   19600           95 :       if (first_interop_obj)
   19601              :         {
   19602           88 :           device = create_tmp_var (integer_type_node);
   19603           88 :           tree c = build_omp_clause (OMP_CLAUSE_LOCATION (first_interop_obj),
   19604              :                                      OMP_CLAUSE_DEVICE);
   19605           88 :           OMP_CLAUSE_DEVICE_ID (c) = device;
   19606           88 :           TREE_CHAIN (c) = TREE_CHAIN (first_interop_obj);
   19607           88 :           TREE_CHAIN (first_interop_obj) = c;
   19608           88 :           first_interop_obj = OMP_CLAUSE_DECL (first_interop_obj);
   19609              :           /* device = omp_get_interop_int (obj, omp_ipr_device_num, NULL);  */
   19610           88 :           tree fn = builtin_decl_explicit (BUILT_IN_OMP_GET_INTEROP_INT);
   19611           88 :           fn = build_call_expr (fn, 3, first_interop_obj,
   19612              :                                 build_int_cst (integer_type_node, -5),
   19613              :                                 null_pointer_node);
   19614           88 :           gimplify_assign (device, fold_convert (integer_type_node, fn), &body);
   19615              :         }
   19616              :     }
   19617          852 :   tree saved_device_icv = NULL_TREE;
   19618          852 :   if (device
   19619          852 :       && (TREE_CODE (device) != INTEGER_CST
   19620          709 :           || !wi::eq_p (wi::to_wide (device), -1 /* omp_initial_device */)))
   19621              :     {
   19622              :       // Save current default-device-var ICV
   19623          360 :       saved_device_icv = create_tmp_var (integer_type_node);
   19624          360 :       tree fn = builtin_decl_explicit (BUILT_IN_OMP_GET_DEFAULT_DEVICE);
   19625          360 :       gcall *call = gimple_build_call (fn, 0);
   19626          360 :       gimple_call_set_lhs (call, saved_device_icv);
   19627          360 :       gimplify_seq_add_stmt (&body, call);
   19628              : 
   19629              :       // Set default device
   19630          360 :       fn = builtin_decl_explicit (BUILT_IN_OMP_SET_DEFAULT_DEVICE);
   19631          360 :       call = gimple_build_call (fn, 1, device);
   19632          360 :       gimplify_seq_add_stmt (&body, call);
   19633              :     }
   19634              : 
   19635              :   // If the novariants and nocontext clauses are not compile-time constants,
   19636              :   // we need to generate code for all possible cases:
   19637              :   //   if (novariants) // implies nocontext
   19638              :   //       base()
   19639              :   //   else if (nocontext)
   19640              :   //       variant1()
   19641              :   //   else
   19642              :   //       variant2()
   19643          852 :   tree *dispatch_body_p = &OMP_DISPATCH_BODY (expr);
   19644          852 :   if (TREE_CODE (*dispatch_body_p) == BIND_EXPR)
   19645           28 :     dispatch_body_p = &BIND_EXPR_BODY (*dispatch_body_p);
   19646          852 :   tree dispatch_body = *dispatch_body_p;
   19647              : 
   19648              :   // Look for IFN_GOMP_DISPATCH and extract the base function call
   19649          852 :   tree base_call_expr = NULL_TREE;
   19650          852 :   if (TREE_CODE (dispatch_body) == STATEMENT_LIST)
   19651          243 :     for (tree_stmt_iterator tsi = tsi_start (dispatch_body); !tsi_end_p (tsi);
   19652          187 :          tsi_next (&tsi))
   19653              :       {
   19654          243 :         tree modify = NULL_TREE;
   19655          243 :         tree stmt = tsi_stmt (tsi);
   19656          243 :         base_call_expr
   19657          243 :           = walk_tree (&stmt, find_ifn_gomp_dispatch, &modify, NULL);
   19658          243 :         if (base_call_expr != NULL_TREE)
   19659              :           break;
   19660              :       }
   19661              :   else
   19662              :     {
   19663          796 :       tree modify = NULL_TREE;
   19664          796 :       base_call_expr
   19665          796 :         = walk_tree (dispatch_body_p, find_ifn_gomp_dispatch, &modify, NULL);
   19666              :     }
   19667          852 :   gcc_assert (base_call_expr != NULL_TREE);
   19668              : 
   19669          852 :   tree dst = NULL_TREE;
   19670          852 :   if (TREE_CODE (base_call_expr) == MODIFY_EXPR)
   19671              :     {
   19672          290 :       dst = TREE_OPERAND (base_call_expr, 0);
   19673          290 :       base_call_expr = TREE_OPERAND (base_call_expr, 1);
   19674              :     }
   19675              : 
   19676          880 :   while (TREE_CODE (base_call_expr) == FLOAT_EXPR
   19677              :          || TREE_CODE (base_call_expr) == CONVERT_EXPR
   19678              :          || TREE_CODE (base_call_expr) == COMPLEX_EXPR
   19679              :          || TREE_CODE (base_call_expr) == INDIRECT_REF
   19680          880 :          || TREE_CODE (base_call_expr) == NOP_EXPR)
   19681           28 :     base_call_expr = TREE_OPERAND (base_call_expr, 0);
   19682              : 
   19683          852 :   gcc_assert (CALL_EXPR_IFN (base_call_expr) == IFN_GOMP_DISPATCH);
   19684          852 :   base_call_expr = CALL_EXPR_ARG (base_call_expr, 0);
   19685              : 
   19686          852 :   tree base_fndecl = get_callee_fndecl (base_call_expr);
   19687          852 :   if (base_fndecl != NULL_TREE)
   19688              :     {
   19689          844 :       if (DECL_VIRTUAL_P (base_fndecl))
   19690              :         {
   19691            6 :           error_at (
   19692            3 :             EXPR_LOCATION (base_call_expr),
   19693              :             "%qD is a virtual function but only a direct call is allowed "
   19694              :             "in a dispatch construct",
   19695            3 :             DECL_NAME (base_fndecl));
   19696              :         }
   19697              : 
   19698              :       /* We are not actually going to expand the variant call or use
   19699              :          the result of omp_get_dynamic candidates here; only check that
   19700              :          it does not trivially resolve to a call to the base function
   19701              :          so that we can avoid some extra work in building code that's
   19702              :          not needed in that case.  */
   19703          844 :       tree construct_context = omp_get_construct_context ();
   19704          844 :       vec<struct omp_variant> all_candidates
   19705          844 :         = omp_declare_variant_candidates (base_fndecl, construct_context);
   19706          844 :       gcc_assert (!all_candidates.is_empty ());
   19707          844 :       vec<struct omp_variant> candidates
   19708          844 :         = omp_get_dynamic_candidates (all_candidates, construct_context);
   19709          844 :       tree variant_fndecl
   19710         1676 :         = (candidates.length () == 1 ? candidates[0].alternative : NULL_TREE);
   19711              : 
   19712          844 :       if (base_fndecl != variant_fndecl
   19713          844 :           && (omp_has_novariants () == -1 || omp_has_nocontext () == -1))
   19714              :         {
   19715           22 :           tree novariants_clause = NULL_TREE, nocontext_clause = NULL_TREE,
   19716           22 :                novariants_cond = NULL_TREE, nocontext_cond = NULL_TREE;
   19717           59 :           for (tree c = OMP_DISPATCH_CLAUSES (expr); c; c = TREE_CHAIN (c))
   19718              :             {
   19719           37 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOVARIANTS
   19720           37 :                   && !integer_zerop (OMP_CLAUSE_NOVARIANTS_EXPR (c)))
   19721              :                 {
   19722           16 :                   gcc_assert (novariants_cond == NULL_TREE);
   19723           16 :                   novariants_clause = c;
   19724           16 :                   novariants_cond = OMP_CLAUSE_NOVARIANTS_EXPR (c);
   19725              :                 }
   19726           21 :               else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOCONTEXT
   19727           21 :                        && !integer_zerop (OMP_CLAUSE_NOCONTEXT_EXPR (c)))
   19728              :                 {
   19729           16 :                   gcc_assert (nocontext_cond == NULL_TREE);
   19730           16 :                   nocontext_clause = c;
   19731           16 :                   nocontext_cond = OMP_CLAUSE_NOCONTEXT_EXPR (c);
   19732              :                 }
   19733              :             }
   19734           22 :           gcc_assert (novariants_cond != NULL_TREE
   19735              :                       || nocontext_cond != NULL_TREE);
   19736              : 
   19737           22 :           enum gimplify_status ret
   19738           22 :             = gimplify_expr (&novariants_cond, &body, NULL, is_gimple_val,
   19739              :                              fb_rvalue);
   19740           22 :           if (ret == GS_ERROR || ret == GS_UNHANDLED)
   19741            0 :             return ret;
   19742           22 :           ret = gimplify_expr (&nocontext_cond, &body, NULL, is_gimple_val,
   19743              :                                fb_rvalue);
   19744           22 :           if (ret == GS_ERROR || ret == GS_UNHANDLED)
   19745              :             return ret;
   19746              : 
   19747           22 :           tree end_label = create_artificial_label (UNKNOWN_LOCATION);
   19748              : 
   19749           22 :           if (novariants_cond != NULL_TREE)
   19750              :             {
   19751           16 :               tree base_label = create_artificial_label (UNKNOWN_LOCATION);
   19752           16 :               tree cond_label = create_artificial_label (UNKNOWN_LOCATION);
   19753           16 :               gcond *novariants_cond_stmt
   19754           16 :                 = gimple_build_cond_from_tree (novariants_cond, base_label,
   19755              :                                                cond_label);
   19756           16 :               gimplify_seq_add_stmt (&body, novariants_cond_stmt);
   19757              : 
   19758           16 :               gimplify_seq_add_stmt (&body, gimple_build_label (base_label));
   19759           16 :               tree base_call_expr2 = copy_node (base_call_expr);
   19760           16 :               base_call_expr2
   19761           16 :                 = build_call_expr_internal_loc (EXPR_LOCATION (base_call_expr2),
   19762              :                                                 IFN_GOMP_DISPATCH,
   19763           16 :                                                 TREE_TYPE (base_call_expr2), 1,
   19764              :                                                 base_call_expr2);
   19765           16 :               if (TREE_CODE (dispatch_body) == MODIFY_EXPR)
   19766              :                 {
   19767           16 :                   base_call_expr2 = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst,
   19768              :                                             base_call_expr2);
   19769              :                 }
   19770           16 :               OMP_CLAUSE_NOVARIANTS_EXPR (novariants_clause)
   19771           16 :                 = boolean_true_node;
   19772           16 :               gimplify_and_add (base_call_expr2, &body);
   19773           16 :               gimplify_seq_add_stmt (&body, gimple_build_goto (end_label));
   19774              : 
   19775           16 :               OMP_CLAUSE_NOVARIANTS_EXPR (novariants_clause)
   19776           16 :                 = boolean_false_node;
   19777           16 :               gimplify_seq_add_stmt (&body, gimple_build_label (cond_label));
   19778              :             }
   19779              : 
   19780           22 :           if (nocontext_cond != NULL_TREE)
   19781              :             {
   19782           16 :               tree variant1_label = create_artificial_label (UNKNOWN_LOCATION);
   19783           16 :               tree variant2_label = create_artificial_label (UNKNOWN_LOCATION);
   19784           16 :               gcond *nocontext_cond_stmt
   19785           16 :                 = gimple_build_cond_from_tree (nocontext_cond, variant1_label,
   19786              :                                                variant2_label);
   19787           16 :               gimplify_seq_add_stmt (&body, nocontext_cond_stmt);
   19788              : 
   19789           32 :               gimplify_seq_add_stmt (&body,
   19790           16 :                                      gimple_build_label (variant1_label));
   19791           16 :               tree variant_call_expr = copy_node (base_call_expr);
   19792           32 :               variant_call_expr = build_call_expr_internal_loc (
   19793           16 :                 EXPR_LOCATION (variant_call_expr), IFN_GOMP_DISPATCH,
   19794           16 :                 TREE_TYPE (variant_call_expr), 1, variant_call_expr);
   19795           16 :               if (TREE_CODE (dispatch_body) == MODIFY_EXPR)
   19796              :                 {
   19797           16 :                   variant_call_expr = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst,
   19798              :                                               variant_call_expr);
   19799              :                 }
   19800           16 :               OMP_CLAUSE_NOCONTEXT_EXPR (nocontext_clause) = boolean_true_node;
   19801           16 :               gimplify_and_add (variant_call_expr, &body);
   19802           16 :               gimplify_seq_add_stmt (&body, gimple_build_goto (end_label));
   19803           16 :               OMP_CLAUSE_NOCONTEXT_EXPR (nocontext_clause) = boolean_false_node;
   19804           32 :               gimplify_seq_add_stmt (&body,
   19805           16 :                                      gimple_build_label (variant2_label));
   19806              :             }
   19807              : 
   19808           22 :           tree variant_call_expr = base_call_expr;
   19809           22 :           variant_call_expr
   19810           22 :             = build_call_expr_internal_loc (EXPR_LOCATION (variant_call_expr),
   19811              :                                             IFN_GOMP_DISPATCH,
   19812           22 :                                             TREE_TYPE (variant_call_expr), 1,
   19813              :                                             variant_call_expr);
   19814           22 :           if (TREE_CODE (dispatch_body) == MODIFY_EXPR)
   19815              :             {
   19816           22 :               variant_call_expr
   19817           22 :                 = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, variant_call_expr);
   19818              :             }
   19819           22 :           gimplify_and_add (variant_call_expr, &body);
   19820           22 :           gimplify_seq_add_stmt (&body, gimple_build_label (end_label));
   19821              :         }
   19822              :       else
   19823          822 :         gimplify_and_add (OMP_DISPATCH_BODY (expr), &body);
   19824              :     }
   19825              :   else
   19826            8 :     gimplify_and_add (OMP_DISPATCH_BODY (expr), &body);
   19827              : 
   19828              :   // Restore default-device-var ICV
   19829          852 :   if (saved_device_icv != NULL_TREE)
   19830              :     {
   19831          360 :       tree fn = builtin_decl_explicit (BUILT_IN_OMP_SET_DEFAULT_DEVICE);
   19832          360 :       gcall *call = gimple_build_call (fn, 1, saved_device_icv);
   19833          360 :       gimplify_seq_add_stmt (&body, call);
   19834              :     }
   19835              : 
   19836              :   // Wrap dispatch body into a bind
   19837          852 :   gimple *bind = gimple_build_bind (NULL_TREE, body, NULL_TREE);
   19838          852 :   pop_gimplify_context (bind);
   19839              : 
   19840              :   // Manually tear down context created by gimplify_scan_omp_clauses to avoid a
   19841              :   // call to gimplify_adjust_omp_clauses
   19842          852 :   gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   19843          852 :   if (ctx != NULL)
   19844              :     {
   19845          852 :       gcc_assert (ctx->code == OMP_DISPATCH);
   19846          852 :       gimplify_omp_ctxp = ctx->outer_context;
   19847          852 :       delete_omp_context (ctx);
   19848              :     }
   19849              : 
   19850              :   // Remove nowait as it has no effect on dispatch (OpenMP 5.2), device as it
   19851              :   // has been handled above, and depend as the front end handled it by inserting
   19852              :   // taskwait.
   19853          852 :   tree *dispatch_clauses_ptr = &OMP_DISPATCH_CLAUSES (expr);
   19854         1445 :   for (tree c = *dispatch_clauses_ptr; c; c = *dispatch_clauses_ptr)
   19855              :     {
   19856          991 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOWAIT
   19857              :           || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
   19858              :           || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE)
   19859              :         {
   19860          398 :           *dispatch_clauses_ptr = OMP_CLAUSE_CHAIN (c);
   19861          398 :           break;
   19862              :         }
   19863              :       else
   19864          593 :         dispatch_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   19865              :     }
   19866              : 
   19867          852 :   gimple *stmt = gimple_build_omp_dispatch (bind, OMP_DISPATCH_CLAUSES (expr));
   19868          852 :   gimplify_seq_add_stmt (pre_p, stmt);
   19869          852 :   *expr_p = NULL_TREE;
   19870          852 :   return GS_ALL_DONE;
   19871              : }
   19872              : 
   19873              : /* Expand a metadirective that has been resolved at gimplification time
   19874              :    into the candidate directive variants in CANDIDATES.  */
   19875              : 
   19876              : static enum gimplify_status
   19877          170 : expand_omp_metadirective (vec<struct omp_variant> &candidates,
   19878              :                           gimple_seq *pre_p)
   19879              : {
   19880          170 :   auto_vec<tree> selectors;
   19881          170 :   auto_vec<tree> directive_labels;
   19882          170 :   auto_vec<gimple_seq> directive_bodies;
   19883          170 :   tree body_label = NULL_TREE;
   19884          170 :   tree end_label = create_artificial_label (UNKNOWN_LOCATION);
   19885              : 
   19886              :   /* Construct bodies for each candidate.  */
   19887          415 :   for (unsigned i = 0; i < candidates.length(); i++)
   19888              :     {
   19889          245 :       struct omp_variant &candidate = candidates[i];
   19890          245 :       gimple_seq body = NULL;
   19891              : 
   19892          245 :       selectors.safe_push (omp_dynamic_cond (candidate.selector,
   19893              :                                              find_supercontext ()));
   19894          245 :       directive_labels.safe_push (create_artificial_label (UNKNOWN_LOCATION));
   19895              : 
   19896          245 :       gimplify_seq_add_stmt (&body,
   19897          245 :                              gimple_build_label (directive_labels.last ()));
   19898          245 :       if (candidate.alternative != NULL_TREE)
   19899          245 :         gimplify_stmt (&candidate.alternative, &body);
   19900          245 :       if (candidate.body != NULL_TREE)
   19901              :         {
   19902           35 :           if (body_label != NULL_TREE)
   19903            0 :             gimplify_seq_add_stmt (&body, gimple_build_goto (body_label));
   19904              :           else
   19905              :             {
   19906           35 :               body_label = create_artificial_label (UNKNOWN_LOCATION);
   19907           35 :               gimplify_seq_add_stmt (&body, gimple_build_label (body_label));
   19908           35 :               gimplify_stmt (&candidate.body, &body);
   19909              :             }
   19910              :         }
   19911              : 
   19912          245 :       directive_bodies.safe_push (body);
   19913              :     }
   19914              : 
   19915          170 :   auto_vec<tree> cond_labels;
   19916              : 
   19917          170 :   cond_labels.safe_push (NULL_TREE);
   19918          376 :   for (unsigned i = 1; i < candidates.length () - 1; i++)
   19919           18 :     cond_labels.safe_push (create_artificial_label (UNKNOWN_LOCATION));
   19920          170 :   if (candidates.length () > 1)
   19921           57 :     cond_labels.safe_push (directive_labels.last ());
   19922              : 
   19923              :   /* Generate conditionals to test each dynamic selector in turn, executing
   19924              :      the directive candidate if successful.  */
   19925          490 :   for (unsigned i = 0; i < candidates.length () - 1; i++)
   19926              :     {
   19927           75 :       if (i != 0)
   19928           18 :         gimplify_seq_add_stmt (pre_p, gimple_build_label (cond_labels [i]));
   19929              : 
   19930           75 :       enum gimplify_status ret = gimplify_expr (&selectors[i], pre_p, NULL,
   19931              :                                                 is_gimple_val, fb_rvalue);
   19932           75 :       if (ret == GS_ERROR || ret == GS_UNHANDLED)
   19933              :         return ret;
   19934              : 
   19935           75 :       gcond *cond_stmt
   19936           75 :         = gimple_build_cond_from_tree (selectors[i], directive_labels[i],
   19937           75 :                                        cond_labels[i + 1]);
   19938              : 
   19939           75 :       gimplify_seq_add_stmt (pre_p, cond_stmt);
   19940           75 :       gimplify_seq_add_seq (pre_p, directive_bodies[i]);
   19941           75 :       gimplify_seq_add_stmt (pre_p, gimple_build_goto (end_label));
   19942              :     }
   19943              : 
   19944          170 :   gimplify_seq_add_seq (pre_p, directive_bodies.last ());
   19945          170 :   gimplify_seq_add_stmt (pre_p, gimple_build_label (end_label));
   19946              : 
   19947          170 :   return GS_ALL_DONE;
   19948          170 : }
   19949              : 
   19950              : /* Expand a variant construct that requires late resolution in the ompdevlow
   19951              :    pass.  It's a bit easier to do this in tree form and then gimplify that,
   19952              :    than to emit gimple.  The output is going to look something like:
   19953              : 
   19954              :      switch_var = OMP_NEXT_VARIANT (0, state);
   19955              :      loop_label:
   19956              :      switch (switch_var)
   19957              :        {
   19958              :        case 1:
   19959              :          if (dynamic_selector_predicate_1)
   19960              :            {
   19961              :              alternative_1;
   19962              :              goto end_label;
   19963              :            }
   19964              :          else
   19965              :            {
   19966              :              switch_var = OMP_NEXT_VARIANT (1, state);
   19967              :              goto loop_label;
   19968              :            }
   19969              :         case 2:
   19970              :           ...
   19971              :         }
   19972              :       end_label:
   19973              : 
   19974              :   OMP_NEXT_VARIANT is a magic cookie that is replaced with the switch variable
   19975              :   index of the next variant to try, after late resolution.  */
   19976              : 
   19977              : static tree
   19978           16 : expand_late_variant_directive (vec<struct omp_variant> all_candidates,
   19979              :                                tree construct_context)
   19980              : {
   19981           16 :   tree body_label = NULL_TREE;
   19982           16 :   tree standalone_body = NULL_TREE;
   19983           16 :   tree loop_label = create_artificial_label (UNKNOWN_LOCATION);
   19984           16 :   tree end_label = create_artificial_label (UNKNOWN_LOCATION);
   19985           32 :   tree selectors = make_tree_vec (all_candidates.length ());
   19986           16 :   tree switch_body = NULL_TREE;
   19987           16 :   tree switch_var = create_tmp_var (integer_type_node, "variant");
   19988           16 :   tree state = tree_cons (NULL_TREE, construct_context, selectors);
   19989              : 
   19990           92 :   for (unsigned int i = 0; i < all_candidates.length (); i++)
   19991              :     {
   19992           76 :       tree selector = all_candidates[i].selector;
   19993           76 :       tree alternative = all_candidates[i].alternative;
   19994           76 :       tree body = all_candidates[i].body;
   19995           76 :       TREE_VEC_ELT (selectors, i) = selector;
   19996              : 
   19997              :       /* Case label.  Numbering is 1-based.  */
   19998           76 :       tree case_val = build_int_cst (integer_type_node, i + 1);
   19999           76 :       tree case_label
   20000           76 :         = build_case_label (case_val, NULL_TREE,
   20001              :                             create_artificial_label (UNKNOWN_LOCATION));
   20002           76 :       append_to_statement_list (case_label, &switch_body);
   20003              : 
   20004              :       /* The actual body of the variant.  */
   20005           76 :       tree variant_body = NULL_TREE;
   20006           76 :       append_to_statement_list (alternative, &variant_body);
   20007              : 
   20008           76 :       if (body != NULL_TREE)
   20009              :         {
   20010            0 :           if (standalone_body == NULL)
   20011              :             {
   20012            0 :               standalone_body = body;
   20013            0 :               body_label = create_artificial_label (UNKNOWN_LOCATION);
   20014              :             }
   20015            0 :           append_to_statement_list (build1 (GOTO_EXPR, void_type_node,
   20016              :                                             body_label),
   20017              :                                     &variant_body);
   20018              :         }
   20019              :       else
   20020           76 :         append_to_statement_list (build1 (GOTO_EXPR, void_type_node,
   20021              :                                           end_label),
   20022              :                                   &variant_body);
   20023              : 
   20024              :       /* If this is a dynamic selector, wrap variant_body with a conditional.
   20025              :          If the predicate doesn't match, the else clause sets switch_var and
   20026              :          jumps to loop_var to try again.  */
   20027           76 :       tree dynamic_selector = omp_dynamic_cond (selector, find_supercontext ());
   20028           76 :       if (dynamic_selector)
   20029              :         {
   20030           20 :           tree else_stmt = NULL_TREE;
   20031           20 :           tree next = build2 (OMP_NEXT_VARIANT, integer_type_node,
   20032              :                               case_val, state);
   20033           20 :           append_to_statement_list (build2 (MODIFY_EXPR, integer_type_node,
   20034              :                                             switch_var, next),
   20035              :                                     &else_stmt);
   20036           20 :           append_to_statement_list (build1 (GOTO_EXPR, void_type_node,
   20037              :                                             loop_label),
   20038              :                                     &else_stmt);
   20039           20 :           variant_body = build3 (COND_EXPR, void_type_node, dynamic_selector,
   20040              :                                  variant_body, else_stmt);
   20041              :         }
   20042           76 :       append_to_statement_list (variant_body, &switch_body);
   20043              :     }
   20044              : 
   20045              :   /* Put it all together.  */
   20046           16 :   tree result = NULL_TREE;
   20047           16 :   tree first = build2 (OMP_NEXT_VARIANT, integer_type_node, integer_zero_node,
   20048              :                        state);
   20049           16 :   append_to_statement_list (build2 (MODIFY_EXPR, integer_type_node,
   20050              :                                     switch_var, first),
   20051              :                             &result);
   20052           16 :   append_to_statement_list (build1 (LABEL_EXPR, void_type_node, loop_label),
   20053              :                             &result);
   20054           16 :   append_to_statement_list (build2 (SWITCH_EXPR, integer_type_node,
   20055              :                                     switch_var, switch_body),
   20056              :                             &result);
   20057           16 :   if (standalone_body)
   20058              :     {
   20059            0 :       append_to_statement_list (build1 (LABEL_EXPR, void_type_node,
   20060              :                                         body_label),
   20061              :                                 &result);
   20062            0 :       append_to_statement_list (standalone_body, &result);
   20063              :     }
   20064           16 :   append_to_statement_list (build1 (LABEL_EXPR, void_type_node, end_label),
   20065              :                             &result);
   20066           16 :   cgraph_node::get (cfun->decl)->has_omp_variant_constructs = 1;
   20067           16 :   return result;
   20068              : }
   20069              : 
   20070              : 
   20071              : /* Gimplify an OMP_METADIRECTIVE construct.   EXPR is the tree version.
   20072              :    The metadirective will be resolved at this point if possible, otherwise
   20073              :    a GIMPLE_OMP_VARIANT_CONSTRUCT is created.  */
   20074              : 
   20075              : static enum gimplify_status
   20076          174 : gimplify_omp_metadirective (tree *expr_p, gimple_seq *pre_p, gimple_seq *,
   20077              :                             bool (*) (tree), fallback_t)
   20078              : {
   20079              :   /* Try to resolve the metadirective.  */
   20080          174 :   tree construct_context = omp_get_construct_context ();
   20081          174 :   vec<struct omp_variant> all_candidates
   20082          174 :     = omp_metadirective_candidates (*expr_p, construct_context);
   20083          174 :   vec<struct omp_variant> candidates
   20084          174 :     = omp_get_dynamic_candidates (all_candidates, construct_context);
   20085          174 :   if (!candidates.is_empty ())
   20086          170 :     return expand_omp_metadirective (candidates, pre_p);
   20087              : 
   20088              :   /* The metadirective cannot be resolved yet.  Turn it into a loop with
   20089              :      a nested switch statement, using OMP_NEXT_VARIANT to set the control
   20090              :      variable for the switch.  */
   20091            4 :   *expr_p = expand_late_variant_directive (all_candidates, construct_context);
   20092            4 :   return GS_OK;
   20093              : }
   20094              : 
   20095              : /* Gimplify an OMP_DECLARE_MAPPER node (by just removing it).  */
   20096              : 
   20097              : static enum gimplify_status
   20098            0 : gimplify_omp_declare_mapper (tree *expr_p)
   20099              : {
   20100            0 :   *expr_p = NULL_TREE;
   20101            0 :   return GS_ALL_DONE;
   20102              : }
   20103              : 
   20104              : /* Convert the GENERIC expression tree *EXPR_P to GIMPLE.  If the
   20105              :    expression produces a value to be used as an operand inside a GIMPLE
   20106              :    statement, the value will be stored back in *EXPR_P.  This value will
   20107              :    be a tree of class tcc_declaration, tcc_constant, tcc_reference or
   20108              :    an SSA_NAME.  The corresponding sequence of GIMPLE statements is
   20109              :    emitted in PRE_P and POST_P.
   20110              : 
   20111              :    Additionally, this process may overwrite parts of the input
   20112              :    expression during gimplification.  Ideally, it should be
   20113              :    possible to do non-destructive gimplification.
   20114              : 
   20115              :    EXPR_P points to the GENERIC expression to convert to GIMPLE.  If
   20116              :       the expression needs to evaluate to a value to be used as
   20117              :       an operand in a GIMPLE statement, this value will be stored in
   20118              :       *EXPR_P on exit.  This happens when the caller specifies one
   20119              :       of fb_lvalue or fb_rvalue fallback flags.
   20120              : 
   20121              :    PRE_P will contain the sequence of GIMPLE statements corresponding
   20122              :        to the evaluation of EXPR and all the side-effects that must
   20123              :        be executed before the main expression.  On exit, the last
   20124              :        statement of PRE_P is the core statement being gimplified.  For
   20125              :        instance, when gimplifying 'if (++a)' the last statement in
   20126              :        PRE_P will be 'if (t.1)' where t.1 is the result of
   20127              :        pre-incrementing 'a'.
   20128              : 
   20129              :    POST_P will contain the sequence of GIMPLE statements corresponding
   20130              :        to the evaluation of all the side-effects that must be executed
   20131              :        after the main expression.  If this is NULL, the post
   20132              :        side-effects are stored at the end of PRE_P.
   20133              : 
   20134              :        The reason why the output is split in two is to handle post
   20135              :        side-effects explicitly.  In some cases, an expression may have
   20136              :        inner and outer post side-effects which need to be emitted in
   20137              :        an order different from the one given by the recursive
   20138              :        traversal.  For instance, for the expression (*p--)++ the post
   20139              :        side-effects of '--' must actually occur *after* the post
   20140              :        side-effects of '++'.  However, gimplification will first visit
   20141              :        the inner expression, so if a separate POST sequence was not
   20142              :        used, the resulting sequence would be:
   20143              : 
   20144              :             1   t.1 = *p
   20145              :             2   p = p - 1
   20146              :             3   t.2 = t.1 + 1
   20147              :             4   *p = t.2
   20148              : 
   20149              :        However, the post-decrement operation in line #2 must not be
   20150              :        evaluated until after the store to *p at line #4, so the
   20151              :        correct sequence should be:
   20152              : 
   20153              :             1   t.1 = *p
   20154              :             2   t.2 = t.1 + 1
   20155              :             3   *p = t.2
   20156              :             4   p = p - 1
   20157              : 
   20158              :        So, by specifying a separate post queue, it is possible
   20159              :        to emit the post side-effects in the correct order.
   20160              :        If POST_P is NULL, an internal queue will be used.  Before
   20161              :        returning to the caller, the sequence POST_P is appended to
   20162              :        the main output sequence PRE_P.
   20163              : 
   20164              :    GIMPLE_TEST_F points to a function that takes a tree T and
   20165              :        returns nonzero if T is in the GIMPLE form requested by the
   20166              :        caller.  The GIMPLE predicates are in gimple.cc.
   20167              : 
   20168              :    FALLBACK tells the function what sort of a temporary we want if
   20169              :        gimplification cannot produce an expression that complies with
   20170              :        GIMPLE_TEST_F.
   20171              : 
   20172              :        fb_none means that no temporary should be generated
   20173              :        fb_rvalue means that an rvalue is OK to generate
   20174              :        fb_lvalue means that an lvalue is OK to generate
   20175              :        fb_either means that either is OK, but an lvalue is preferable.
   20176              :        fb_mayfail means that gimplification may fail (in which case
   20177              :        GS_ERROR will be returned)
   20178              : 
   20179              :    The return value is either GS_ERROR or GS_ALL_DONE, since this
   20180              :    function iterates until EXPR is completely gimplified or an error
   20181              :    occurs.  */
   20182              : 
   20183              : enum gimplify_status
   20184    514139856 : gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   20185              :                bool (*gimple_test_f) (tree), fallback_t fallback)
   20186              : {
   20187    514139856 :   tree tmp;
   20188    514139856 :   gimple_seq internal_pre = NULL;
   20189    514139856 :   gimple_seq internal_post = NULL;
   20190    514139856 :   tree save_expr;
   20191    514139856 :   bool is_statement;
   20192    514139856 :   location_t saved_location;
   20193    514139856 :   enum gimplify_status ret;
   20194    514139856 :   gimple_stmt_iterator pre_last_gsi, post_last_gsi;
   20195    514139856 :   tree label;
   20196              : 
   20197    514139856 :   save_expr = *expr_p;
   20198    514139856 :   if (save_expr == NULL_TREE)
   20199              :     return GS_ALL_DONE;
   20200              : 
   20201              :   /* If we are gimplifying a top-level statement, PRE_P must be valid.  */
   20202    462292913 :   is_statement = gimple_test_f == is_gimple_stmt;
   20203    462292913 :   if (is_statement)
   20204    100380726 :     gcc_assert (pre_p);
   20205              : 
   20206              :   /* Consistency checks.  */
   20207    462292913 :   if (gimple_test_f == is_gimple_reg)
   20208      6219072 :     gcc_assert (fallback & (fb_rvalue | fb_lvalue));
   20209    456073841 :   else if (gimple_test_f == is_gimple_val
   20210    336277208 :            || gimple_test_f == is_gimple_call_addr
   20211    320132746 :            || gimple_test_f == is_gimple_condexpr_for_cond
   20212    314563629 :            || gimple_test_f == is_gimple_mem_rhs
   20213    314419805 :            || gimple_test_f == is_gimple_mem_rhs_or_call
   20214    303267902 :            || gimple_test_f == is_gimple_reg_rhs
   20215    302658207 :            || gimple_test_f == is_gimple_reg_rhs_or_call
   20216    231157112 :            || gimple_test_f == is_gimple_asm_val
   20217    231117426 :            || gimple_test_f == is_gimple_mem_ref_addr)
   20218    240124708 :     gcc_assert (fallback & fb_rvalue);
   20219    215949133 :   else if (gimple_test_f == is_gimple_min_lval
   20220    185991507 :            || gimple_test_f == is_gimple_lvalue)
   20221     83126709 :     gcc_assert (fallback & fb_lvalue);
   20222    132822424 :   else if (gimple_test_f == is_gimple_addressable)
   20223     32441698 :     gcc_assert (fallback & fb_either);
   20224    100380726 :   else if (gimple_test_f == is_gimple_stmt)
   20225    100380726 :     gcc_assert (fallback == fb_none);
   20226              :   else
   20227              :     {
   20228              :       /* We should have recognized the GIMPLE_TEST_F predicate to
   20229              :          know what kind of fallback to use in case a temporary is
   20230              :          needed to hold the value or address of *EXPR_P.  */
   20231            0 :       gcc_unreachable ();
   20232              :     }
   20233              : 
   20234              :   /* We used to check the predicate here and return immediately if it
   20235              :      succeeds.  This is wrong; the design is for gimplification to be
   20236              :      idempotent, and for the predicates to only test for valid forms, not
   20237              :      whether they are fully simplified.  */
   20238    462292913 :   if (pre_p == NULL)
   20239            0 :     pre_p = &internal_pre;
   20240              : 
   20241    462292913 :   if (post_p == NULL)
   20242    185706736 :     post_p = &internal_post;
   20243              : 
   20244              :   /* Remember the last statements added to PRE_P and POST_P.  Every
   20245              :      new statement added by the gimplification helpers needs to be
   20246              :      annotated with location information.  To centralize the
   20247              :      responsibility, we remember the last statement that had been
   20248              :      added to both queues before gimplifying *EXPR_P.  If
   20249              :      gimplification produces new statements in PRE_P and POST_P, those
   20250              :      statements will be annotated with the same location information
   20251              :      as *EXPR_P.  */
   20252    462292913 :   pre_last_gsi = gsi_last (*pre_p);
   20253    462292913 :   post_last_gsi = gsi_last (*post_p);
   20254              : 
   20255    462292913 :   saved_location = input_location;
   20256    462292913 :   if (save_expr != error_mark_node
   20257    462292913 :       && EXPR_HAS_LOCATION (*expr_p))
   20258    173015986 :     input_location = EXPR_LOCATION (*expr_p);
   20259              : 
   20260              :   /* Loop over the specific gimplifiers until the toplevel node
   20261              :      remains the same.  */
   20262    480203642 :   do
   20263              :     {
   20264              :       /* Strip away as many useless type conversions as possible
   20265              :          at the toplevel.  */
   20266    480203642 :       STRIP_USELESS_TYPE_CONVERSION (*expr_p);
   20267              : 
   20268              :       /* Remember the expr.  */
   20269    480203642 :       save_expr = *expr_p;
   20270              : 
   20271              :       /* Die, die, die, my darling.  */
   20272    480203642 :       if (error_operand_p (save_expr))
   20273              :         {
   20274              :           ret = GS_ERROR;
   20275              :           break;
   20276              :         }
   20277              : 
   20278              :       /* Do any language-specific gimplification.  */
   20279    480199974 :       ret = ((enum gimplify_status)
   20280    480199974 :              lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
   20281    480199974 :       if (ret == GS_OK)
   20282              :         {
   20283     27756025 :           if (*expr_p == NULL_TREE)
   20284              :             break;
   20285     27756025 :           if (*expr_p != save_expr)
   20286      4645252 :             continue;
   20287              :         }
   20288    452443949 :       else if (ret != GS_UNHANDLED)
   20289              :         break;
   20290              : 
   20291              :       /* Make sure that all the cases set 'ret' appropriately.  */
   20292    474988470 :       ret = GS_UNHANDLED;
   20293    474988470 :       switch (TREE_CODE (*expr_p))
   20294              :         {
   20295              :           /* First deal with the special cases.  */
   20296              : 
   20297      1125563 :         case POSTINCREMENT_EXPR:
   20298      1125563 :         case POSTDECREMENT_EXPR:
   20299      1125563 :         case PREINCREMENT_EXPR:
   20300      1125563 :         case PREDECREMENT_EXPR:
   20301      2251126 :           ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
   20302              :                                         fallback != fb_none,
   20303      1125563 :                                         TREE_TYPE (*expr_p));
   20304      1125563 :           break;
   20305              : 
   20306       589180 :         case VIEW_CONVERT_EXPR:
   20307       589180 :           if ((fallback & fb_rvalue)
   20308       589054 :               && is_gimple_reg_type (TREE_TYPE (*expr_p))
   20309      1002731 :               && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
   20310              :             {
   20311       401801 :               ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   20312              :                                    post_p, is_gimple_val, fb_rvalue);
   20313       401801 :               recalculate_side_effects (*expr_p);
   20314       401801 :               break;
   20315              :             }
   20316              :           /* Fallthru.  */
   20317              : 
   20318     29894761 :         case ARRAY_REF:
   20319     29894761 :         case ARRAY_RANGE_REF:
   20320     29894761 :         case REALPART_EXPR:
   20321     29894761 :         case IMAGPART_EXPR:
   20322     29894761 :         case COMPONENT_REF:
   20323     29894761 :           ret = gimplify_compound_lval (expr_p, pre_p, post_p,
   20324              :                                         fallback ? fallback : fb_rvalue);
   20325     29894761 :           break;
   20326              : 
   20327      6186388 :         case COND_EXPR:
   20328      6186388 :           ret = gimplify_cond_expr (expr_p, pre_p, fallback);
   20329              : 
   20330              :           /* C99 code may assign to an array in a structure value of a
   20331              :              conditional expression, and this has undefined behavior
   20332              :              only on execution, so create a temporary if an lvalue is
   20333              :              required.  */
   20334      6186388 :           if (fallback == fb_lvalue)
   20335              :             {
   20336            7 :               *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
   20337            7 :               mark_addressable (*expr_p);
   20338            7 :               ret = GS_OK;
   20339              :             }
   20340              :           break;
   20341              : 
   20342     16669640 :         case CALL_EXPR:
   20343     16669640 :           ret = gimplify_call_expr (expr_p, pre_p, fallback);
   20344              : 
   20345              :           /* C99 code may assign to an array in a structure returned
   20346              :              from a function, and this has undefined behavior only on
   20347              :              execution, so create a temporary if an lvalue is
   20348              :              required.  */
   20349     16669640 :           if (fallback == fb_lvalue)
   20350              :             {
   20351        17299 :               *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
   20352        17299 :               mark_addressable (*expr_p);
   20353        17299 :               ret = GS_OK;
   20354              :             }
   20355              :           break;
   20356              : 
   20357            0 :         case TREE_LIST:
   20358            0 :           gcc_unreachable ();
   20359              : 
   20360            0 :         case OMP_ARRAY_SECTION:
   20361            0 :           gcc_unreachable ();
   20362              : 
   20363       478764 :         case COMPOUND_EXPR:
   20364       478764 :           ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
   20365       478764 :           break;
   20366              : 
   20367        37190 :         case COMPOUND_LITERAL_EXPR:
   20368        37190 :           ret = gimplify_compound_literal_expr (expr_p, pre_p,
   20369              :                                                 gimple_test_f, fallback);
   20370        37190 :           break;
   20371              : 
   20372     49865939 :         case MODIFY_EXPR:
   20373     49865939 :         case INIT_EXPR:
   20374     49865939 :           ret = gimplify_modify_expr (expr_p, pre_p, post_p,
   20375              :                                       fallback != fb_none);
   20376     49865939 :           break;
   20377              : 
   20378       112201 :         case TRUTH_ANDIF_EXPR:
   20379       112201 :         case TRUTH_ORIF_EXPR:
   20380       112201 :           {
   20381              :             /* Preserve the original type of the expression and the
   20382              :                source location of the outer expression.  */
   20383       112201 :             tree org_type = TREE_TYPE (*expr_p);
   20384       112201 :             *expr_p = gimple_boolify (*expr_p);
   20385       112201 :             *expr_p = build3_loc (input_location, COND_EXPR,
   20386              :                                   org_type, *expr_p,
   20387              :                                   fold_convert_loc
   20388              :                                     (input_location,
   20389              :                                      org_type, boolean_true_node),
   20390              :                                   fold_convert_loc
   20391              :                                     (input_location,
   20392              :                                      org_type, boolean_false_node));
   20393       112201 :             ret = GS_OK;
   20394       112201 :             break;
   20395              :           }
   20396              : 
   20397       229981 :         case TRUTH_NOT_EXPR:
   20398       229981 :           {
   20399       229981 :             tree type = TREE_TYPE (*expr_p);
   20400              :             /* The parsers are careful to generate TRUTH_NOT_EXPR
   20401              :                only with operands that are always zero or one.
   20402              :                We do not fold here but handle the only interesting case
   20403              :                manually, as fold may re-introduce the TRUTH_NOT_EXPR.  */
   20404       229981 :             *expr_p = gimple_boolify (*expr_p);
   20405       229981 :             if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
   20406       229981 :               *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
   20407       229981 :                                     TREE_TYPE (*expr_p),
   20408       229981 :                                     TREE_OPERAND (*expr_p, 0));
   20409              :             else
   20410            0 :               *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
   20411            0 :                                     TREE_TYPE (*expr_p),
   20412            0 :                                     TREE_OPERAND (*expr_p, 0),
   20413            0 :                                     build_int_cst (TREE_TYPE (*expr_p), 1));
   20414       229981 :             if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
   20415         4905 :               *expr_p = fold_convert_loc (input_location, type, *expr_p);
   20416              :             ret = GS_OK;
   20417              :             break;
   20418              :           }
   20419              : 
   20420     32518792 :         case ADDR_EXPR:
   20421     32518792 :           ret = gimplify_addr_expr (expr_p, pre_p, post_p);
   20422     32518792 :           break;
   20423              : 
   20424         5521 :         case ANNOTATE_EXPR:
   20425         5521 :           {
   20426         5521 :             tree cond = TREE_OPERAND (*expr_p, 0);
   20427         5521 :             tree kind = TREE_OPERAND (*expr_p, 1);
   20428         5521 :             tree data = TREE_OPERAND (*expr_p, 2);
   20429         5521 :             tree type = TREE_TYPE (cond);
   20430         5521 :             if (!INTEGRAL_TYPE_P (type))
   20431              :               {
   20432            0 :                 *expr_p = cond;
   20433            0 :                 ret = GS_OK;
   20434            0 :                 break;
   20435              :               }
   20436         5521 :             tree tmp = create_tmp_var (type);
   20437         5521 :             gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
   20438         5521 :             gcall *call
   20439         5521 :               = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
   20440         5521 :             gimple_call_set_lhs (call, tmp);
   20441         5521 :             gimplify_seq_add_stmt (pre_p, call);
   20442         5521 :             *expr_p = tmp;
   20443         5521 :             ret = GS_ALL_DONE;
   20444         5521 :             break;
   20445              :           }
   20446              : 
   20447        51131 :         case VA_ARG_EXPR:
   20448        51131 :           ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
   20449        51131 :           break;
   20450              : 
   20451     17119553 :         CASE_CONVERT:
   20452     17119553 :           if (IS_EMPTY_STMT (*expr_p))
   20453              :             {
   20454              :               ret = GS_ALL_DONE;
   20455              :               break;
   20456              :             }
   20457              : 
   20458     15407451 :           if (VOID_TYPE_P (TREE_TYPE (*expr_p))
   20459     15407451 :               || fallback == fb_none)
   20460              :             {
   20461              :               /* Just strip a conversion to void (or in void context) and
   20462              :                  try again.  */
   20463      2582776 :               *expr_p = TREE_OPERAND (*expr_p, 0);
   20464      2582776 :               ret = GS_OK;
   20465      2582776 :               break;
   20466              :             }
   20467              : 
   20468     12824675 :           ret = gimplify_conversion (expr_p);
   20469     12824675 :           if (ret == GS_ERROR)
   20470              :             break;
   20471     12824675 :           if (*expr_p != save_expr)
   20472              :             break;
   20473              :           /* FALLTHRU */
   20474              : 
   20475     12951073 :         case FIX_TRUNC_EXPR:
   20476              :           /* unary_expr: ... | '(' cast ')' val | ...  */
   20477     12951073 :           ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   20478              :                                is_gimple_val, fb_rvalue);
   20479     12951073 :           recalculate_side_effects (*expr_p);
   20480     12951073 :           break;
   20481              : 
   20482      6148330 :         case INDIRECT_REF:
   20483      6148330 :           {
   20484      6148330 :             bool volatilep = TREE_THIS_VOLATILE (*expr_p);
   20485      6148330 :             bool notrap = TREE_THIS_NOTRAP (*expr_p);
   20486      6148330 :             tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
   20487              : 
   20488      6148330 :             *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
   20489      6148330 :             if (*expr_p != save_expr)
   20490              :               {
   20491              :                 ret = GS_OK;
   20492              :                 break;
   20493              :               }
   20494              : 
   20495      6130482 :             ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   20496              :                                  is_gimple_reg, fb_rvalue);
   20497      6130482 :             if (ret == GS_ERROR)
   20498              :               break;
   20499              : 
   20500      6130479 :             recalculate_side_effects (*expr_p);
   20501     12260958 :             *expr_p = fold_build2_loc (input_location, MEM_REF,
   20502      6130479 :                                        TREE_TYPE (*expr_p),
   20503      6130479 :                                        TREE_OPERAND (*expr_p, 0),
   20504              :                                        build_int_cst (saved_ptr_type, 0));
   20505      6130479 :             TREE_THIS_VOLATILE (*expr_p) = volatilep;
   20506      6130479 :             TREE_THIS_NOTRAP (*expr_p) = notrap;
   20507      6130479 :             ret = GS_OK;
   20508      6130479 :             break;
   20509              :           }
   20510              : 
   20511              :         /* We arrive here through the various re-gimplifcation paths.  */
   20512     15642207 :         case MEM_REF:
   20513              :           /* First try re-folding the whole thing.  */
   20514     15642207 :           tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
   20515              :                              TREE_OPERAND (*expr_p, 0),
   20516              :                              TREE_OPERAND (*expr_p, 1));
   20517     15642207 :           if (tmp)
   20518              :             {
   20519         6578 :               REF_REVERSE_STORAGE_ORDER (tmp)
   20520         3289 :                 = REF_REVERSE_STORAGE_ORDER (*expr_p);
   20521         3289 :               *expr_p = tmp;
   20522         3289 :               recalculate_side_effects (*expr_p);
   20523         3289 :               ret = GS_OK;
   20524         3289 :               break;
   20525              :             }
   20526              :           /* Avoid re-gimplifying the address operand if it is already
   20527              :              in suitable form.  Re-gimplifying would mark the address
   20528              :              operand addressable.  Always gimplify when not in SSA form
   20529              :              as we still may have to gimplify decls with value-exprs.  */
   20530     15638918 :           if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
   20531     16648569 :               || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
   20532              :             {
   20533     14684378 :               ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   20534              :                                    is_gimple_mem_ref_addr, fb_rvalue);
   20535     14684378 :               if (ret == GS_ERROR)
   20536              :                 break;
   20537              :             }
   20538     15638918 :           recalculate_side_effects (*expr_p);
   20539     15638918 :           ret = GS_ALL_DONE;
   20540     15638918 :           break;
   20541              : 
   20542              :         /* Constants need not be gimplified.  */
   20543     43921159 :         case INTEGER_CST:
   20544     43921159 :         case REAL_CST:
   20545     43921159 :         case FIXED_CST:
   20546     43921159 :         case STRING_CST:
   20547     43921159 :         case COMPLEX_CST:
   20548     43921159 :         case VECTOR_CST:
   20549              :           /* Drop the overflow flag on constants, we do not want
   20550              :              that in the GIMPLE IL.  */
   20551     43921159 :           if (TREE_OVERFLOW_P (*expr_p))
   20552          900 :             *expr_p = drop_tree_overflow (*expr_p);
   20553              :           ret = GS_ALL_DONE;
   20554              :           break;
   20555              : 
   20556       117197 :         case CONST_DECL:
   20557              :           /* If we require an lvalue, such as for ADDR_EXPR, retain the
   20558              :              CONST_DECL node.  Otherwise the decl is replaceable by its
   20559              :              value.  */
   20560              :           /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either.  */
   20561       117197 :           if (fallback & fb_lvalue)
   20562              :             ret = GS_ALL_DONE;
   20563              :           else
   20564              :             {
   20565         3236 :               *expr_p = DECL_INITIAL (*expr_p);
   20566         3236 :               ret = GS_OK;
   20567              :             }
   20568              :           break;
   20569              : 
   20570      6523205 :         case DECL_EXPR:
   20571      6523205 :           ret = gimplify_decl_expr (expr_p, pre_p);
   20572      6523205 :           break;
   20573              : 
   20574      5927825 :         case BIND_EXPR:
   20575      5927825 :           ret = gimplify_bind_expr (expr_p, pre_p);
   20576      5927825 :           break;
   20577              : 
   20578       203308 :         case LOOP_EXPR:
   20579       203308 :           ret = gimplify_loop_expr (expr_p, pre_p);
   20580       203308 :           break;
   20581              : 
   20582        49515 :         case SWITCH_EXPR:
   20583        49515 :           ret = gimplify_switch_expr (expr_p, pre_p);
   20584        49515 :           break;
   20585              : 
   20586         3069 :         case EXIT_EXPR:
   20587         3069 :           ret = gimplify_exit_expr (expr_p);
   20588         3069 :           break;
   20589              : 
   20590      1097331 :         case GOTO_EXPR:
   20591              :           /* If the target is not LABEL, then it is a computed jump
   20592              :              and the target needs to be gimplified.  */
   20593      1097331 :           if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
   20594              :             {
   20595         1118 :               ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
   20596              :                                    NULL, is_gimple_val, fb_rvalue);
   20597         1118 :               if (ret == GS_ERROR)
   20598              :                 break;
   20599              :             }
   20600      2194660 :           gimplify_seq_add_stmt (pre_p,
   20601      1097330 :                           gimple_build_goto (GOTO_DESTINATION (*expr_p)));
   20602      1097330 :           ret = GS_ALL_DONE;
   20603      1097330 :           break;
   20604              : 
   20605       102465 :         case PREDICT_EXPR:
   20606       409860 :           gimplify_seq_add_stmt (pre_p,
   20607       102465 :                         gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
   20608       102465 :                                               PREDICT_EXPR_OUTCOME (*expr_p)));
   20609       102465 :           ret = GS_ALL_DONE;
   20610       102465 :           break;
   20611              : 
   20612      2544320 :         case LABEL_EXPR:
   20613      2544320 :           ret = gimplify_label_expr (expr_p, pre_p);
   20614      2544320 :           label = LABEL_EXPR_LABEL (*expr_p);
   20615      2544320 :           gcc_assert (decl_function_context (label) == current_function_decl);
   20616              : 
   20617              :           /* If the label is used in a goto statement, or address of the label
   20618              :              is taken, we need to unpoison all variables that were seen so far.
   20619              :              Doing so would prevent us from reporting a false positives.  */
   20620      2544320 :           if (asan_poisoned_variables
   20621         4391 :               && asan_used_labels != NULL
   20622         1325 :               && asan_used_labels->contains (label)
   20623      2545232 :               && !gimplify_omp_ctxp)
   20624          904 :             asan_poison_variables (asan_poisoned_variables, false, pre_p);
   20625              :           break;
   20626              : 
   20627      1034044 :         case CASE_LABEL_EXPR:
   20628      1034044 :           ret = gimplify_case_label_expr (expr_p, pre_p);
   20629              : 
   20630      1034044 :           if (gimplify_ctxp->live_switch_vars)
   20631      1033857 :             asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
   20632              :                                    pre_p);
   20633              :           break;
   20634              : 
   20635      2201605 :         case RETURN_EXPR:
   20636      2201605 :           ret = gimplify_return_expr (*expr_p, pre_p);
   20637      2201605 :           break;
   20638              : 
   20639       950341 :         case CONSTRUCTOR:
   20640              :           /* Don't reduce this in place; let gimplify_init_constructor work its
   20641              :              magic.  Buf if we're just elaborating this for side effects, just
   20642              :              gimplify any element that has side-effects.  */
   20643       950341 :           if (fallback == fb_none)
   20644              :             {
   20645          358 :               unsigned HOST_WIDE_INT ix;
   20646          358 :               tree val;
   20647          358 :               tree temp = NULL_TREE;
   20648          375 :               FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
   20649           17 :                 if (TREE_SIDE_EFFECTS (val))
   20650            4 :                   append_to_statement_list (val, &temp);
   20651              : 
   20652          358 :               *expr_p = temp;
   20653          358 :               ret = temp ? GS_OK : GS_ALL_DONE;
   20654              :             }
   20655              :           /* C99 code may assign to an array in a constructed
   20656              :              structure or union, and this has undefined behavior only
   20657              :              on execution, so create a temporary if an lvalue is
   20658              :              required.  */
   20659       949983 :           else if (fallback == fb_lvalue)
   20660              :             {
   20661           11 :               *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
   20662           11 :               mark_addressable (*expr_p);
   20663           11 :               ret = GS_OK;
   20664              :             }
   20665              :           else
   20666              :             ret = GS_ALL_DONE;
   20667              :           break;
   20668              : 
   20669              :           /* The following are special cases that are not handled by the
   20670              :              original GIMPLE grammar.  */
   20671              : 
   20672              :           /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
   20673              :              eliminated.  */
   20674       439210 :         case SAVE_EXPR:
   20675       439210 :           ret = gimplify_save_expr (expr_p, pre_p, post_p);
   20676       439210 :           break;
   20677              : 
   20678       377723 :         case BIT_FIELD_REF:
   20679       377723 :           ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   20680              :                                post_p, is_gimple_lvalue, fb_either);
   20681       377723 :           recalculate_side_effects (*expr_p);
   20682       377723 :           break;
   20683              : 
   20684         2475 :         case TARGET_MEM_REF:
   20685         2475 :           {
   20686         2475 :             enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
   20687              : 
   20688         2475 :             if (TMR_BASE (*expr_p))
   20689         2475 :               r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
   20690              :                                   post_p, is_gimple_mem_ref_addr, fb_either);
   20691         2475 :             if (TMR_INDEX (*expr_p))
   20692         1203 :               r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
   20693              :                                   post_p, is_gimple_val, fb_rvalue);
   20694         2475 :             if (TMR_INDEX2 (*expr_p))
   20695           78 :               r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
   20696              :                                   post_p, is_gimple_val, fb_rvalue);
   20697              :             /* TMR_STEP and TMR_OFFSET are always integer constants.  */
   20698         2475 :             ret = MIN (r0, r1);
   20699              :           }
   20700              :           break;
   20701              : 
   20702            0 :         case NON_LVALUE_EXPR:
   20703              :           /* This should have been stripped above.  */
   20704            0 :           gcc_unreachable ();
   20705              : 
   20706        98207 :         case ASM_EXPR:
   20707        98207 :           ret = gimplify_asm_expr (expr_p, pre_p, post_p);
   20708        98207 :           break;
   20709              : 
   20710       484720 :         case TRY_FINALLY_EXPR:
   20711       484720 :         case TRY_CATCH_EXPR:
   20712       484720 :           {
   20713       484720 :             gimple_seq eval, cleanup;
   20714       484720 :             gtry *try_;
   20715              : 
   20716              :             /* Calls to destructors are generated automatically in FINALLY/CATCH
   20717              :                block. They should have location as UNKNOWN_LOCATION. However,
   20718              :                gimplify_call_expr will reset these call stmts to input_location
   20719              :                if it finds stmt's location is unknown. To prevent resetting for
   20720              :                destructors, we set the input_location to unknown.
   20721              :                Note that this only affects the destructor calls in FINALLY/CATCH
   20722              :                block, and will automatically reset to its original value by the
   20723              :                end of gimplify_expr.  */
   20724       484720 :             input_location = UNKNOWN_LOCATION;
   20725       484720 :             eval = cleanup = NULL;
   20726       484720 :             gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
   20727       484720 :             bool save_in_handler_expr = gimplify_ctxp->in_handler_expr;
   20728       484720 :             if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
   20729       484720 :                 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
   20730              :               {
   20731          226 :                 gimple_seq n = NULL, e = NULL;
   20732          226 :                 gimplify_ctxp->in_handler_expr = true;
   20733          226 :                 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
   20734              :                                                 0), &n);
   20735          226 :                 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
   20736              :                                                 1), &e);
   20737          226 :                 if (!gimple_seq_empty_p (n) || !gimple_seq_empty_p (e))
   20738              :                   {
   20739          220 :                     geh_else *stmt = gimple_build_eh_else (n, e);
   20740          220 :                     gimple_seq_add_stmt (&cleanup, stmt);
   20741              :                   }
   20742              :               }
   20743              :             else
   20744              :               {
   20745       484494 :                 gimplify_ctxp->in_handler_expr = true;
   20746       484494 :                 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
   20747              :               }
   20748       484720 :             gimplify_ctxp->in_handler_expr = save_in_handler_expr;
   20749              :             /* Don't create bogus GIMPLE_TRY with empty cleanup.  */
   20750       484720 :             if (gimple_seq_empty_p (cleanup))
   20751              :               {
   20752        26989 :                 gimple_seq_add_seq (pre_p, eval);
   20753        26989 :                 ret = GS_ALL_DONE;
   20754        26989 :                 break;
   20755              :               }
   20756       457731 :             try_ = gimple_build_try (eval, cleanup,
   20757       457731 :                                      TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
   20758              :                                      ? GIMPLE_TRY_FINALLY
   20759              :                                      : GIMPLE_TRY_CATCH);
   20760       457731 :             if (EXPR_HAS_LOCATION (save_expr))
   20761       837408 :               gimple_set_location (try_, EXPR_LOCATION (save_expr));
   20762        39027 :             else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
   20763        28580 :               gimple_set_location (try_, saved_location);
   20764       457731 :             if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
   20765       163920 :               gimple_try_set_catch_is_cleanup (try_,
   20766       163920 :                                                TRY_CATCH_IS_CLEANUP (*expr_p));
   20767       457731 :             gimplify_seq_add_stmt (pre_p, try_);
   20768       457731 :             ret = GS_ALL_DONE;
   20769       457731 :             break;
   20770              :           }
   20771              : 
   20772      5105785 :         case CLEANUP_POINT_EXPR:
   20773      5105785 :           ret = gimplify_cleanup_point_expr (expr_p, pre_p);
   20774      5105785 :           break;
   20775              : 
   20776       790742 :         case TARGET_EXPR:
   20777       790742 :           ret = gimplify_target_expr (expr_p, pre_p, post_p);
   20778       790742 :           break;
   20779              : 
   20780        39954 :         case CATCH_EXPR:
   20781        39954 :           {
   20782        39954 :             gimple *c;
   20783        39954 :             gimple_seq handler = NULL;
   20784        39954 :             gimplify_and_add (CATCH_BODY (*expr_p), &handler);
   20785        39954 :             c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
   20786        39954 :             gimplify_seq_add_stmt (pre_p, c);
   20787        39954 :             ret = GS_ALL_DONE;
   20788        39954 :             break;
   20789              :           }
   20790              : 
   20791         4632 :         case EH_FILTER_EXPR:
   20792         4632 :           {
   20793         4632 :             gimple *ehf;
   20794         4632 :             gimple_seq failure = NULL;
   20795              : 
   20796         4632 :             gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
   20797         4632 :             ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
   20798         4632 :             copy_warning (ehf, *expr_p);
   20799         4632 :             gimplify_seq_add_stmt (pre_p, ehf);
   20800         4632 :             ret = GS_ALL_DONE;
   20801         4632 :             break;
   20802              :           }
   20803              : 
   20804        49032 :         case OBJ_TYPE_REF:
   20805        49032 :           {
   20806        49032 :             enum gimplify_status r0, r1;
   20807        49032 :             r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
   20808              :                                 post_p, is_gimple_val, fb_rvalue);
   20809        49032 :             r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
   20810              :                                 post_p, is_gimple_val, fb_rvalue);
   20811        49032 :             TREE_SIDE_EFFECTS (*expr_p) = 0;
   20812        49032 :             ret = MIN (r0, r1);
   20813              :           }
   20814              :           break;
   20815              : 
   20816        40854 :         case LABEL_DECL:
   20817              :           /* We get here when taking the address of a label.  We mark
   20818              :              the label as "forced"; meaning it can never be removed and
   20819              :              it is a potential target for any computed goto.  */
   20820        40854 :           FORCED_LABEL (*expr_p) = 1;
   20821        40854 :           ret = GS_ALL_DONE;
   20822        40854 :           break;
   20823              : 
   20824      8453338 :         case STATEMENT_LIST:
   20825      8453338 :           ret = gimplify_statement_list (expr_p, pre_p);
   20826      8453338 :           break;
   20827              : 
   20828         1740 :         case WITH_SIZE_EXPR:
   20829         1740 :           {
   20830         2022 :             gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   20831              :                            post_p == &internal_post ? NULL : post_p,
   20832              :                            gimple_test_f, fallback);
   20833         1740 :             gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
   20834              :                            is_gimple_val, fb_rvalue);
   20835         1740 :             ret = GS_ALL_DONE;
   20836              :           }
   20837         1740 :           break;
   20838              : 
   20839    107873281 :         case VAR_DECL:
   20840    107873281 :         case PARM_DECL:
   20841    107873281 :           ret = gimplify_var_or_parm_decl (expr_p);
   20842    107873281 :           break;
   20843              : 
   20844       335402 :         case RESULT_DECL:
   20845              :           /* When within an OMP context, notice uses of variables.  */
   20846       335402 :           if (gimplify_omp_ctxp)
   20847         1412 :             omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
   20848              :           /* Handlers can refer to the function result; if that has been
   20849              :              moved, we need to track it.  */
   20850       335402 :           if (gimplify_ctxp->in_handler_expr && gimplify_ctxp->return_temp)
   20851           64 :             *expr_p = gimplify_ctxp->return_temp;
   20852              :           ret = GS_ALL_DONE;
   20853              :           break;
   20854              : 
   20855            0 :         case DEBUG_EXPR_DECL:
   20856            0 :           gcc_unreachable ();
   20857              : 
   20858      2434223 :         case DEBUG_BEGIN_STMT:
   20859      4868446 :           gimplify_seq_add_stmt (pre_p,
   20860              :                                  gimple_build_debug_begin_stmt
   20861      2434223 :                                  (TREE_BLOCK (*expr_p),
   20862      2434223 :                                   EXPR_LOCATION (*expr_p)));
   20863      2434223 :           ret = GS_ALL_DONE;
   20864      2434223 :           *expr_p = NULL;
   20865      2434223 :           break;
   20866              : 
   20867              :         case SSA_NAME:
   20868              :           /* Allow callbacks into the gimplifier during optimization.  */
   20869              :           ret = GS_ALL_DONE;
   20870              :           break;
   20871              : 
   20872        18244 :         case OMP_PARALLEL:
   20873        18244 :           gimplify_omp_parallel (expr_p, pre_p);
   20874        18244 :           ret = GS_ALL_DONE;
   20875        18244 :           break;
   20876              : 
   20877         3855 :         case OMP_TASK:
   20878         3855 :           gimplify_omp_task (expr_p, pre_p);
   20879         3855 :           ret = GS_ALL_DONE;
   20880         3855 :           break;
   20881              : 
   20882        10683 :         case OMP_SIMD:
   20883        10683 :           {
   20884              :             /* Temporarily disable into_ssa, as scan_omp_simd
   20885              :                which calls copy_gimple_seq_and_replace_locals can't deal
   20886              :                with SSA_NAMEs defined outside of the body properly.  */
   20887        10683 :             bool saved_into_ssa = gimplify_ctxp->into_ssa;
   20888        10683 :             gimplify_ctxp->into_ssa = false;
   20889        10683 :             ret = gimplify_omp_for (expr_p, pre_p);
   20890        10683 :             gimplify_ctxp->into_ssa = saved_into_ssa;
   20891        10683 :             break;
   20892              :           }
   20893              : 
   20894        47403 :         case OMP_FOR:
   20895        47403 :         case OMP_DISTRIBUTE:
   20896        47403 :         case OMP_TASKLOOP:
   20897        47403 :         case OMP_TILE:
   20898        47403 :         case OMP_UNROLL:
   20899        47403 :         case OACC_LOOP:
   20900        47403 :           ret = gimplify_omp_for (expr_p, pre_p);
   20901        47403 :           break;
   20902              : 
   20903         1056 :         case OMP_LOOP:
   20904         1056 :           ret = gimplify_omp_loop (expr_p, pre_p);
   20905         1056 :           break;
   20906              : 
   20907          665 :         case OACC_CACHE:
   20908          665 :           gimplify_oacc_cache (expr_p, pre_p);
   20909          665 :           ret = GS_ALL_DONE;
   20910          665 :           break;
   20911              : 
   20912          254 :         case OACC_DECLARE:
   20913          254 :           gimplify_oacc_declare (expr_p, pre_p);
   20914          254 :           ret = GS_ALL_DONE;
   20915          254 :           break;
   20916              : 
   20917        39824 :         case OACC_HOST_DATA:
   20918        39824 :         case OACC_DATA:
   20919        39824 :         case OACC_KERNELS:
   20920        39824 :         case OACC_PARALLEL:
   20921        39824 :         case OACC_SERIAL:
   20922        39824 :         case OMP_SCOPE:
   20923        39824 :         case OMP_SECTIONS:
   20924        39824 :         case OMP_SINGLE:
   20925        39824 :         case OMP_TARGET:
   20926        39824 :         case OMP_TARGET_DATA:
   20927        39824 :         case OMP_TEAMS:
   20928        39824 :           gimplify_omp_workshare (expr_p, pre_p);
   20929        39824 :           ret = GS_ALL_DONE;
   20930        39824 :           break;
   20931              : 
   20932        12297 :         case OACC_ENTER_DATA:
   20933        12297 :         case OACC_EXIT_DATA:
   20934        12297 :         case OACC_UPDATE:
   20935        12297 :         case OMP_TARGET_UPDATE:
   20936        12297 :         case OMP_TARGET_ENTER_DATA:
   20937        12297 :         case OMP_TARGET_EXIT_DATA:
   20938        12297 :           gimplify_omp_target_update (expr_p, pre_p);
   20939        12297 :           ret = GS_ALL_DONE;
   20940        12297 :           break;
   20941              : 
   20942         7043 :         case OMP_SECTION:
   20943         7043 :         case OMP_STRUCTURED_BLOCK:
   20944         7043 :         case OMP_MASTER:
   20945         7043 :         case OMP_MASKED:
   20946         7043 :         case OMP_ORDERED:
   20947         7043 :         case OMP_CRITICAL:
   20948         7043 :         case OMP_SCAN:
   20949         7043 :           {
   20950         7043 :             gimple_seq body = NULL;
   20951         7043 :             gimple *g;
   20952         7043 :             bool saved_in_omp_construct = in_omp_construct;
   20953              : 
   20954         7043 :             in_omp_construct = true;
   20955         7043 :             gimplify_and_add (OMP_BODY (*expr_p), &body);
   20956         7043 :             in_omp_construct = saved_in_omp_construct;
   20957         7043 :             switch (TREE_CODE (*expr_p))
   20958              :               {
   20959         1271 :               case OMP_SECTION:
   20960         1271 :                 g = gimple_build_omp_section (body);
   20961         1271 :                 break;
   20962          791 :               case OMP_STRUCTURED_BLOCK:
   20963          791 :                 g = gimple_build_omp_structured_block (body);
   20964          791 :                 break;
   20965          874 :               case OMP_MASTER:
   20966          874 :                 g = gimple_build_omp_master (body);
   20967          874 :                 break;
   20968         1950 :               case OMP_ORDERED:
   20969         1950 :                 g = gimplify_omp_ordered (*expr_p, body);
   20970         1950 :                 if (OMP_BODY (*expr_p) == NULL_TREE
   20971         1950 :                     && gimple_code (g) == GIMPLE_OMP_ORDERED)
   20972         1025 :                   gimple_omp_ordered_standalone (g);
   20973              :                 break;
   20974          493 :               case OMP_MASKED:
   20975          493 :                 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
   20976              :                                            pre_p, ORT_WORKSHARE, OMP_MASKED);
   20977          493 :                 gimplify_adjust_omp_clauses (pre_p, body,
   20978              :                                              &OMP_MASKED_CLAUSES (*expr_p),
   20979              :                                              OMP_MASKED);
   20980          986 :                 g = gimple_build_omp_masked (body,
   20981          493 :                                              OMP_MASKED_CLAUSES (*expr_p));
   20982          493 :                 break;
   20983          546 :               case OMP_CRITICAL:
   20984          546 :                 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
   20985              :                                            pre_p, ORT_WORKSHARE, OMP_CRITICAL);
   20986          546 :                 gimplify_adjust_omp_clauses (pre_p, body,
   20987              :                                              &OMP_CRITICAL_CLAUSES (*expr_p),
   20988              :                                              OMP_CRITICAL);
   20989         1638 :                 g = gimple_build_omp_critical (body,
   20990          546 :                                                OMP_CRITICAL_NAME (*expr_p),
   20991          546 :                                                OMP_CRITICAL_CLAUSES (*expr_p));
   20992          546 :                 break;
   20993         1118 :               case OMP_SCAN:
   20994         1118 :                 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
   20995              :                                            pre_p, ORT_WORKSHARE, OMP_SCAN);
   20996         1118 :                 gimplify_adjust_omp_clauses (pre_p, body,
   20997              :                                              &OMP_SCAN_CLAUSES (*expr_p),
   20998              :                                              OMP_SCAN);
   20999         1118 :                 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
   21000         1118 :                 break;
   21001            0 :               default:
   21002            0 :                 gcc_unreachable ();
   21003              :               }
   21004         7043 :             gimplify_seq_add_stmt (pre_p, g);
   21005         7043 :             ret = GS_ALL_DONE;
   21006         7043 :             break;
   21007              :           }
   21008              : 
   21009          611 :         case OMP_TASKGROUP:
   21010          611 :           {
   21011          611 :             gimple_seq body = NULL;
   21012              : 
   21013          611 :             tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
   21014          611 :             bool saved_in_omp_construct = in_omp_construct;
   21015          611 :             gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
   21016              :                                        OMP_TASKGROUP);
   21017          611 :             gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
   21018              : 
   21019          611 :             in_omp_construct = true;
   21020          611 :             gimplify_and_add (OMP_BODY (*expr_p), &body);
   21021          611 :             in_omp_construct = saved_in_omp_construct;
   21022          611 :             gimple_seq cleanup = NULL;
   21023          611 :             tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
   21024          611 :             gimple *g = gimple_build_call (fn, 0);
   21025          611 :             gimple_seq_add_stmt (&cleanup, g);
   21026          611 :             g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
   21027          611 :             body = NULL;
   21028          611 :             gimple_seq_add_stmt (&body, g);
   21029          611 :             g = gimple_build_omp_taskgroup (body, *pclauses);
   21030          611 :             gimplify_seq_add_stmt (pre_p, g);
   21031          611 :             ret = GS_ALL_DONE;
   21032          611 :             break;
   21033              :           }
   21034              : 
   21035          612 :         case OMP_INTEROP:
   21036          612 :           ret = gimplify_omp_interop (expr_p, pre_p);
   21037          612 :           break;
   21038        10236 :         case OMP_ATOMIC:
   21039        10236 :         case OMP_ATOMIC_READ:
   21040        10236 :         case OMP_ATOMIC_CAPTURE_OLD:
   21041        10236 :         case OMP_ATOMIC_CAPTURE_NEW:
   21042        10236 :           ret = gimplify_omp_atomic (expr_p, pre_p);
   21043        10236 :           break;
   21044              : 
   21045          852 :         case OMP_DISPATCH:
   21046          852 :           ret = gimplify_omp_dispatch (expr_p, pre_p);
   21047          852 :           break;
   21048              : 
   21049          174 :         case OMP_METADIRECTIVE:
   21050          174 :           ret = gimplify_omp_metadirective (expr_p, pre_p, post_p,
   21051              :                                             gimple_test_f, fallback);
   21052          174 :           break;
   21053              : 
   21054           36 :         case OMP_NEXT_VARIANT:
   21055           36 :         case OMP_TARGET_DEVICE_MATCHES:
   21056              :           /* These are placeholders for constants.  There's nothing to do with
   21057              :              them here but we must mark the containing function as needing
   21058              :              to run the ompdevlow pass to resolve them.  Note that
   21059              :              OMP_TARGET_DEVICE_MATCHES, in particular, may be inserted by
   21060              :              the front ends.  */
   21061           36 :           cgraph_node::get (cfun->decl)->has_omp_variant_constructs = 1;
   21062           36 :           ret = GS_ALL_DONE;
   21063           36 :           break;
   21064              : 
   21065            0 :         case OMP_DECLARE_MAPPER:
   21066            0 :           ret = gimplify_omp_declare_mapper (expr_p);
   21067            0 :           break;
   21068              : 
   21069          478 :         case TRANSACTION_EXPR:
   21070          478 :           ret = gimplify_transaction (expr_p, pre_p);
   21071          478 :           break;
   21072              : 
   21073       288345 :         case TRUTH_AND_EXPR:
   21074       288345 :         case TRUTH_OR_EXPR:
   21075       288345 :         case TRUTH_XOR_EXPR:
   21076       288345 :           {
   21077       288345 :             tree orig_type = TREE_TYPE (*expr_p);
   21078       288345 :             tree new_type, xop0, xop1;
   21079       288345 :             *expr_p = gimple_boolify (*expr_p);
   21080       288345 :             new_type = TREE_TYPE (*expr_p);
   21081       288345 :             if (!useless_type_conversion_p (orig_type, new_type))
   21082              :               {
   21083         1146 :                 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
   21084         1146 :                 ret = GS_OK;
   21085         1146 :                 break;
   21086              :               }
   21087              : 
   21088              :           /* Boolified binary truth expressions are semantically equivalent
   21089              :              to bitwise binary expressions.  Canonicalize them to the
   21090              :              bitwise variant.  */
   21091       287199 :             switch (TREE_CODE (*expr_p))
   21092              :               {
   21093       170544 :               case TRUTH_AND_EXPR:
   21094       170544 :                 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
   21095       170544 :                 break;
   21096       116052 :               case TRUTH_OR_EXPR:
   21097       116052 :                 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
   21098       116052 :                 break;
   21099          603 :               case TRUTH_XOR_EXPR:
   21100          603 :                 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
   21101          603 :                 break;
   21102              :               default:
   21103              :                 break;
   21104              :               }
   21105              :             /* Now make sure that operands have compatible type to
   21106              :                expression's new_type.  */
   21107       287199 :             xop0 = TREE_OPERAND (*expr_p, 0);
   21108       287199 :             xop1 = TREE_OPERAND (*expr_p, 1);
   21109       287199 :             if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
   21110          326 :               TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
   21111              :                                                             new_type,
   21112              :                                                             xop0);
   21113       287199 :             if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
   21114          366 :               TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
   21115              :                                                             new_type,
   21116              :                                                             xop1);
   21117              :             /* Continue classified as tcc_binary.  */
   21118       287199 :             goto expr_2;
   21119              :           }
   21120              : 
   21121        10495 :         case VEC_COND_EXPR:
   21122        10495 :           goto expr_3;
   21123              : 
   21124       133421 :         case VEC_PERM_EXPR:
   21125              :           /* Classified as tcc_expression.  */
   21126       133421 :           goto expr_3;
   21127              : 
   21128           48 :         case BIT_INSERT_EXPR:
   21129              :           /* Argument 3 is a constant.  */
   21130           48 :           goto expr_2;
   21131              : 
   21132      3816518 :         case POINTER_PLUS_EXPR:
   21133      3816518 :           {
   21134      3816518 :             enum gimplify_status r0, r1;
   21135      3816518 :             r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   21136              :                                 post_p, is_gimple_val, fb_rvalue);
   21137      3816518 :             r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
   21138              :                                 post_p, is_gimple_val, fb_rvalue);
   21139      3816518 :             recalculate_side_effects (*expr_p);
   21140      3816518 :             ret = MIN (r0, r1);
   21141              :             break;
   21142              :           }
   21143              : 
   21144     44061201 :         default:
   21145     44061201 :           switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
   21146              :             {
   21147      6952528 :             case tcc_comparison:
   21148              :               /* Handle comparison of objects of non scalar mode aggregates
   21149              :                  with a call to memcmp.  It would be nice to only have to do
   21150              :                  this for variable-sized objects, but then we'd have to allow
   21151              :                  the same nest of reference nodes we allow for MODIFY_EXPR and
   21152              :                  that's too complex.
   21153              : 
   21154              :                  Compare scalar mode aggregates as scalar mode values.  Using
   21155              :                  memcmp for them would be very inefficient at best, and is
   21156              :                  plain wrong if bitfields are involved.  */
   21157      6952528 :               if (error_operand_p (TREE_OPERAND (*expr_p, 1)))
   21158              :                 ret = GS_ERROR;
   21159              :               else
   21160              :                 {
   21161      6952528 :                   tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
   21162              : 
   21163              :                   /* Vector comparisons need no boolification.  */
   21164      6952528 :                   if (TREE_CODE (type) == VECTOR_TYPE)
   21165        12585 :                     goto expr_2;
   21166      6939943 :                   else if (!AGGREGATE_TYPE_P (type))
   21167              :                     {
   21168      6939927 :                       tree org_type = TREE_TYPE (*expr_p);
   21169      6939927 :                       *expr_p = gimple_boolify (*expr_p);
   21170      6939927 :                       if (!useless_type_conversion_p (org_type,
   21171      6939927 :                                                       TREE_TYPE (*expr_p)))
   21172              :                         {
   21173        56437 :                           *expr_p = fold_convert_loc (input_location,
   21174              :                                                       org_type, *expr_p);
   21175        56437 :                           ret = GS_OK;
   21176              :                         }
   21177              :                       else
   21178      6883490 :                         goto expr_2;
   21179              :                     }
   21180           16 :                   else if (SCALAR_INT_MODE_P (TYPE_MODE (type)))
   21181           16 :                     ret = gimplify_scalar_mode_aggregate_compare (expr_p);
   21182              :                   else
   21183            0 :                     ret = gimplify_variable_sized_compare (expr_p);
   21184              :                 }
   21185              :               break;
   21186              : 
   21187              :             /* If *EXPR_P does not need to be special-cased, handle it
   21188              :                according to its class.  */
   21189      1590150 :             case tcc_unary:
   21190      1590150 :               ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   21191              :                                    post_p, is_gimple_val, fb_rvalue);
   21192      1590150 :               break;
   21193              : 
   21194     26298005 :             case tcc_binary:
   21195     26298005 :             expr_2:
   21196     26298005 :               {
   21197     26298005 :                 enum gimplify_status r0, r1;
   21198              : 
   21199     26298005 :                 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   21200              :                                     post_p, is_gimple_val, fb_rvalue);
   21201     26298005 :                 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
   21202              :                                     post_p, is_gimple_val, fb_rvalue);
   21203              : 
   21204     26298005 :                 ret = MIN (r0, r1);
   21205              :                 break;
   21206              :               }
   21207              : 
   21208       143916 :             expr_3:
   21209       143916 :               {
   21210       143916 :                 enum gimplify_status r0, r1, r2;
   21211              : 
   21212       143916 :                 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   21213              :                                     post_p, is_gimple_val, fb_rvalue);
   21214       143916 :                 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
   21215              :                                     post_p, is_gimple_val, fb_rvalue);
   21216       143916 :                 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
   21217              :                                     post_p, is_gimple_val, fb_rvalue);
   21218              : 
   21219       143916 :                 ret = MIN (MIN (r0, r1), r2);
   21220              :                 break;
   21221              :               }
   21222              : 
   21223     16403840 :             case tcc_declaration:
   21224     16403840 :             case tcc_constant:
   21225     16403840 :               ret = GS_ALL_DONE;
   21226     16403840 :               goto dont_recalculate;
   21227              : 
   21228            0 :             default:
   21229            0 :               gcc_unreachable ();
   21230              :             }
   21231              : 
   21232     28088524 :           recalculate_side_effects (*expr_p);
   21233              : 
   21234    474988470 :         dont_recalculate:
   21235              :           break;
   21236              :         }
   21237              : 
   21238    474988470 :       gcc_assert (*expr_p || ret != GS_OK);
   21239              :     }
   21240    479633722 :   while (ret == GS_OK);
   21241              : 
   21242              :   /* If we encountered an error_mark somewhere nested inside, either
   21243              :      stub out the statement or propagate the error back out.  */
   21244    462292913 :   if (ret == GS_ERROR)
   21245              :     {
   21246         5309 :       if (is_statement)
   21247         4074 :         *expr_p = NULL;
   21248         5309 :       goto out;
   21249              :     }
   21250              : 
   21251              :   /* This was only valid as a return value from the langhook, which
   21252              :      we handled.  Make sure it doesn't escape from any other context.  */
   21253    462287604 :   gcc_assert (ret != GS_UNHANDLED);
   21254              : 
   21255    462287604 :   if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
   21256              :     {
   21257              :       /* We aren't looking for a value, and we don't have a valid
   21258              :          statement.  If it doesn't have side-effects, throw it away.
   21259              :          We can also get here with code such as "*&&L;", where L is
   21260              :          a LABEL_DECL that is marked as FORCED_LABEL.  */
   21261      1175324 :       if (TREE_CODE (*expr_p) == LABEL_DECL
   21262      1175324 :           || !TREE_SIDE_EFFECTS (*expr_p))
   21263      1174308 :         *expr_p = NULL;
   21264         1016 :       else if (!TREE_THIS_VOLATILE (*expr_p))
   21265              :         {
   21266              :           /* This is probably a _REF that contains something nested that
   21267              :              has side effects.  Recurse through the operands to find it.  */
   21268            0 :           enum tree_code code = TREE_CODE (*expr_p);
   21269              : 
   21270            0 :           switch (code)
   21271              :             {
   21272            0 :             case COMPONENT_REF:
   21273            0 :             case REALPART_EXPR:
   21274            0 :             case IMAGPART_EXPR:
   21275            0 :             case VIEW_CONVERT_EXPR:
   21276            0 :               gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   21277              :                              gimple_test_f, fallback);
   21278            0 :               break;
   21279              : 
   21280            0 :             case ARRAY_REF:
   21281            0 :             case ARRAY_RANGE_REF:
   21282            0 :               gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   21283              :                              gimple_test_f, fallback);
   21284            0 :               gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
   21285              :                              gimple_test_f, fallback);
   21286            0 :               break;
   21287              : 
   21288            0 :             default:
   21289              :                /* Anything else with side-effects must be converted to
   21290              :                   a valid statement before we get here.  */
   21291            0 :               gcc_unreachable ();
   21292              :             }
   21293              : 
   21294            0 :           *expr_p = NULL;
   21295              :         }
   21296         1016 :       else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
   21297          966 :                && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
   21298         1969 :                && !is_empty_type (TREE_TYPE (*expr_p)))
   21299              :         {
   21300              :           /* Historically, the compiler has treated a bare reference
   21301              :              to a non-BLKmode volatile lvalue as forcing a load.  */
   21302          893 :           tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
   21303              : 
   21304              :           /* Normally, we do not want to create a temporary for a
   21305              :              TREE_ADDRESSABLE type because such a type should not be
   21306              :              copied by bitwise-assignment.  However, we make an
   21307              :              exception here, as all we are doing here is ensuring that
   21308              :              we read the bytes that make up the type.  We use
   21309              :              create_tmp_var_raw because create_tmp_var will abort when
   21310              :              given a TREE_ADDRESSABLE type.  */
   21311          893 :           tree tmp = create_tmp_var_raw (type, "vol");
   21312          893 :           gimple_add_tmp_var (tmp);
   21313          893 :           gimplify_assign (tmp, *expr_p, pre_p);
   21314          893 :           *expr_p = NULL;
   21315              :         }
   21316              :       else
   21317              :         /* We can't do anything useful with a volatile reference to
   21318              :            an incomplete type, so just throw it away.  Likewise for
   21319              :            a BLKmode type, since any implicit inner load should
   21320              :            already have been turned into an explicit one by the
   21321              :            gimplification process.  */
   21322          123 :         *expr_p = NULL;
   21323              :     }
   21324              : 
   21325              :   /* If we are gimplifying at the statement level, we're done.  Tack
   21326              :      everything together and return.  */
   21327    462287604 :   if (fallback == fb_none || is_statement)
   21328              :     {
   21329              :       /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
   21330              :          it out for GC to reclaim it.  */
   21331    100376652 :       *expr_p = NULL_TREE;
   21332              : 
   21333    100376652 :       if (!gimple_seq_empty_p (internal_pre)
   21334    100376652 :           || !gimple_seq_empty_p (internal_post))
   21335              :         {
   21336           19 :           gimplify_seq_add_seq (&internal_pre, internal_post);
   21337           19 :           gimplify_seq_add_seq (pre_p, internal_pre);
   21338              :         }
   21339              : 
   21340              :       /* The result of gimplifying *EXPR_P is going to be the last few
   21341              :          statements in *PRE_P and *POST_P.  Add location information
   21342              :          to all the statements that were added by the gimplification
   21343              :          helpers.  */
   21344    100376652 :       if (!gimple_seq_empty_p (*pre_p))
   21345     97898463 :         annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
   21346              : 
   21347    100376652 :       if (!gimple_seq_empty_p (*post_p))
   21348           19 :         annotate_all_with_location_after (*post_p, post_last_gsi,
   21349              :                                           input_location);
   21350              : 
   21351    100376652 :       goto out;
   21352              :     }
   21353              : 
   21354              : #ifdef ENABLE_GIMPLE_CHECKING
   21355    361910952 :   if (*expr_p)
   21356              :     {
   21357    361910952 :       enum tree_code code = TREE_CODE (*expr_p);
   21358              :       /* These expressions should already be in gimple IR form.  */
   21359    361910952 :       gcc_assert (code != MODIFY_EXPR
   21360              :                   && code != ASM_EXPR
   21361              :                   && code != BIND_EXPR
   21362              :                   && code != CATCH_EXPR
   21363              :                   && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
   21364              :                   && code != EH_FILTER_EXPR
   21365              :                   && code != GOTO_EXPR
   21366              :                   && code != LABEL_EXPR
   21367              :                   && code != LOOP_EXPR
   21368              :                   && code != SWITCH_EXPR
   21369              :                   && code != TRY_FINALLY_EXPR
   21370              :                   && code != EH_ELSE_EXPR
   21371              :                   && code != OACC_PARALLEL
   21372              :                   && code != OACC_KERNELS
   21373              :                   && code != OACC_SERIAL
   21374              :                   && code != OACC_DATA
   21375              :                   && code != OACC_HOST_DATA
   21376              :                   && code != OACC_DECLARE
   21377              :                   && code != OACC_UPDATE
   21378              :                   && code != OACC_ENTER_DATA
   21379              :                   && code != OACC_EXIT_DATA
   21380              :                   && code != OACC_CACHE
   21381              :                   && code != OMP_CRITICAL
   21382              :                   && code != OMP_FOR
   21383              :                   && code != OACC_LOOP
   21384              :                   && code != OMP_MASTER
   21385              :                   && code != OMP_MASKED
   21386              :                   && code != OMP_TASKGROUP
   21387              :                   && code != OMP_ORDERED
   21388              :                   && code != OMP_PARALLEL
   21389              :                   && code != OMP_SCAN
   21390              :                   && code != OMP_SECTIONS
   21391              :                   && code != OMP_SECTION
   21392              :                   && code != OMP_STRUCTURED_BLOCK
   21393              :                   && code != OMP_SINGLE
   21394              :                   && code != OMP_SCOPE
   21395              :                   && code != OMP_DISPATCH);
   21396              :     }
   21397              : #endif
   21398              : 
   21399              :   /* Otherwise we're gimplifying a subexpression, so the resulting
   21400              :      value is interesting.  If it's a valid operand that matches
   21401              :      GIMPLE_TEST_F, we're done. Unless we are handling some
   21402              :      post-effects internally; if that's the case, we need to copy into
   21403              :      a temporary before adding the post-effects to POST_P.  */
   21404    361910952 :   if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
   21405    336057452 :     goto out;
   21406              : 
   21407              :   /* Otherwise, we need to create a new temporary for the gimplified
   21408              :      expression.  */
   21409              : 
   21410              :   /* We can't return an lvalue if we have an internal postqueue.  The
   21411              :      object the lvalue refers to would (probably) be modified by the
   21412              :      postqueue; we need to copy the value out first, which means an
   21413              :      rvalue.  */
   21414     25853500 :   if ((fallback & fb_lvalue)
   21415       575905 :       && gimple_seq_empty_p (internal_post)
   21416     26429405 :       && is_gimple_addressable (*expr_p))
   21417              :     {
   21418              :       /* An lvalue will do.  Take the address of the expression, store it
   21419              :          in a temporary, and replace the expression with an INDIRECT_REF of
   21420              :          that temporary.  */
   21421           15 :       tree ref_alias_type = reference_alias_ptr_type (*expr_p);
   21422           15 :       unsigned int ref_align = get_object_alignment (*expr_p);
   21423           15 :       tree ref_type = TREE_TYPE (*expr_p);
   21424           15 :       tmp = build_fold_addr_expr_loc (input_location, *expr_p);
   21425           15 :       gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
   21426           15 :       if (TYPE_ALIGN (ref_type) != ref_align)
   21427            1 :         ref_type = build_aligned_type (ref_type, ref_align);
   21428           15 :       *expr_p = build2 (MEM_REF, ref_type,
   21429              :                         tmp, build_zero_cst (ref_alias_type));
   21430              :     }
   21431     25853485 :   else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
   21432              :     {
   21433              :       /* An rvalue will do.  Assign the gimplified expression into a
   21434              :          new temporary TMP and replace the original expression with
   21435              :          TMP.  First, make sure that the expression has a type so that
   21436              :          it can be assigned into a temporary.  */
   21437     25853477 :       gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
   21438     25853477 :       *expr_p = get_formal_tmp_var (*expr_p, pre_p);
   21439              :     }
   21440              :   else
   21441              :     {
   21442              : #ifdef ENABLE_GIMPLE_CHECKING
   21443            8 :       if (!(fallback & fb_mayfail))
   21444              :         {
   21445            0 :           fprintf (stderr, "gimplification failed:\n");
   21446            0 :           print_generic_expr (stderr, *expr_p);
   21447            0 :           debug_tree (*expr_p);
   21448            0 :           internal_error ("gimplification failed");
   21449              :         }
   21450              : #endif
   21451            8 :       gcc_assert (fallback & fb_mayfail);
   21452              : 
   21453              :       /* If this is an asm statement, and the user asked for the
   21454              :          impossible, don't die.  Fail and let gimplify_asm_expr
   21455              :          issue an error.  */
   21456            8 :       ret = GS_ERROR;
   21457            8 :       goto out;
   21458              :     }
   21459              : 
   21460              :   /* Make sure the temporary matches our predicate.  */
   21461     25853492 :   gcc_assert ((*gimple_test_f) (*expr_p));
   21462              : 
   21463     25853492 :   if (!gimple_seq_empty_p (internal_post))
   21464              :     {
   21465            0 :       annotate_all_with_location (internal_post, input_location);
   21466            0 :       gimplify_seq_add_seq (pre_p, internal_post);
   21467              :     }
   21468              : 
   21469     25853492 :  out:
   21470    462292913 :   input_location = saved_location;
   21471    462292913 :   return ret;
   21472              : }
   21473              : 
   21474              : /* Like gimplify_expr but make sure the gimplified result is not itself
   21475              :    a SSA name (but a decl if it were).  Temporaries required by
   21476              :    evaluating *EXPR_P may be still SSA names.  */
   21477              : 
   21478              : static enum gimplify_status
   21479     33268639 : gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   21480              :                bool (*gimple_test_f) (tree), fallback_t fallback,
   21481              :                bool allow_ssa)
   21482              : {
   21483     33268639 :   enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
   21484              :                                             gimple_test_f, fallback);
   21485     33268639 :   if (! allow_ssa
   21486       266280 :       && TREE_CODE (*expr_p) == SSA_NAME)
   21487        68670 :     *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
   21488     33268639 :   return ret;
   21489              : }
   21490              : 
   21491              : /* Look through TYPE for variable-sized objects and gimplify each such
   21492              :    size that we find.  Add to LIST_P any statements generated.  */
   21493              : 
   21494              : void
   21495      8091205 : gimplify_type_sizes (tree type, gimple_seq *list_p)
   21496              : {
   21497      8091205 :   if (type == NULL || type == error_mark_node)
   21498              :     return;
   21499              : 
   21500      8090959 :   const bool ignored_p
   21501      8090959 :     = TYPE_NAME (type)
   21502      4064645 :       && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
   21503     11924028 :       && DECL_IGNORED_P (TYPE_NAME (type));
   21504      8090959 :   tree t;
   21505              : 
   21506              :   /* We first do the main variant, then copy into any other variants.  */
   21507      8090959 :   type = TYPE_MAIN_VARIANT (type);
   21508              : 
   21509              :   /* Avoid infinite recursion.  */
   21510      8090959 :   if (TYPE_SIZES_GIMPLIFIED (type))
   21511              :     return;
   21512              : 
   21513      2409130 :   TYPE_SIZES_GIMPLIFIED (type) = 1;
   21514              : 
   21515      2409130 :   switch (TREE_CODE (type))
   21516              :     {
   21517       489078 :     case INTEGER_TYPE:
   21518       489078 :     case ENUMERAL_TYPE:
   21519       489078 :     case BOOLEAN_TYPE:
   21520       489078 :     case REAL_TYPE:
   21521       489078 :     case FIXED_POINT_TYPE:
   21522       489078 :       gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
   21523       489078 :       gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
   21524              : 
   21525      9717228 :       for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
   21526              :         {
   21527      9228150 :           TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
   21528      9228150 :           TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
   21529              :         }
   21530              :       break;
   21531              : 
   21532       179726 :     case ARRAY_TYPE:
   21533              :       /* These types may not have declarations, so handle them here.  */
   21534       179726 :       gimplify_type_sizes (TREE_TYPE (type), list_p);
   21535       179726 :       gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
   21536              :       /* Ensure VLA bounds aren't removed, for -O0 they should be variables
   21537              :          with assigned stack slots, for -O1+ -g they should be tracked
   21538              :          by VTA.  */
   21539       179726 :       if (!ignored_p
   21540       179726 :           && TYPE_DOMAIN (type)
   21541       359227 :           && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
   21542              :         {
   21543       179501 :           t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
   21544       179501 :           if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
   21545            0 :             DECL_IGNORED_P (t) = 0;
   21546       179501 :           t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
   21547       179501 :           if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
   21548        19018 :             DECL_IGNORED_P (t) = 0;
   21549              :         }
   21550              :       break;
   21551              : 
   21552       484298 :     case RECORD_TYPE:
   21553       484298 :     case UNION_TYPE:
   21554       484298 :     case QUAL_UNION_TYPE:
   21555     10386446 :       for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
   21556      9902148 :         if (TREE_CODE (field) == FIELD_DECL)
   21557              :           {
   21558      1063665 :             gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
   21559              :             /* Likewise, ensure variable offsets aren't removed.  */
   21560      1063665 :             if (!ignored_p
   21561      1063665 :                 && (t = DECL_FIELD_OFFSET (field))
   21562      1063653 :                 && VAR_P (t)
   21563      1063827 :                 && DECL_ARTIFICIAL (t))
   21564          162 :               DECL_IGNORED_P (t) = 0;
   21565      1063665 :             gimplify_one_sizepos (&DECL_SIZE (field), list_p);
   21566      1063665 :             gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
   21567      1063665 :             gimplify_type_sizes (TREE_TYPE (field), list_p);
   21568              :           }
   21569              :       break;
   21570              : 
   21571              :     case POINTER_TYPE:
   21572              :     case REFERENCE_TYPE:
   21573              :         /* We used to recurse on the pointed-to type here, which turned out to
   21574              :            be incorrect because its definition might refer to variables not
   21575              :            yet initialized at this point if a forward declaration is involved.
   21576              : 
   21577              :            It was actually useful for anonymous pointed-to types to ensure
   21578              :            that the sizes evaluation dominates every possible later use of the
   21579              :            values.  Restricting to such types here would be safe since there
   21580              :            is no possible forward declaration around, but would introduce an
   21581              :            undesirable middle-end semantic to anonymity.  We then defer to
   21582              :            front-ends the responsibility of ensuring that the sizes are
   21583              :            evaluated both early and late enough, e.g. by attaching artificial
   21584              :            type declarations to the tree.  */
   21585              :       break;
   21586              : 
   21587              :     default:
   21588              :       break;
   21589              :     }
   21590              : 
   21591      2409130 :   gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
   21592      2409130 :   gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
   21593              : 
   21594     15960436 :   for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
   21595              :     {
   21596     13551306 :       TYPE_SIZE (t) = TYPE_SIZE (type);
   21597     13551306 :       TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
   21598     13551306 :       TYPE_SIZES_GIMPLIFIED (t) = 1;
   21599              :     }
   21600              : }
   21601              : 
   21602              : /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
   21603              :    a size or position, has had all of its SAVE_EXPRs evaluated.
   21604              :    We add any required statements to *STMT_P.  */
   21605              : 
   21606              : void
   21607      9005529 : gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
   21608              : {
   21609      9005529 :   tree expr = *expr_p;
   21610              : 
   21611              :   /* We don't do anything if the value isn't there, is constant, or contains
   21612              :      A PLACEHOLDER_EXPR.  We also don't want to do anything if it's already
   21613              :      a VAR_DECL.  If it's a VAR_DECL from another function, the gimplifier
   21614              :      will want to replace it with a new variable, but that will cause problems
   21615              :      if this type is from outside the function.  It's OK to have that here.  */
   21616      9005529 :   if (expr == NULL_TREE
   21617      9009420 :       || is_gimple_constant (expr)
   21618        80956 :       || VAR_P (expr)
   21619      9082594 :       || CONTAINS_PLACEHOLDER_P (expr))
   21620      8928464 :     return;
   21621              : 
   21622        77065 :   *expr_p = unshare_expr (expr);
   21623              : 
   21624              :   /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
   21625              :      if the def vanishes.  */
   21626        77065 :   gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
   21627              : 
   21628              :   /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
   21629              :      FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
   21630              :      as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs.  */
   21631        77065 :   if (is_gimple_constant (*expr_p))
   21632          548 :     *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
   21633              : }
   21634              : 
   21635              : /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
   21636              :    containing the sequence of corresponding GIMPLE statements.  If DO_PARMS
   21637              :    is true, also gimplify the parameters.  */
   21638              : 
   21639              : gbind *
   21640      2881248 : gimplify_body (tree fndecl, bool do_parms)
   21641              : {
   21642      2881248 :   location_t saved_location = input_location;
   21643      2881248 :   gimple_seq parm_stmts, parm_cleanup = NULL, seq;
   21644      2881248 :   gimple *outer_stmt;
   21645      2881248 :   gbind *outer_bind;
   21646              : 
   21647      2881248 :   timevar_push (TV_TREE_GIMPLIFY);
   21648              : 
   21649      2881248 :   init_tree_ssa (cfun);
   21650              : 
   21651              :   /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
   21652              :      gimplification.  */
   21653      2881248 :   default_rtl_profile ();
   21654              : 
   21655      2881248 :   gcc_assert (gimplify_ctxp == NULL);
   21656      2881248 :   push_gimplify_context (true);
   21657              : 
   21658      2881248 :   if (flag_openacc || flag_openmp)
   21659              :     {
   21660        54898 :       gcc_assert (gimplify_omp_ctxp == NULL);
   21661        54898 :       if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
   21662         9733 :         gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
   21663              :     }
   21664              : 
   21665              :   /* Unshare most shared trees in the body and in that of any nested functions.
   21666              :      It would seem we don't have to do this for nested functions because
   21667              :      they are supposed to be output and then the outer function gimplified
   21668              :      first, but the g++ front end doesn't always do it that way.  */
   21669      2881248 :   unshare_body (fndecl);
   21670      2881248 :   unvisit_body (fndecl);
   21671              : 
   21672              :   /* Make sure input_location isn't set to something weird.  */
   21673      2881248 :   input_location = DECL_SOURCE_LOCATION (fndecl);
   21674              : 
   21675              :   /* Resolve callee-copies.  This has to be done before processing
   21676              :      the body so that DECL_VALUE_EXPR gets processed correctly.  */
   21677      2881248 :   parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
   21678              : 
   21679              :   /* Gimplify the function's body.  */
   21680      2881248 :   seq = NULL;
   21681      2881248 :   gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
   21682      2881248 :   outer_stmt = gimple_seq_first_nondebug_stmt (seq);
   21683      2881248 :   if (!outer_stmt)
   21684              :     {
   21685        26516 :       outer_stmt = gimple_build_nop ();
   21686        26516 :       gimplify_seq_add_stmt (&seq, outer_stmt);
   21687              :     }
   21688              : 
   21689              :   /* The body must contain exactly one statement, a GIMPLE_BIND.  If this is
   21690              :      not the case, wrap everything in a GIMPLE_BIND to make it so.  */
   21691      2881248 :   if (gimple_code (outer_stmt) == GIMPLE_BIND
   21692      2881248 :       && (gimple_seq_first_nondebug_stmt (seq)
   21693      1681643 :           == gimple_seq_last_nondebug_stmt (seq)))
   21694              :     {
   21695      1615339 :       outer_bind = as_a <gbind *> (outer_stmt);
   21696      1615339 :       if (gimple_seq_first_stmt (seq) != outer_stmt
   21697      1615339 :           || gimple_seq_last_stmt (seq) != outer_stmt)
   21698              :         {
   21699              :           /* If there are debug stmts before or after outer_stmt, move them
   21700              :              inside of outer_bind body.  */
   21701            1 :           gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
   21702            1 :           gimple_seq second_seq = NULL;
   21703            1 :           if (gimple_seq_first_stmt (seq) != outer_stmt
   21704            2 :               && gimple_seq_last_stmt (seq) != outer_stmt)
   21705              :             {
   21706            0 :               second_seq = gsi_split_seq_after (gsi);
   21707            0 :               gsi_remove (&gsi, false);
   21708              :             }
   21709            1 :           else if (gimple_seq_first_stmt (seq) != outer_stmt)
   21710            1 :             gsi_remove (&gsi, false);
   21711              :           else
   21712              :             {
   21713            0 :               gsi_remove (&gsi, false);
   21714            0 :               second_seq = seq;
   21715            0 :               seq = NULL;
   21716              :             }
   21717            1 :           gimple_seq_add_seq_without_update (&seq,
   21718              :                                              gimple_bind_body (outer_bind));
   21719            1 :           gimple_seq_add_seq_without_update (&seq, second_seq);
   21720            1 :           gimple_bind_set_body (outer_bind, seq);
   21721              :         }
   21722              :     }
   21723              :   else
   21724      1265909 :     outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
   21725              : 
   21726      2881248 :   DECL_SAVED_TREE (fndecl) = NULL_TREE;
   21727              : 
   21728              :   /* If we had callee-copies statements, insert them at the beginning
   21729              :      of the function and clear DECL_HAS_VALUE_EXPR_P on the parameters.  */
   21730      2881248 :   if (!gimple_seq_empty_p (parm_stmts))
   21731              :     {
   21732           41 :       tree parm;
   21733              : 
   21734           41 :       gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
   21735           41 :       if (parm_cleanup)
   21736              :         {
   21737            0 :           gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
   21738              :                                       GIMPLE_TRY_FINALLY);
   21739            0 :           parm_stmts = NULL;
   21740            0 :           gimple_seq_add_stmt (&parm_stmts, g);
   21741              :         }
   21742           41 :       gimple_bind_set_body (outer_bind, parm_stmts);
   21743              : 
   21744           41 :       for (parm = DECL_ARGUMENTS (current_function_decl);
   21745          101 :            parm; parm = DECL_CHAIN (parm))
   21746           60 :         if (DECL_HAS_VALUE_EXPR_P (parm))
   21747              :           {
   21748            0 :             DECL_HAS_VALUE_EXPR_P (parm) = 0;
   21749            0 :             DECL_IGNORED_P (parm) = 0;
   21750              :           }
   21751              :     }
   21752              : 
   21753      2881248 :   if ((flag_openacc || flag_openmp || flag_openmp_simd)
   21754        57154 :       && gimplify_omp_ctxp)
   21755              :     {
   21756         9786 :       delete_omp_context (gimplify_omp_ctxp);
   21757         9786 :       gimplify_omp_ctxp = NULL;
   21758              :     }
   21759              : 
   21760      2881248 :   pop_gimplify_context (outer_bind);
   21761      2881248 :   gcc_assert (gimplify_ctxp == NULL);
   21762              : 
   21763      2881248 :   if (flag_checking && !seen_error ())
   21764      2831687 :     verify_gimple_in_seq (gimple_bind_body (outer_bind));
   21765              : 
   21766      2881248 :   timevar_pop (TV_TREE_GIMPLIFY);
   21767      2881248 :   input_location = saved_location;
   21768              : 
   21769      2881248 :   return outer_bind;
   21770              : }
   21771              : 
   21772              : typedef char *char_p; /* For DEF_VEC_P.  */
   21773              : 
   21774              : /* Return whether we should exclude FNDECL from instrumentation.  */
   21775              : 
   21776              : static bool
   21777           43 : flag_instrument_functions_exclude_p (tree fndecl)
   21778              : {
   21779           43 :   vec<char_p> *v;
   21780              : 
   21781           43 :   v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
   21782           44 :   if (v && v->length () > 0)
   21783              :     {
   21784            1 :       const char *name;
   21785            1 :       int i;
   21786            1 :       char *s;
   21787              : 
   21788            1 :       name = lang_hooks.decl_printable_name (fndecl, 1);
   21789            2 :       FOR_EACH_VEC_ELT (*v, i, s)
   21790            1 :         if (strstr (name, s) != NULL)
   21791            2 :           return true;
   21792              :     }
   21793              : 
   21794           42 :   v = (vec<char_p> *) flag_instrument_functions_exclude_files;
   21795           43 :   if (v && v->length () > 0)
   21796              :     {
   21797            1 :       const char *name;
   21798            1 :       int i;
   21799            1 :       char *s;
   21800              : 
   21801            1 :       name = DECL_SOURCE_FILE (fndecl);
   21802            1 :       FOR_EACH_VEC_ELT (*v, i, s)
   21803            1 :         if (strstr (name, s) != NULL)
   21804            2 :           return true;
   21805              :     }
   21806              : 
   21807              :   return false;
   21808              : }
   21809              : 
   21810              : /* Build a call to the instrumentation function FNCODE and add it to SEQ.
   21811              :    If COND_VAR is not NULL, it is a boolean variable guarding the call to
   21812              :    the instrumentation function.  IF STMT is not NULL, it is a statement
   21813              :    to be executed just before the call to the instrumentation function.  */
   21814              : 
   21815              : static void
   21816           82 : build_instrumentation_call (gimple_seq *seq, enum built_in_function fncode,
   21817              :                             tree cond_var, gimple *stmt)
   21818              : {
   21819              :   /* The instrumentation hooks aren't going to call the instrumented
   21820              :      function and the address they receive is expected to be matchable
   21821              :      against symbol addresses.  Make sure we don't create a trampoline,
   21822              :      in case the current function is nested.  */
   21823           82 :   tree this_fn_addr = build_fold_addr_expr (current_function_decl);
   21824           82 :   TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
   21825              : 
   21826           82 :   tree label_true, label_false;
   21827           82 :   if (cond_var)
   21828              :     {
   21829           20 :       label_true = create_artificial_label (UNKNOWN_LOCATION);
   21830           20 :       label_false = create_artificial_label (UNKNOWN_LOCATION);
   21831           20 :       gcond *cond = gimple_build_cond (EQ_EXPR, cond_var, boolean_false_node,
   21832              :                                       label_true, label_false);
   21833           20 :       gimplify_seq_add_stmt (seq, cond);
   21834           20 :       gimplify_seq_add_stmt (seq, gimple_build_label (label_true));
   21835           20 :       gimplify_seq_add_stmt (seq, gimple_build_predict (PRED_COLD_LABEL,
   21836              :                                                         NOT_TAKEN));
   21837              :     }
   21838              : 
   21839           82 :   if (stmt)
   21840           10 :     gimplify_seq_add_stmt (seq, stmt);
   21841              : 
   21842           82 :   tree x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
   21843           82 :   gcall *call = gimple_build_call (x, 1, integer_zero_node);
   21844           82 :   tree tmp_var = create_tmp_var (ptr_type_node, "return_addr");
   21845           82 :   gimple_call_set_lhs (call, tmp_var);
   21846           82 :   gimplify_seq_add_stmt (seq, call);
   21847           82 :   x = builtin_decl_implicit (fncode);
   21848           82 :   call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
   21849           82 :   gimplify_seq_add_stmt (seq, call);
   21850              : 
   21851           82 :   if (cond_var)
   21852           20 :     gimplify_seq_add_stmt (seq, gimple_build_label (label_false));
   21853           82 : }
   21854              : 
   21855              : /* Entry point to the gimplification pass.  FNDECL is the FUNCTION_DECL
   21856              :    node for the function we want to gimplify.
   21857              : 
   21858              :    Return the sequence of GIMPLE statements corresponding to the body
   21859              :    of FNDECL.  */
   21860              : 
   21861              : void
   21862      2880744 : gimplify_function_tree (tree fndecl)
   21863              : {
   21864      2880744 :   gimple_seq seq;
   21865      2880744 :   gbind *bind;
   21866              : 
   21867      2880744 :   gcc_assert (!gimple_body (fndecl));
   21868              : 
   21869      2880744 :   if (DECL_STRUCT_FUNCTION (fndecl))
   21870      2876347 :     push_cfun (DECL_STRUCT_FUNCTION (fndecl));
   21871              :   else
   21872         4397 :     push_struct_function (fndecl);
   21873              : 
   21874      2880744 :   reset_cond_uid ();
   21875      2880744 :   if (cond_uids)
   21876              :     {
   21877           65 :       delete cond_uids;
   21878           65 :       cond_uids = NULL;
   21879              :     }
   21880              : 
   21881              :   /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
   21882              :      if necessary.  */
   21883      2880744 :   cfun->curr_properties |= PROP_gimple_lva;
   21884              : 
   21885      2880744 :   if (asan_sanitize_use_after_scope ())
   21886         8634 :     asan_poisoned_variables = new hash_set<tree> ();
   21887      2880744 :   if (flag_openmp)
   21888        47224 :     omp_resolved_variant_calls = new hash_set<tree> ();
   21889              : 
   21890      2880744 :   bind = gimplify_body (fndecl, true);
   21891              : 
   21892      2880744 :   if (omp_resolved_variant_calls)
   21893              :     {
   21894        47224 :       delete omp_resolved_variant_calls;
   21895        47224 :       omp_resolved_variant_calls = NULL;
   21896              :     }
   21897      2880744 :   if (asan_poisoned_variables)
   21898              :     {
   21899         8634 :       delete asan_poisoned_variables;
   21900         8634 :       asan_poisoned_variables = NULL;
   21901              :     }
   21902              : 
   21903              :   /* The tree body of the function is no longer needed, replace it
   21904              :      with the new GIMPLE body.  */
   21905      2880744 :   seq = NULL;
   21906      2880744 :   gimple_seq_add_stmt (&seq, bind);
   21907      2880744 :   gimple_set_body (fndecl, seq);
   21908              : 
   21909              :   /* If we're instrumenting function entry/exit, then prepend the call to
   21910              :      the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
   21911              :      catch the exit hook.  */
   21912              :   /* ??? Add some way to ignore exceptions for this TFE.  */
   21913      2880744 :   if (flag_instrument_function_entry_exit
   21914           97 :       && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
   21915              :       /* Do not instrument extern inline functions.  */
   21916           44 :       && !(DECL_DECLARED_INLINE_P (fndecl)
   21917            6 :            && DECL_EXTERNAL (fndecl)
   21918            1 :            && DECL_DISREGARD_INLINE_LIMITS (fndecl))
   21919      2880787 :       && !flag_instrument_functions_exclude_p (fndecl))
   21920              :     {
   21921           41 :       gimple_seq body = NULL, cleanup = NULL;
   21922           41 :       gassign *assign;
   21923           41 :       tree cond_var;
   21924              : 
   21925              :       /* If -finstrument-functions-once is specified, generate:
   21926              : 
   21927              :            static volatile bool C.0 = false;
   21928              :            bool tmp_called;
   21929              : 
   21930              :            tmp_called = C.0;
   21931              :            if (!tmp_called)
   21932              :              {
   21933              :                C.0 = true;
   21934              :                [call profiling enter function]
   21935              :              }
   21936              : 
   21937              :          without specific protection for data races.  */
   21938           41 :       if (flag_instrument_function_entry_exit > 1)
   21939              :         {
   21940           10 :           tree first_var
   21941           10 :             = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
   21942              :                           VAR_DECL,
   21943              :                           create_tmp_var_name ("C"),
   21944              :                           boolean_type_node);
   21945           10 :           DECL_ARTIFICIAL (first_var) = 1;
   21946           10 :           DECL_IGNORED_P (first_var) = 1;
   21947           10 :           TREE_STATIC (first_var) = 1;
   21948           10 :           TREE_THIS_VOLATILE (first_var) = 1;
   21949           10 :           TREE_USED (first_var) = 1;
   21950           10 :           DECL_INITIAL (first_var) = boolean_false_node;
   21951           10 :           varpool_node::add (first_var);
   21952              : 
   21953           10 :           cond_var = create_tmp_var (boolean_type_node, "tmp_called");
   21954           10 :           assign = gimple_build_assign (cond_var, first_var);
   21955           10 :           gimplify_seq_add_stmt (&body, assign);
   21956              : 
   21957           10 :           assign = gimple_build_assign (first_var, boolean_true_node);
   21958              :         }
   21959              : 
   21960              :       else
   21961              :         {
   21962              :           cond_var = NULL_TREE;
   21963              :           assign = NULL;
   21964              :         }
   21965              : 
   21966           41 :       build_instrumentation_call (&body, BUILT_IN_PROFILE_FUNC_ENTER,
   21967              :                                   cond_var, assign);
   21968              : 
   21969              :       /* If -finstrument-functions-once is specified, generate:
   21970              : 
   21971              :            if (!tmp_called)
   21972              :              [call profiling exit function]
   21973              : 
   21974              :          without specific protection for data races.  */
   21975           41 :       build_instrumentation_call (&cleanup, BUILT_IN_PROFILE_FUNC_EXIT,
   21976              :                                   cond_var, NULL);
   21977              : 
   21978           41 :       gimple *tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
   21979           41 :       gimplify_seq_add_stmt (&body, tf);
   21980           41 :       gbind *new_bind = gimple_build_bind (NULL, body, NULL);
   21981              : 
   21982              :       /* Replace the current function body with the body
   21983              :          wrapped in the try/finally TF.  */
   21984           41 :       seq = NULL;
   21985           41 :       gimple_seq_add_stmt (&seq, new_bind);
   21986           41 :       gimple_set_body (fndecl, seq);
   21987           41 :       bind = new_bind;
   21988              :     }
   21989              : 
   21990      2880744 :   if (sanitize_flags_p (SANITIZE_THREAD)
   21991      2880744 :       && param_tsan_instrument_func_entry_exit)
   21992              :     {
   21993         1147 :       gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
   21994         1147 :       gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
   21995         1147 :       gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
   21996              :       /* Replace the current function body with the body
   21997              :          wrapped in the try/finally TF.  */
   21998         1147 :       seq = NULL;
   21999         1147 :       gimple_seq_add_stmt (&seq, new_bind);
   22000         1147 :       gimple_set_body (fndecl, seq);
   22001              :     }
   22002              : 
   22003      2880744 :   DECL_SAVED_TREE (fndecl) = NULL_TREE;
   22004      2880744 :   cfun->curr_properties |= PROP_gimple_any;
   22005              : 
   22006      2880744 :   pop_cfun ();
   22007              : 
   22008      2880744 :   dump_function (TDI_gimple, fndecl);
   22009      2880744 : }
   22010              : 
   22011              : /* Return a dummy expression of type TYPE in order to keep going after an
   22012              :    error.  */
   22013              : 
   22014              : static tree
   22015           30 : dummy_object (tree type)
   22016              : {
   22017           30 :   tree t = build_int_cst (build_pointer_type (type), 0);
   22018           30 :   return build2 (MEM_REF, type, t, t);
   22019              : }
   22020              : 
   22021              : /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
   22022              :    builtin function, but a very special sort of operator.  */
   22023              : 
   22024              : enum gimplify_status
   22025        51131 : gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
   22026              :                       gimple_seq *post_p ATTRIBUTE_UNUSED)
   22027              : {
   22028        51131 :   tree promoted_type, have_va_type;
   22029        51131 :   tree valist = TREE_OPERAND (*expr_p, 0);
   22030        51131 :   tree type = TREE_TYPE (*expr_p);
   22031        51131 :   tree t, tag, aptag;
   22032        51131 :   location_t loc = EXPR_LOCATION (*expr_p);
   22033              : 
   22034              :   /* Verify that valist is of the proper type.  */
   22035        51131 :   have_va_type = TREE_TYPE (valist);
   22036        51131 :   if (have_va_type == error_mark_node)
   22037              :     return GS_ERROR;
   22038        51112 :   have_va_type = targetm.canonical_va_list_type (have_va_type);
   22039        51112 :   if (have_va_type == NULL_TREE
   22040        51112 :       && POINTER_TYPE_P (TREE_TYPE (valist)))
   22041              :     /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg.  */
   22042          258 :     have_va_type
   22043          258 :       = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
   22044        51112 :   gcc_assert (have_va_type != NULL_TREE);
   22045              : 
   22046              :   /* Generate a diagnostic for requesting data of a type that cannot
   22047              :      be passed through `...' due to type promotion at the call site.  */
   22048        51112 :   if ((promoted_type = lang_hooks.types.type_promotes_to (type))
   22049              :            != type)
   22050              :     {
   22051           30 :       static bool gave_help;
   22052           30 :       bool warned;
   22053              :       /* Use the expansion point to handle cases such as passing bool (defined
   22054              :          in a system header) through `...'.  */
   22055           30 :       location_t xloc
   22056           30 :         = expansion_point_location_if_in_system_header (loc);
   22057              : 
   22058              :       /* Unfortunately, this is merely undefined, rather than a constraint
   22059              :          violation, so we cannot make this an error.  If this call is never
   22060              :          executed, the program is still strictly conforming.  */
   22061           30 :       auto_diagnostic_group d;
   22062           30 :       warned = warning_at (xloc, 0,
   22063              :                            "%qT is promoted to %qT when passed through %<...%>",
   22064              :                            type, promoted_type);
   22065           30 :       if (!gave_help && warned)
   22066              :         {
   22067           15 :           gave_help = true;
   22068           15 :           inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
   22069              :                   promoted_type, type);
   22070              :         }
   22071              : 
   22072              :       /* We can, however, treat "undefined" any way we please.
   22073              :          Call abort to encourage the user to fix the program.  */
   22074           23 :       if (warned)
   22075           23 :         inform (xloc, "if this code is reached, the program will abort");
   22076              :       /* Before the abort, allow the evaluation of the va_list
   22077              :          expression to exit or longjmp.  */
   22078           30 :       gimplify_and_add (valist, pre_p);
   22079           60 :       t = build_call_expr_loc (loc,
   22080              :                                builtin_decl_implicit (BUILT_IN_TRAP), 0);
   22081           30 :       gimplify_and_add (t, pre_p);
   22082              : 
   22083              :       /* This is dead code, but go ahead and finish so that the
   22084              :          mode of the result comes out right.  */
   22085           30 :       *expr_p = dummy_object (type);
   22086           30 :       return GS_ALL_DONE;
   22087           30 :     }
   22088              : 
   22089        51082 :   tag = build_int_cst (build_pointer_type (type), 0);
   22090        51082 :   aptag = build_int_cst (TREE_TYPE (valist), 0);
   22091              : 
   22092        51082 :   *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
   22093              :                                           valist, tag, aptag);
   22094              : 
   22095              :   /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
   22096              :      needs to be expanded.  */
   22097        51082 :   cfun->curr_properties &= ~PROP_gimple_lva;
   22098              : 
   22099        51082 :   return GS_OK;
   22100              : }
   22101              : 
   22102              : /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
   22103              : 
   22104              :    DST/SRC are the destination and source respectively.  You can pass
   22105              :    ungimplified trees in DST or SRC, in which case they will be
   22106              :    converted to a gimple operand if necessary.
   22107              : 
   22108              :    This function returns the newly created GIMPLE_ASSIGN tuple.  */
   22109              : 
   22110              : gimple *
   22111       875161 : gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
   22112              : {
   22113       875161 :   tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
   22114       875161 :   gimplify_and_add (t, seq_p);
   22115       875161 :   ggc_free (t);
   22116       875161 :   return gimple_seq_last_stmt (*seq_p);
   22117              : }
   22118              : 
   22119              : inline hashval_t
   22120      1584541 : gimplify_hasher::hash (const elt_t *p)
   22121              : {
   22122      1584541 :   tree t = p->val;
   22123      1584541 :   return iterative_hash_expr (t, 0);
   22124              : }
   22125              : 
   22126              : inline bool
   22127       594997 : gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
   22128              : {
   22129       594997 :   tree t1 = p1->val;
   22130       594997 :   tree t2 = p2->val;
   22131       594997 :   enum tree_code code = TREE_CODE (t1);
   22132              : 
   22133       594997 :   if (TREE_CODE (t2) != code
   22134       594997 :       || TREE_TYPE (t1) != TREE_TYPE (t2))
   22135              :     return false;
   22136              : 
   22137       364599 :   if (!operand_equal_p (t1, t2, 0))
   22138              :     return false;
   22139              : 
   22140              :   return true;
   22141              : }
        

Generated by: LCOV version 2.4-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.