LCOV - code coverage report
Current view: top level - gcc - omp-low.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.0 % 9239 8778
Test Date: 2026-05-30 15:37:04 Functions: 98.5 % 131 129
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Lowering pass for OMP directives.  Converts OMP directives into explicit
       2              :    calls to the runtime library (libgomp), data marshalling to implement data
       3              :    sharing and copying clauses, offloading to accelerators, and more.
       4              : 
       5              :    Contributed by Diego Novillo <dnovillo@redhat.com>
       6              : 
       7              :    Copyright (C) 2005-2026 Free Software Foundation, Inc.
       8              : 
       9              : This file is part of GCC.
      10              : 
      11              : GCC is free software; you can redistribute it and/or modify it under
      12              : the terms of the GNU General Public License as published by the Free
      13              : Software Foundation; either version 3, or (at your option) any later
      14              : version.
      15              : 
      16              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      17              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      18              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      19              : for more details.
      20              : 
      21              : You should have received a copy of the GNU General Public License
      22              : along with GCC; see the file COPYING3.  If not see
      23              : <http://www.gnu.org/licenses/>.  */
      24              : 
      25              : #include "config.h"
      26              : #include "system.h"
      27              : #include "coretypes.h"
      28              : #include "backend.h"
      29              : #include "target.h"
      30              : #include "tree.h"
      31              : #include "gimple.h"
      32              : #include "tree-pass.h"
      33              : #include "ssa.h"
      34              : #include "cgraph.h"
      35              : #include "pretty-print.h"
      36              : #include "diagnostic-core.h"
      37              : #include "fold-const.h"
      38              : #include "stor-layout.h"
      39              : #include "internal-fn.h"
      40              : #include "gimple-iterator.h"
      41              : #include "gimple-fold.h"
      42              : #include "gimplify.h"
      43              : #include "gimplify-me.h"
      44              : #include "gimple-walk.h"
      45              : #include "tree-iterator.h"
      46              : #include "tree-inline.h"
      47              : #include "langhooks.h"
      48              : #include "tree-dfa.h"
      49              : #include "tree-ssa.h"
      50              : #include "splay-tree.h"
      51              : #include "omp-general.h"
      52              : #include "omp-low.h"
      53              : #include "gimple-low.h"
      54              : #include "alloc-pool.h"
      55              : #include "symbol-summary.h"
      56              : #include "tree-nested.h"
      57              : #include "context.h"
      58              : #include "gomp-constants.h"
      59              : #include "gimple-pretty-print.h"
      60              : #include "stringpool.h"
      61              : #include "attribs.h"
      62              : #include "omp-offload.h"
      63              : 
      64              : /* Lowering of OMP parallel and workshare constructs proceeds in two
      65              :    phases.  The first phase scans the function looking for OMP statements
      66              :    and then for variables that must be replaced to satisfy data sharing
      67              :    clauses.  The second phase expands code for the constructs, as well as
      68              :    re-gimplifying things when variables have been replaced with complex
      69              :    expressions.
      70              : 
      71              :    Final code generation is done by pass_expand_omp.  The flowgraph is
      72              :    scanned for regions which are then moved to a new
      73              :    function, to be invoked by the thread library, or offloaded.  */
      74              : 
      75              : /* Context structure.  Used to store information about each parallel
      76              :    directive in the code.  */
      77              : 
      78              : struct omp_context
      79              : {
      80              :   /* This field must be at the beginning, as we do "inheritance": Some
      81              :      callback functions for tree-inline.cc (e.g., omp_copy_decl)
      82              :      receive a copy_body_data pointer that is up-casted to an
      83              :      omp_context pointer.  */
      84              :   copy_body_data cb;
      85              : 
      86              :   /* The tree of contexts corresponding to the encountered constructs.  */
      87              :   struct omp_context *outer;
      88              :   gimple *stmt;
      89              : 
      90              :   /* Map variables to fields in a structure that allows communication
      91              :      between sending and receiving threads.  */
      92              :   splay_tree field_map;
      93              :   tree record_type;
      94              :   tree sender_decl;
      95              :   tree receiver_decl;
      96              : 
      97              :   /* These are used just by task contexts, if task firstprivate fn is
      98              :      needed.  srecord_type is used to communicate from the thread
      99              :      that encountered the task construct to task firstprivate fn,
     100              :      record_type is allocated by GOMP_task, initialized by task firstprivate
     101              :      fn and passed to the task body fn.  */
     102              :   splay_tree sfield_map;
     103              :   tree srecord_type;
     104              : 
     105              :   /* A chain of variables to add to the top-level block surrounding the
     106              :      construct.  In the case of a parallel, this is in the child function.  */
     107              :   tree block_vars;
     108              : 
     109              :   /* Label to which GOMP_cancel{,llation_point} and explicit and implicit
     110              :      barriers should jump to during omplower pass.  */
     111              :   tree cancel_label;
     112              : 
     113              :   /* The sibling GIMPLE_OMP_FOR simd with _simt_ clause or NULL
     114              :      otherwise.  */
     115              :   gimple *simt_stmt;
     116              : 
     117              :   /* For task reductions registered in this context, a vector containing
     118              :      the length of the private copies block (if constant, otherwise NULL)
     119              :      and then offsets (if constant, otherwise NULL) for each entry.  */
     120              :   vec<tree> task_reductions;
     121              : 
     122              :   /* A hash map from the reduction clauses to the registered array
     123              :      elts.  */
     124              :   hash_map<tree, unsigned> *task_reduction_map;
     125              : 
     126              :   /* And a hash map from the lastprivate(conditional:) variables to their
     127              :      corresponding tracking loop iteration variables.  */
     128              :   hash_map<tree, tree> *lastprivate_conditional_map;
     129              : 
     130              :   /* And a hash map from the allocate variables to their corresponding
     131              :      allocators.  */
     132              :   hash_map<tree, tree> *allocate_map;
     133              : 
     134              :   /* A tree_list of the reduction clauses in this context. This is
     135              :     only used for checking the consistency of OpenACC reduction
     136              :     clauses in scan_omp_for and is not guaranteed to contain a valid
     137              :     value outside of this function. */
     138              :   tree local_reduction_clauses;
     139              : 
     140              :   /* A tree_list of the reduction clauses in outer contexts. This is
     141              :     only used for checking the consistency of OpenACC reduction
     142              :     clauses in scan_omp_for and is not guaranteed to contain a valid
     143              :     value outside of this function. */
     144              :   tree outer_reduction_clauses;
     145              : 
     146              :   /* Nesting depth of this context.  Used to beautify error messages re
     147              :      invalid gotos.  The outermost ctx is depth 1, with depth 0 being
     148              :      reserved for the main body of the function.  */
     149              :   int depth;
     150              : 
     151              :   /* True if this parallel directive is nested within another.  */
     152              :   bool is_nested;
     153              : 
     154              :   /* True if this construct can be cancelled.  */
     155              :   bool cancellable;
     156              : 
     157              :   /* True if lower_omp_1 should look up lastprivate conditional in parent
     158              :      context.  */
     159              :   bool combined_into_simd_safelen1;
     160              : 
     161              :   /* True if there is nested scan context with inclusive clause.  */
     162              :   bool scan_inclusive;
     163              : 
     164              :   /* True if there is nested scan context with exclusive clause.  */
     165              :   bool scan_exclusive;
     166              : 
     167              :   /* True in the second simd loop of for simd with inscan reductions.  */
     168              :   bool for_simd_scan_phase;
     169              : 
     170              :   /* True if there is order(concurrent) clause on the construct.  */
     171              :   bool order_concurrent;
     172              : 
     173              :   /* True if there is bind clause on the construct (i.e. a loop construct).  */
     174              :   bool loop_p;
     175              : 
     176              :   /* Only used for omp target contexts.  True if a teams construct is
     177              :      strictly nested in it.  */
     178              :   bool teams_nested_p;
     179              : 
     180              :   /* Only used for omp target contexts.  True if an OpenMP construct other
     181              :      than teams is strictly nested in it.  */
     182              :   bool nonteams_nested_p;
     183              : 
     184              :   /* Candidates for adjusting OpenACC privatization level.  */
     185              :   vec<tree> oacc_privatization_candidates;
     186              : };
     187              : 
     188              : static splay_tree all_contexts;
     189              : static int taskreg_nesting_level;
     190              : static int target_nesting_level;
     191              : static bitmap make_addressable_vars;
     192              : static bitmap global_nonaddressable_vars;
     193              : static vec<omp_context *> taskreg_contexts;
     194              : static vec<gomp_task *> task_cpyfns;
     195              : 
     196              : static void scan_omp (gimple_seq *, omp_context *);
     197              : static tree scan_omp_1_op (tree *, int *, void *);
     198              : static bool omp_maybe_offloaded_ctx (omp_context *ctx);
     199              : 
     200              : #define WALK_SUBSTMTS  \
     201              :     case GIMPLE_BIND: \
     202              :     case GIMPLE_TRY: \
     203              :     case GIMPLE_CATCH: \
     204              :     case GIMPLE_EH_FILTER: \
     205              :     case GIMPLE_ASSUME: \
     206              :     case GIMPLE_TRANSACTION: \
     207              :       /* The sub-statements for these should be walked.  */ \
     208              :       *handled_ops_p = false; \
     209              :       break;
     210              : 
     211              : /* Return whether CTX represents an OpenACC 'parallel' or 'serial' construct.
     212              :    (This doesn't include OpenACC 'kernels' decomposed parts.)  */
     213              : 
     214              : static bool
     215        33532 : is_oacc_parallel_or_serial (omp_context *ctx)
     216              : {
     217        33532 :   enum gimple_code outer_type = gimple_code (ctx->stmt);
     218        33532 :   return ((outer_type == GIMPLE_OMP_TARGET)
     219        33532 :           && ((gimple_omp_target_kind (ctx->stmt)
     220              :                == GF_OMP_TARGET_KIND_OACC_PARALLEL)
     221        15190 :               || (gimple_omp_target_kind (ctx->stmt)
     222        33532 :                   == GF_OMP_TARGET_KIND_OACC_SERIAL)));
     223              : }
     224              : 
     225              : /* Return whether CTX represents an OpenACC 'kernels' construct.
     226              :    (This doesn't include OpenACC 'kernels' decomposed parts.)  */
     227              : 
     228              : static bool
     229        49900 : is_oacc_kernels (omp_context *ctx)
     230              : {
     231        49900 :   enum gimple_code outer_type = gimple_code (ctx->stmt);
     232        49900 :   return ((outer_type == GIMPLE_OMP_TARGET)
     233        49900 :           && (gimple_omp_target_kind (ctx->stmt)
     234        49900 :               == GF_OMP_TARGET_KIND_OACC_KERNELS));
     235              : }
     236              : 
     237              : /* Return whether CTX represents an OpenACC 'kernels' decomposed part.  */
     238              : 
     239              : static bool
     240        21645 : is_oacc_kernels_decomposed_part (omp_context *ctx)
     241              : {
     242        21645 :   enum gimple_code outer_type = gimple_code (ctx->stmt);
     243        21645 :   return ((outer_type == GIMPLE_OMP_TARGET)
     244        21645 :           && ((gimple_omp_target_kind (ctx->stmt)
     245              :                == GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED)
     246        14552 :               || (gimple_omp_target_kind (ctx->stmt)
     247              :                   == GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE)
     248        14552 :               || (gimple_omp_target_kind (ctx->stmt)
     249        21645 :                   == GF_OMP_TARGET_KIND_OACC_DATA_KERNELS)));
     250              : }
     251              : 
     252              : /* Return true if STMT corresponds to an OpenMP target region.  */
     253              : static bool
     254        42818 : is_omp_target (gimple *stmt)
     255              : {
     256        42818 :   if (gimple_code (stmt) == GIMPLE_OMP_TARGET)
     257              :     {
     258         6485 :       int kind = gimple_omp_target_kind (stmt);
     259         6485 :       return (kind == GF_OMP_TARGET_KIND_REGION
     260         6485 :               || kind == GF_OMP_TARGET_KIND_DATA
     261         6485 :               || kind == GF_OMP_TARGET_KIND_ENTER_DATA
     262        11095 :               || kind == GF_OMP_TARGET_KIND_EXIT_DATA);
     263              :     }
     264              :   return false;
     265              : }
     266              : 
     267              : /* If DECL is the artificial dummy VAR_DECL created for non-static
     268              :    data member privatization, return the underlying "this" parameter,
     269              :    otherwise return NULL.  */
     270              : 
     271              : tree
     272       538436 : omp_member_access_dummy_var (tree decl)
     273              : {
     274       538436 :   if (!VAR_P (decl)
     275       330579 :       || !DECL_ARTIFICIAL (decl)
     276       162251 :       || !DECL_IGNORED_P (decl)
     277       156841 :       || !DECL_HAS_VALUE_EXPR_P (decl)
     278       551218 :       || !lang_hooks.decls.omp_disregard_value_expr (decl, false))
     279       536176 :     return NULL_TREE;
     280              : 
     281         2260 :   tree v = DECL_VALUE_EXPR (decl);
     282         2260 :   if (TREE_CODE (v) != COMPONENT_REF)
     283              :     return NULL_TREE;
     284              : 
     285        16164 :   while (1)
     286         9197 :     switch (TREE_CODE (v))
     287              :       {
     288         6967 :       case COMPONENT_REF:
     289         6967 :       case MEM_REF:
     290         6967 :       case INDIRECT_REF:
     291         6967 :       CASE_CONVERT:
     292         6967 :       case POINTER_PLUS_EXPR:
     293         6967 :         v = TREE_OPERAND (v, 0);
     294         6967 :         continue;
     295         2211 :       case PARM_DECL:
     296         2211 :         if (DECL_CONTEXT (v) == current_function_decl
     297         2211 :             && DECL_ARTIFICIAL (v)
     298         4422 :             && TREE_CODE (TREE_TYPE (v)) == POINTER_TYPE)
     299              :           return v;
     300              :         return NULL_TREE;
     301              :       default:
     302              :         return NULL_TREE;
     303              :       }
     304              : }
     305              : 
     306              : /* Helper for unshare_and_remap, called through walk_tree.  */
     307              : 
     308              : static tree
     309         1579 : unshare_and_remap_1 (tree *tp, int *walk_subtrees, void *data)
     310              : {
     311         1579 :   tree *pair = (tree *) data;
     312         1579 :   if (*tp == pair[0])
     313              :     {
     314          233 :       *tp = unshare_expr (pair[1]);
     315          233 :       *walk_subtrees = 0;
     316              :     }
     317         1346 :   else if (IS_TYPE_OR_DECL_P (*tp))
     318          244 :     *walk_subtrees = 0;
     319         1579 :   return NULL_TREE;
     320              : }
     321              : 
     322              : /* Return unshare_expr (X) with all occurrences of FROM
     323              :    replaced with TO.  */
     324              : 
     325              : static tree
     326          150 : unshare_and_remap (tree x, tree from, tree to)
     327              : {
     328          150 :   tree pair[2] = { from, to };
     329          150 :   x = unshare_expr (x);
     330          150 :   walk_tree (&x, unshare_and_remap_1, pair, NULL);
     331          150 :   return x;
     332              : }
     333              : 
     334              : /* Convenience function for calling scan_omp_1_op on tree operands.  */
     335              : 
     336              : static inline tree
     337       338965 : scan_omp_op (tree *tp, omp_context *ctx)
     338              : {
     339       338965 :   struct walk_stmt_info wi;
     340              : 
     341       338965 :   memset (&wi, 0, sizeof (wi));
     342       338965 :   wi.info = ctx;
     343       338965 :   wi.want_locations = true;
     344              : 
     345       338965 :   return walk_tree (tp, scan_omp_1_op, &wi, NULL);
     346              : }
     347              : 
     348              : static void lower_omp (gimple_seq *, omp_context *);
     349              : static tree lookup_decl_in_outer_ctx (tree, omp_context *);
     350              : static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
     351              : 
     352              : /* Return true if CTX is for an omp parallel.  */
     353              : 
     354              : static inline bool
     355       775973 : is_parallel_ctx (omp_context *ctx)
     356              : {
     357        61144 :   return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
     358              : }
     359              : 
     360              : 
     361              : /* Return true if CTX is for an omp task.  */
     362              : 
     363              : static inline bool
     364       235766 : is_task_ctx (omp_context *ctx)
     365              : {
     366        38740 :   return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
     367              : }
     368              : 
     369              : 
     370              : /* Return true if CTX is for an omp taskloop.  */
     371              : 
     372              : static inline bool
     373         8182 : is_taskloop_ctx (omp_context *ctx)
     374              : {
     375         8182 :   return gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
     376         8182 :          && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_TASKLOOP;
     377              : }
     378              : 
     379              : 
     380              : /* Return true if CTX is for a host omp teams.  */
     381              : 
     382              : static inline bool
     383       521093 : is_host_teams_ctx (omp_context *ctx)
     384              : {
     385       521093 :   return gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
     386       521093 :          && gimple_omp_teams_host (as_a <gomp_teams *> (ctx->stmt));
     387              : }
     388              : 
     389              : /* Return true if CTX is for an omp parallel or omp task or host omp teams
     390              :    (the last one is strictly not a task region in OpenMP speak, but we
     391              :    need to treat it similarly).  */
     392              : 
     393              : static inline bool
     394       663390 : is_taskreg_ctx (omp_context *ctx)
     395              : {
     396       663390 :   return is_parallel_ctx (ctx) || is_task_ctx (ctx) || is_host_teams_ctx (ctx);
     397              : }
     398              : 
     399              : /* Return true if EXPR is variable sized.  If IS_REF is true, then
     400              :    EXPR is assumed to be a reference and the object it refers
     401              :    to is checked instead.  */
     402              : 
     403              : static inline bool
     404       905209 : is_variable_sized (const_tree expr, bool is_ref = false)
     405              : {
     406       905209 :   if (is_ref)
     407         2140 :     expr = TREE_TYPE (expr);
     408       905209 :   return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
     409              : }
     410              : 
     411              : /* Lookup variables.  The "maybe" form
     412              :    allows for the variable form to not have been entered, otherwise we
     413              :    assert that the variable must have been entered.  */
     414              : 
     415              : static inline tree
     416       715551 : lookup_decl (tree var, omp_context *ctx)
     417              : {
     418      1431003 :   tree *n = ctx->cb.decl_map->get (var);
     419       715551 :   return *n;
     420              : }
     421              : 
     422              : static inline tree
     423       719087 : maybe_lookup_decl (const_tree var, omp_context *ctx)
     424              : {
     425       719087 :   tree *n = ctx->cb.decl_map->get (const_cast<tree> (var));
     426       719087 :   return n ? *n : NULL_TREE;
     427              : }
     428              : 
     429              : static inline tree
     430       126999 : lookup_field (tree var, omp_context *ctx)
     431              : {
     432       126999 :   splay_tree_node n;
     433       253998 :   n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
     434       126999 :   return (tree) n->value;
     435              : }
     436              : 
     437              : static inline tree
     438       168951 : lookup_sfield (splay_tree_key key, omp_context *ctx)
     439              : {
     440       168951 :   splay_tree_node n;
     441       168951 :   n = splay_tree_lookup (ctx->sfield_map
     442              :                          ? ctx->sfield_map : ctx->field_map, key);
     443       168951 :   return (tree) n->value;
     444              : }
     445              : 
     446              : static inline tree
     447          967 : lookup_sfield (tree var, omp_context *ctx)
     448              : {
     449          967 :   return lookup_sfield ((splay_tree_key) var, ctx);
     450              : }
     451              : 
     452              : static inline tree
     453       220980 : maybe_lookup_field (splay_tree_key key, omp_context *ctx)
     454              : {
     455       220980 :   splay_tree_node n;
     456       220980 :   n = splay_tree_lookup (ctx->field_map, key);
     457       220980 :   return n ? (tree) n->value : NULL_TREE;
     458              : }
     459              : 
     460              : static inline tree
     461       220980 : maybe_lookup_field (tree var, omp_context *ctx)
     462              : {
     463         2555 :   return maybe_lookup_field ((splay_tree_key) var, ctx);
     464              : }
     465              : 
     466              : /* Return true if DECL should be copied by pointer.  SHARED_CTX is
     467              :    the parallel context if DECL is to be shared.  */
     468              : 
     469              : static bool
     470       232266 : use_pointer_for_field (tree decl, omp_context *shared_ctx)
     471              : {
     472       453008 :   if (AGGREGATE_TYPE_P (TREE_TYPE (decl))
     473       215629 :       || TYPE_ATOMIC (TREE_TYPE (decl))
     474       447895 :       || POLY_INT_CST_P (DECL_SIZE (decl)))
     475              :     return true;
     476              : 
     477              :   /* We can only use copy-in/copy-out semantics for shared variables
     478              :      when we know the value is not accessible from an outer scope.  */
     479       215599 :   if (shared_ctx)
     480              :     {
     481        29413 :       gcc_assert (!is_gimple_omp_oacc (shared_ctx->stmt));
     482              : 
     483              :       /* ??? Trivially accessible from anywhere.  But why would we even
     484              :          be passing an address in this case?  Should we simply assert
     485              :          this to be false, or should we have a cleanup pass that removes
     486              :          these from the list of mappings?  */
     487        29413 :       if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, shared_ctx)))
     488              :         return true;
     489              : 
     490              :       /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
     491              :          without analyzing the expression whether or not its location
     492              :          is accessible to anyone else.  In the case of nested parallel
     493              :          regions it certainly may be.  */
     494        29413 :       if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
     495              :         return true;
     496              : 
     497              :       /* Do not use copy-in/copy-out for variables that have their
     498              :          address taken.  */
     499        28499 :       if (is_global_var (decl))
     500              :         {
     501              :           /* For file scope vars, track whether we've seen them as
     502              :              non-addressable initially and in that case, keep the same
     503              :              answer for the duration of the pass, even when they are made
     504              :              addressable later on e.g. through reduction expansion.  Global
     505              :              variables which weren't addressable before the pass will not
     506              :              have their privatized copies address taken.  See PR91216.  */
     507         1232 :           if (!TREE_ADDRESSABLE (decl))
     508              :             {
     509          479 :               if (!global_nonaddressable_vars)
     510           74 :                 global_nonaddressable_vars = BITMAP_ALLOC (NULL);
     511          479 :               bitmap_set_bit (global_nonaddressable_vars, DECL_UID (decl));
     512              :             }
     513          753 :           else if (!global_nonaddressable_vars
     514          986 :                    || !bitmap_bit_p (global_nonaddressable_vars,
     515          233 :                                      DECL_UID (decl)))
     516          731 :             return true;
     517              :         }
     518        27267 :       else if (TREE_ADDRESSABLE (decl))
     519              :         return true;
     520              : 
     521              :       /* lower_send_shared_vars only uses copy-in, but not copy-out
     522              :          for these.  */
     523        18362 :       if (TREE_READONLY (decl)
     524        18362 :           || ((TREE_CODE (decl) == RESULT_DECL
     525        11779 :                || TREE_CODE (decl) == PARM_DECL)
     526          673 :               && DECL_BY_REFERENCE (decl)))
     527              :         return false;
     528              : 
     529              :       /* Disallow copy-in/out in nested parallel if
     530              :          decl is shared in outer parallel, otherwise
     531              :          each thread could store the shared variable
     532              :          in its own copy-in location, making the
     533              :          variable no longer really shared.  */
     534        11547 :       if (shared_ctx->is_nested)
     535              :         {
     536         2470 :           omp_context *up;
     537              : 
     538         5975 :           for (up = shared_ctx->outer; up; up = up->outer)
     539         5702 :             if ((is_taskreg_ctx (up)
     540         3643 :                  || (gimple_code (up->stmt) == GIMPLE_OMP_TARGET
     541          411 :                      && is_gimple_omp_offloaded (up->stmt)))
     542         6113 :                 && maybe_lookup_decl (decl, up))
     543              :               break;
     544              : 
     545         2470 :           if (up)
     546              :             {
     547         2197 :               tree c;
     548              : 
     549         2197 :               if (gimple_code (up->stmt) == GIMPLE_OMP_TARGET)
     550              :                 {
     551          309 :                   for (c = gimple_omp_target_clauses (up->stmt);
     552         2031 :                        c; c = OMP_CLAUSE_CHAIN (c))
     553         1932 :                     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
     554         1932 :                         && OMP_CLAUSE_DECL (c) == decl)
     555              :                       break;
     556              :                 }
     557              :               else
     558         1888 :                 for (c = gimple_omp_taskreg_clauses (up->stmt);
     559         6909 :                      c; c = OMP_CLAUSE_CHAIN (c))
     560         6454 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
     561         6454 :                       && OMP_CLAUSE_DECL (c) == decl)
     562              :                     break;
     563              : 
     564         2197 :               if (c)
     565         1643 :                 goto maybe_mark_addressable_and_ret;
     566              :             }
     567              :         }
     568              : 
     569              :       /* For tasks avoid using copy-in/out.  As tasks can be
     570              :          deferred or executed in different thread, when GOMP_task
     571              :          returns, the task hasn't necessarily terminated.  */
     572         9904 :       if (is_task_ctx (shared_ctx))
     573              :         {
     574         2193 :           tree outer;
     575          550 :         maybe_mark_addressable_and_ret:
     576         2193 :           outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
     577         2193 :           if (is_gimple_reg (outer) && !omp_member_access_dummy_var (outer))
     578              :             {
     579              :               /* Taking address of OUTER in lower_send_shared_vars
     580              :                  might need regimplification of everything that uses the
     581              :                  variable.  */
     582          982 :               if (!make_addressable_vars)
     583          489 :                 make_addressable_vars = BITMAP_ALLOC (NULL);
     584          982 :               bitmap_set_bit (make_addressable_vars, DECL_UID (outer));
     585          982 :               TREE_ADDRESSABLE (outer) = 1;
     586              :             }
     587         2193 :           return true;
     588              :         }
     589              :     }
     590              : 
     591              :   return false;
     592              : }
     593              : 
     594              : /* Construct a new automatic decl similar to VAR.  */
     595              : 
     596              : static tree
     597       229339 : omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
     598              : {
     599       229339 :   tree copy = copy_var_decl (var, name, type);
     600              : 
     601       229339 :   DECL_CONTEXT (copy) = current_function_decl;
     602              : 
     603       229339 :   if (ctx)
     604              :     {
     605       229058 :       DECL_CHAIN (copy) = ctx->block_vars;
     606       229058 :       ctx->block_vars = copy;
     607              :     }
     608              :   else
     609          281 :     record_vars (copy);
     610              : 
     611              :   /* If VAR is listed in make_addressable_vars, it wasn't
     612              :      originally addressable, but was only later made so.
     613              :      We don't need to take address of privatizations
     614              :      from that var.  */
     615       229339 :   if (TREE_ADDRESSABLE (var)
     616       229339 :       && ((make_addressable_vars
     617         3467 :            && bitmap_bit_p (make_addressable_vars, DECL_UID (var)))
     618        39586 :           || (global_nonaddressable_vars
     619          515 :               && bitmap_bit_p (global_nonaddressable_vars, DECL_UID (var)))))
     620         2077 :     TREE_ADDRESSABLE (copy) = 0;
     621              : 
     622       229339 :   return copy;
     623              : }
     624              : 
     625              : static tree
     626       229339 : omp_copy_decl_1 (tree var, omp_context *ctx)
     627              : {
     628       229339 :   return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
     629              : }
     630              : 
     631              : /* Build tree nodes to access the field for VAR on the receiver side.  */
     632              : 
     633              : static tree
     634       122543 : build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
     635              : {
     636       122543 :   tree x, field = lookup_field (var, ctx);
     637              : 
     638              :   /* If the receiver record type was remapped in the child function,
     639              :      remap the field into the new record type.  */
     640       122543 :   x = maybe_lookup_field (field, ctx);
     641       122543 :   if (x != NULL)
     642        11143 :     field = x;
     643              : 
     644       122543 :   x = build_simple_mem_ref (ctx->receiver_decl);
     645       122543 :   TREE_THIS_NOTRAP (x) = 1;
     646       122543 :   x = omp_build_component_ref (x, field);
     647       122543 :   if (by_ref)
     648              :     {
     649        36034 :       x = build_simple_mem_ref (x);
     650        36034 :       TREE_THIS_NOTRAP (x) = 1;
     651              :     }
     652              : 
     653       122543 :   return x;
     654              : }
     655              : 
     656              : /* Build tree nodes to access VAR in the scope outer to CTX.  In the case
     657              :    of a parallel, this is a component reference; for workshare constructs
     658              :    this is some variable.  */
     659              : 
     660              : static tree
     661       114329 : build_outer_var_ref (tree var, omp_context *ctx,
     662              :                      enum omp_clause_code code = OMP_CLAUSE_ERROR)
     663              : {
     664       114329 :   tree x;
     665       114329 :   omp_context *outer = ctx->outer;
     666       114718 :   for (; outer; outer = outer->outer)
     667              :     {
     668        82472 :       if (gimple_code (outer->stmt) == GIMPLE_OMP_TASKGROUP)
     669          373 :         continue;
     670        82115 :       if (gimple_code (outer->stmt) == GIMPLE_OMP_SCOPE
     671        82099 :           && !maybe_lookup_decl (var, outer))
     672           16 :         continue;
     673              :       break;
     674              :     }
     675              : 
     676       114329 :   if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
     677              :     x = var;
     678       106230 :   else if (is_variable_sized (var))
     679              :     {
     680           47 :       x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
     681           47 :       x = build_outer_var_ref (x, ctx, code);
     682           47 :       x = build_simple_mem_ref (x);
     683              :     }
     684       106183 :   else if (is_taskreg_ctx (ctx))
     685              :     {
     686        63646 :       bool by_ref = use_pointer_for_field (var, NULL);
     687        63646 :       x = build_receiver_ref (var, by_ref, ctx);
     688              :     }
     689        42537 :   else if ((gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
     690        41200 :             && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
     691        14075 :            || ctx->loop_p
     692        13302 :            || code == OMP_CLAUSE_ALLOCATE
     693        55587 :            || (code == OMP_CLAUSE_PRIVATE
     694           40 :                && (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
     695              :                    || gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS
     696              :                    || gimple_code (ctx->stmt) == GIMPLE_OMP_SINGLE)))
     697              :     {
     698              :       /* #pragma omp simd isn't a worksharing construct, and can reference
     699              :          even private vars in its linear etc. clauses.
     700              :          Similarly for OMP_CLAUSE_PRIVATE with outer ref, that can refer
     701              :          to private vars in all worksharing constructs.  */
     702        29507 :       x = NULL_TREE;
     703        29507 :       if (outer && is_taskreg_ctx (outer))
     704         1002 :         x = lookup_decl (var, outer);
     705        28505 :       else if (outer)
     706        22315 :         x = maybe_lookup_decl_in_outer_ctx (var, ctx);
     707        23317 :       if (x == NULL_TREE)
     708              :         x = var;
     709              :     }
     710        13030 :   else if (code == OMP_CLAUSE_LASTPRIVATE && is_taskloop_ctx (ctx))
     711              :     {
     712          689 :       gcc_assert (outer);
     713          689 :       splay_tree_node n
     714         1378 :         = splay_tree_lookup (outer->field_map,
     715          689 :                              (splay_tree_key) &DECL_UID (var));
     716          689 :       if (n == NULL)
     717              :         {
     718          610 :           if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, outer)))
     719              :             x = var;
     720              :           else
     721          384 :             x = lookup_decl (var, outer);
     722              :         }
     723              :       else
     724              :         {
     725           79 :           tree field = (tree) n->value;
     726              :           /* If the receiver record type was remapped in the child function,
     727              :              remap the field into the new record type.  */
     728           79 :           x = maybe_lookup_field (field, outer);
     729           79 :           if (x != NULL)
     730            0 :             field = x;
     731              : 
     732           79 :           x = build_simple_mem_ref (outer->receiver_decl);
     733           79 :           x = omp_build_component_ref (x, field);
     734           79 :           if (use_pointer_for_field (var, outer))
     735           59 :             x = build_simple_mem_ref (x);
     736              :         }
     737              :     }
     738        12341 :   else if (outer)
     739        12149 :     x = lookup_decl (var, outer);
     740          192 :   else if (omp_privatize_by_reference (var))
     741              :     /* This can happen with orphaned constructs.  If var is reference, it is
     742              :        possible it is shared and as such valid.  */
     743              :     x = var;
     744           94 :   else if (omp_member_access_dummy_var (var))
     745              :     x = var;
     746              :   else
     747            0 :     gcc_unreachable ();
     748              : 
     749       114329 :   if (x == var)
     750              :     {
     751        16281 :       tree t = omp_member_access_dummy_var (var);
     752        16281 :       if (t)
     753              :         {
     754          220 :           x = DECL_VALUE_EXPR (var);
     755          220 :           tree o = maybe_lookup_decl_in_outer_ctx (t, ctx);
     756          220 :           if (o != t)
     757           54 :             x = unshare_and_remap (x, t, o);
     758              :           else
     759          166 :             x = unshare_expr (x);
     760              :         }
     761              :     }
     762              : 
     763       114329 :   if (omp_privatize_by_reference (var))
     764         3080 :     x = build_simple_mem_ref (x);
     765              : 
     766       114329 :   return x;
     767              : }
     768              : 
     769              : /* Build tree nodes to access the field for VAR on the sender side.  */
     770              : 
     771              : static tree
     772       167905 : build_sender_ref (splay_tree_key key, omp_context *ctx)
     773              : {
     774       167905 :   tree field = lookup_sfield (key, ctx);
     775       167905 :   tree tmp = ctx->sender_decl;
     776       167905 :   if (POINTER_TYPE_P (TREE_TYPE (tmp)))
     777          451 :     tmp = build_fold_indirect_ref (tmp);
     778       167905 :   return omp_build_component_ref (tmp, field);
     779              : }
     780              : 
     781              : static tree
     782       163759 : build_sender_ref (tree var, omp_context *ctx)
     783              : {
     784            0 :   return build_sender_ref ((splay_tree_key) var, ctx);
     785              : }
     786              : 
     787              : /* Add a new field for VAR inside the structure CTX.  If BY_REF is true,
     788              :    use a pointer to the VAR rather than VAR itself.
     789              :    MASK is a bit mask of other options.  Bits are interpreted as:
     790              :       1: Install VAR in ctx->field_map.
     791              :       2: Install VAR in ctx->sfield_map.
     792              :       4: VAR is an array, convert it to a pointer.
     793              :       8: Use DECL_UID (VAR) instead of VAR as key.
     794              :      16: Use DECL_NAME (VAR) instead of VAR as key.
     795              :      32: Don't dereference omp_is_reference types.
     796              :    KEY_EXPR allows specifying something other than VAR as the lookup key.
     797              :    If specified, it also overrides the 8 and 16 MASK bits.  */
     798              : 
     799              : static void
     800       130866 : install_var_field (tree var, bool by_ref, int mask, omp_context *ctx,
     801              :                    tree key_expr = NULL_TREE)
     802              : {
     803       130866 :   tree field, type, sfield = NULL_TREE;
     804       130866 :   splay_tree_key key = (splay_tree_key) var;
     805              : 
     806       130866 :   if (key_expr)
     807              :     /* Allow caller to explicitly set the expression used as the key.  */
     808        44615 :     key = (splay_tree_key) key_expr;
     809              :   else
     810              :     {
     811        86251 :       if ((mask & 16) != 0)
     812              :         {
     813          620 :           key = (splay_tree_key) &DECL_NAME (var);
     814          620 :           gcc_checking_assert (key != (splay_tree_key) var);
     815              :         }
     816        86251 :       if ((mask & 8) != 0)
     817              :         {
     818         1615 :           key = (splay_tree_key) &DECL_UID (var);
     819         1615 :           gcc_checking_assert (key != (splay_tree_key) var);
     820              :         }
     821              :     }
     822       130866 :   gcc_assert ((mask & 1) == 0
     823              :               || !splay_tree_lookup (ctx->field_map, key));
     824       130866 :   gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
     825              :               || !splay_tree_lookup (ctx->sfield_map, key));
     826       130866 :   gcc_assert ((mask & 3) == 3
     827              :               || !is_gimple_omp_oacc (ctx->stmt));
     828              : 
     829       130866 :   type = TREE_TYPE (var);
     830       130866 :   if ((mask & 16) != 0)
     831          620 :     type = lang_hooks.decls.omp_array_data (var, true);
     832              : 
     833              :   /* Prevent redeclaring the var in the split-off function with a restrict
     834              :      pointer type.  Note that we only clear type itself, restrict qualifiers in
     835              :      the pointed-to type will be ignored by points-to analysis.  */
     836       130866 :   if (POINTER_TYPE_P (type)
     837       130866 :       && TYPE_RESTRICT (type))
     838         6975 :     type = build_qualified_type (type, TYPE_QUALS (type) & ~TYPE_QUAL_RESTRICT);
     839              : 
     840       130866 :   if (mask & 4)
     841              :     {
     842          425 :       gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
     843          425 :       type = build_pointer_type (build_pointer_type (type));
     844              :     }
     845       130441 :   else if (by_ref)
     846        63831 :     type = build_pointer_type (type);
     847        66610 :   else if ((mask & (32 | 3)) == 1
     848        66610 :            && omp_privatize_by_reference (var))
     849          162 :     type = TREE_TYPE (type);
     850              : 
     851       130866 :   field = build_decl (DECL_SOURCE_LOCATION (var),
     852       130866 :                       FIELD_DECL, DECL_NAME (var), type);
     853              : 
     854              :   /* Remember what variable this field was created for.  This does have a
     855              :      side effect of making dwarf2out ignore this member, so for helpful
     856              :      debugging we clear it later in delete_omp_context.  */
     857       130866 :   DECL_ABSTRACT_ORIGIN (field) = var;
     858       130866 :   if ((mask & 16) == 0 && type == TREE_TYPE (var))
     859              :     {
     860        62152 :       SET_DECL_ALIGN (field, DECL_ALIGN (var));
     861        62152 :       DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
     862        62152 :       TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
     863              :     }
     864              :   else
     865        68714 :     SET_DECL_ALIGN (field, TYPE_ALIGN (type));
     866              : 
     867       130866 :   if ((mask & 3) == 3)
     868              :     {
     869       129814 :       insert_field_into_struct (ctx->record_type, field);
     870       129814 :       if (ctx->srecord_type)
     871              :         {
     872          678 :           sfield = build_decl (DECL_SOURCE_LOCATION (var),
     873          678 :                                FIELD_DECL, DECL_NAME (var), type);
     874          678 :           DECL_ABSTRACT_ORIGIN (sfield) = var;
     875          678 :           SET_DECL_ALIGN (sfield, DECL_ALIGN (field));
     876          678 :           DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
     877          678 :           TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
     878          678 :           insert_field_into_struct (ctx->srecord_type, sfield);
     879              :         }
     880              :     }
     881              :   else
     882              :     {
     883         1052 :       if (ctx->srecord_type == NULL_TREE)
     884              :         {
     885          544 :           tree t;
     886              : 
     887          544 :           ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
     888          544 :           ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
     889         2027 :           for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
     890              :             {
     891         1483 :               sfield = build_decl (DECL_SOURCE_LOCATION (t),
     892         1483 :                                    FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
     893         1483 :               DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
     894         1483 :               insert_field_into_struct (ctx->srecord_type, sfield);
     895         2966 :               splay_tree_insert (ctx->sfield_map,
     896         1483 :                                  (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
     897              :                                  (splay_tree_value) sfield);
     898              :             }
     899              :         }
     900         1052 :       sfield = field;
     901         1052 :       insert_field_into_struct ((mask & 1) ? ctx->record_type
     902              :                                 : ctx->srecord_type, field);
     903              :     }
     904              : 
     905       130866 :   if (mask & 1)
     906       130479 :     splay_tree_insert (ctx->field_map, key, (splay_tree_value) field);
     907       130866 :   if ((mask & 2) && ctx->sfield_map)
     908         1065 :     splay_tree_insert (ctx->sfield_map, key, (splay_tree_value) sfield);
     909       130866 : }
     910              : 
     911              : static tree
     912       228908 : install_var_local (tree var, omp_context *ctx)
     913              : {
     914       228908 :   tree new_var = omp_copy_decl_1 (var, ctx);
     915       228908 :   insert_decl_map (&ctx->cb, var, new_var);
     916       228908 :   return new_var;
     917              : }
     918              : 
     919              : /* Adjust the replacement for DECL in CTX for the new context.  This means
     920              :    copying the DECL_VALUE_EXPR, and fixing up the type.  */
     921              : 
     922              : static void
     923       204180 : fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
     924              : {
     925       204180 :   tree new_decl, size;
     926              : 
     927       204180 :   new_decl = lookup_decl (decl, ctx);
     928              : 
     929       204180 :   TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
     930              : 
     931       407227 :   if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
     932       204369 :       && DECL_HAS_VALUE_EXPR_P (decl))
     933              :     {
     934         1322 :       tree ve = DECL_VALUE_EXPR (decl);
     935         1322 :       walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
     936         1322 :       SET_DECL_VALUE_EXPR (new_decl, ve);
     937         1322 :       DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
     938              :     }
     939              : 
     940       204180 :   if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
     941              :     {
     942         1133 :       size = remap_decl (DECL_SIZE (decl), &ctx->cb);
     943         1133 :       if (size == error_mark_node)
     944          316 :         size = TYPE_SIZE (TREE_TYPE (new_decl));
     945         1133 :       DECL_SIZE (new_decl) = size;
     946              : 
     947         1133 :       size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
     948         1133 :       if (size == error_mark_node)
     949          303 :         size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
     950         1133 :       DECL_SIZE_UNIT (new_decl) = size;
     951              :     }
     952       204180 : }
     953              : 
     954              : /* The callback for remap_decl.  Search all containing contexts for a
     955              :    mapping of the variable; this avoids having to duplicate the splay
     956              :    tree ahead of time.  We know a mapping doesn't already exist in the
     957              :    given context.  Create new mappings to implement default semantics.  */
     958              : 
     959              : static tree
     960       463093 : omp_copy_decl (tree var, copy_body_data *cb)
     961              : {
     962       463093 :   omp_context *ctx = (omp_context *) cb;
     963       463093 :   tree new_var;
     964              : 
     965       463093 :   if (TREE_CODE (var) == LABEL_DECL)
     966              :     {
     967       187921 :       if (FORCED_LABEL (var) || DECL_NONLOCAL (var))
     968              :         return var;
     969       187915 :       new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
     970       187915 :       DECL_CONTEXT (new_var) = current_function_decl;
     971       187915 :       insert_decl_map (&ctx->cb, var, new_var);
     972       187915 :       return new_var;
     973              :     }
     974              : 
     975       357004 :   while (!is_taskreg_ctx (ctx))
     976              :     {
     977       337803 :       ctx = ctx->outer;
     978       337803 :       if (ctx == NULL)
     979              :         return var;
     980       279598 :       new_var = maybe_lookup_decl (var, ctx);
     981       279598 :       if (new_var)
     982              :         return new_var;
     983              :     }
     984              : 
     985        19201 :   if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
     986        13368 :     return var;
     987              : 
     988         5833 :   return error_mark_node;
     989              : }
     990              : 
     991              : /* Create a new context, with OUTER_CTX being the surrounding context.  */
     992              : 
     993              : static omp_context *
     994       137492 : new_omp_context (gimple *stmt, omp_context *outer_ctx)
     995              : {
     996       137492 :   omp_context *ctx = XCNEW (omp_context);
     997              : 
     998       137492 :   splay_tree_insert (all_contexts, (splay_tree_key) stmt,
     999              :                      (splay_tree_value) ctx);
    1000       137492 :   ctx->stmt = stmt;
    1001              : 
    1002       137492 :   if (outer_ctx)
    1003              :     {
    1004        74441 :       ctx->outer = outer_ctx;
    1005        74441 :       ctx->cb = outer_ctx->cb;
    1006        74441 :       ctx->cb.block = NULL;
    1007        74441 :       ctx->depth = outer_ctx->depth + 1;
    1008              :     }
    1009              :   else
    1010              :     {
    1011        63051 :       ctx->cb.src_fn = current_function_decl;
    1012        63051 :       ctx->cb.dst_fn = current_function_decl;
    1013        63051 :       ctx->cb.src_node = cgraph_node::get (current_function_decl);
    1014        63051 :       gcc_checking_assert (ctx->cb.src_node);
    1015        63051 :       ctx->cb.dst_node = ctx->cb.src_node;
    1016        63051 :       ctx->cb.src_cfun = cfun;
    1017        63051 :       ctx->cb.copy_decl = omp_copy_decl;
    1018        63051 :       ctx->cb.eh_lp_nr = 0;
    1019        63051 :       ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
    1020        63051 :       ctx->cb.adjust_array_error_bounds = true;
    1021        63051 :       ctx->cb.dont_remap_vla_if_no_change = true;
    1022        63051 :       ctx->depth = 1;
    1023              :     }
    1024              : 
    1025       137492 :   ctx->cb.decl_map = new hash_map<tree, tree>;
    1026              : 
    1027       137492 :   return ctx;
    1028              : }
    1029              : 
    1030              : static gimple_seq maybe_catch_exception (gimple_seq);
    1031              : 
    1032              : /* Finalize task copyfn.  */
    1033              : 
    1034              : static void
    1035          504 : finalize_task_copyfn (gomp_task *task_stmt)
    1036              : {
    1037          504 :   struct function *child_cfun;
    1038          504 :   tree child_fn;
    1039          504 :   gimple_seq seq = NULL, new_seq;
    1040          504 :   gbind *bind;
    1041              : 
    1042          504 :   child_fn = gimple_omp_task_copy_fn (task_stmt);
    1043          504 :   if (child_fn == NULL_TREE)
    1044            0 :     return;
    1045              : 
    1046          504 :   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
    1047          504 :   DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
    1048              : 
    1049          504 :   push_cfun (child_cfun);
    1050          504 :   bind = gimplify_body (child_fn, false);
    1051          504 :   gimple_seq_add_stmt (&seq, bind);
    1052          504 :   new_seq = maybe_catch_exception (seq);
    1053          504 :   if (new_seq != seq)
    1054              :     {
    1055          332 :       bind = gimple_build_bind (NULL, new_seq, NULL);
    1056          332 :       seq = NULL;
    1057          332 :       gimple_seq_add_stmt (&seq, bind);
    1058              :     }
    1059          504 :   gimple_set_body (child_fn, seq);
    1060          504 :   pop_cfun ();
    1061              : 
    1062              :   /* Inform the callgraph about the new function.  */
    1063          504 :   cgraph_node *node = cgraph_node::get_create (child_fn);
    1064          504 :   node->parallelized_function = 1;
    1065          504 :   cgraph_node::add_new_function (child_fn, false);
    1066              : }
    1067              : 
    1068              : /* Destroy a omp_context data structures.  Called through the splay tree
    1069              :    value delete callback.  */
    1070              : 
    1071              : static void
    1072       137486 : delete_omp_context (splay_tree_value value)
    1073              : {
    1074       137486 :   omp_context *ctx = (omp_context *) value;
    1075              : 
    1076       274972 :   delete ctx->cb.decl_map;
    1077              : 
    1078       137486 :   if (ctx->field_map)
    1079        68979 :     splay_tree_delete (ctx->field_map);
    1080       137486 :   if (ctx->sfield_map)
    1081          544 :     splay_tree_delete (ctx->sfield_map);
    1082              : 
    1083              :   /* We hijacked DECL_ABSTRACT_ORIGIN earlier.  We need to clear it before
    1084              :      it produces corrupt debug information.  */
    1085       137486 :   if (ctx->record_type)
    1086              :     {
    1087        53188 :       tree t;
    1088       221742 :       for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
    1089       168554 :         DECL_ABSTRACT_ORIGIN (t) = NULL;
    1090              :     }
    1091       137486 :   if (ctx->srecord_type)
    1092              :     {
    1093          544 :       tree t;
    1094         3092 :       for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = DECL_CHAIN (t))
    1095         2548 :         DECL_ABSTRACT_ORIGIN (t) = NULL;
    1096              :     }
    1097              : 
    1098       137486 :   if (ctx->task_reduction_map)
    1099              :     {
    1100         1165 :       ctx->task_reductions.release ();
    1101         2330 :       delete ctx->task_reduction_map;
    1102              :     }
    1103              : 
    1104       137759 :   delete ctx->lastprivate_conditional_map;
    1105       138865 :   delete ctx->allocate_map;
    1106              : 
    1107       137486 :   XDELETE (ctx);
    1108       137486 : }
    1109              : 
    1110              : /* Fix up RECEIVER_DECL with a type that has been remapped to the child
    1111              :    context.  */
    1112              : 
    1113              : static void
    1114        36607 : fixup_child_record_type (omp_context *ctx)
    1115              : {
    1116        36607 :   tree f, type = ctx->record_type;
    1117              : 
    1118        36607 :   if (!ctx->receiver_decl)
    1119              :     return;
    1120              :   /* ??? It isn't sufficient to just call remap_type here, because
    1121              :      variably_modified_type_p doesn't work the way we expect for
    1122              :      record types.  Testing each field for whether it needs remapping
    1123              :      and creating a new record by hand works, however.  */
    1124       161040 :   for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
    1125       125702 :     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
    1126              :       break;
    1127        36607 :   if (f)
    1128              :     {
    1129         1269 :       tree name, new_fields = NULL;
    1130              : 
    1131         1269 :       type = lang_hooks.types.make_type (RECORD_TYPE);
    1132         1269 :       name = DECL_NAME (TYPE_NAME (ctx->record_type));
    1133         1269 :       name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
    1134              :                          TYPE_DECL, name, type);
    1135         1269 :       TYPE_NAME (type) = name;
    1136              : 
    1137        13406 :       for (f = TYPE_FIELDS (ctx->record_type); f ; f = DECL_CHAIN (f))
    1138              :         {
    1139        12137 :           tree new_f = copy_node (f);
    1140        12137 :           DECL_CONTEXT (new_f) = type;
    1141        12137 :           TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
    1142        12137 :           DECL_CHAIN (new_f) = new_fields;
    1143        12137 :           walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
    1144        12137 :           walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
    1145              :                      &ctx->cb, NULL);
    1146        12137 :           walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
    1147              :                      &ctx->cb, NULL);
    1148        12137 :           new_fields = new_f;
    1149              : 
    1150              :           /* Arrange to be able to look up the receiver field
    1151              :              given the sender field.  */
    1152        12137 :           splay_tree_insert (ctx->field_map, (splay_tree_key) f,
    1153              :                              (splay_tree_value) new_f);
    1154              :         }
    1155         1269 :       TYPE_FIELDS (type) = nreverse (new_fields);
    1156         1269 :       layout_type (type);
    1157              :     }
    1158              : 
    1159              :   /* In a target region we never modify any of the pointers in *.omp_data_i,
    1160              :      so attempt to help the optimizers.  */
    1161        36607 :   if (is_gimple_omp_offloaded (ctx->stmt))
    1162        17465 :     type = build_qualified_type (type, TYPE_QUAL_CONST);
    1163              : 
    1164        36607 :   TREE_TYPE (ctx->receiver_decl)
    1165       109821 :     = build_qualified_type (flexible_array_type_p (type)
    1166          107 :                             ? build_pointer_type (type)
    1167        36500 :                             : build_reference_type (type), TYPE_QUAL_RESTRICT);
    1168              : }
    1169              : 
    1170              : /* Instantiate decls as necessary in CTX to satisfy the data sharing
    1171              :    specified by CLAUSES.  */
    1172              : 
    1173              : static void
    1174       129655 : scan_sharing_clauses (tree clauses, omp_context *ctx)
    1175              : {
    1176       129655 :   tree c, decl;
    1177       129655 :   bool scan_array_reductions = false;
    1178       129655 :   bool flex_array_ptr = false;
    1179              : 
    1180       549329 :   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    1181       419674 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE
    1182       419674 :         && (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
    1183              :             /* omp_default_mem_alloc is 1 */
    1184         1284 :             || !integer_onep (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
    1185          572 :             || OMP_CLAUSE_ALLOCATE_ALIGN (c) != NULL_TREE))
    1186              :       {
    1187              :         /* The allocate clauses that appear on a target construct or on
    1188              :            constructs in a target region must specify an allocator expression
    1189              :            unless a requires directive with the dynamic_allocators clause
    1190              :            is present in the same compilation unit.  */
    1191         1848 :         if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
    1192         1092 :             && ((omp_requires_mask & OMP_REQUIRES_DYNAMIC_ALLOCATORS) == 0)
    1193         2928 :             && omp_maybe_offloaded_ctx (ctx))
    1194           10 :           error_at (OMP_CLAUSE_LOCATION (c), "%<allocate%> clause must"
    1195              :                     " specify an allocator here");
    1196         1848 :         if (ctx->allocate_map == NULL)
    1197         1379 :           ctx->allocate_map = new hash_map<tree, tree>;
    1198         1848 :         tree val = integer_zero_node;
    1199         1848 :         if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
    1200          756 :           val = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
    1201         1848 :         if (OMP_CLAUSE_ALLOCATE_ALIGN (c))
    1202          287 :           val = build_tree_list (val, OMP_CLAUSE_ALLOCATE_ALIGN (c));
    1203         1848 :         ctx->allocate_map->put (OMP_CLAUSE_DECL (c), val);
    1204              :       }
    1205              : 
    1206       549329 :   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    1207              :     {
    1208       419674 :       bool by_ref;
    1209              : 
    1210       419674 :       switch (OMP_CLAUSE_CODE (c))
    1211              :         {
    1212        73215 :         case OMP_CLAUSE_PRIVATE:
    1213        73215 :           decl = OMP_CLAUSE_DECL (c);
    1214        73215 :           if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
    1215          165 :             goto do_private;
    1216        73050 :           else if (!is_variable_sized (decl))
    1217        72687 :             install_var_local (decl, ctx);
    1218              :           break;
    1219              : 
    1220        46768 :         case OMP_CLAUSE_SHARED:
    1221        46768 :           decl = OMP_CLAUSE_DECL (c);
    1222        46768 :           if (ctx->allocate_map && ctx->allocate_map->get (decl))
    1223           37 :             ctx->allocate_map->remove (decl);
    1224              :           /* Ignore shared directives in teams construct inside of
    1225              :              target construct.  */
    1226        46768 :           if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
    1227        46768 :               && !is_host_teams_ctx (ctx))
    1228              :             {
    1229              :               /* Global variables don't need to be copied,
    1230              :                  the receiver side will use them directly.  */
    1231        11856 :               tree odecl = maybe_lookup_decl_in_outer_ctx (decl, ctx);
    1232        11856 :               if (is_global_var (odecl))
    1233              :                 break;
    1234         8127 :               insert_decl_map (&ctx->cb, decl, odecl);
    1235         8127 :               break;
    1236              :             }
    1237        34912 :           gcc_assert (is_taskreg_ctx (ctx));
    1238        34912 :           gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
    1239              :                       || !is_variable_sized (decl));
    1240              :           /* Global variables don't need to be copied,
    1241              :              the receiver side will use them directly.  */
    1242        34912 :           if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
    1243              :             break;
    1244        28847 :           if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
    1245              :             {
    1246           86 :               use_pointer_for_field (decl, ctx);
    1247           86 :               break;
    1248              :             }
    1249        28761 :           by_ref = use_pointer_for_field (decl, NULL);
    1250        55057 :           if ((! TREE_READONLY (decl) && !OMP_CLAUSE_SHARED_READONLY (c))
    1251        19259 :               || TREE_ADDRESSABLE (decl)
    1252        18902 :               || by_ref
    1253        47663 :               || omp_privatize_by_reference (decl))
    1254              :             {
    1255        11970 :               by_ref = use_pointer_for_field (decl, ctx);
    1256        11970 :               install_var_field (decl, by_ref, 3, ctx);
    1257        11970 :               install_var_local (decl, ctx);
    1258        11970 :               break;
    1259              :             }
    1260              :           /* We don't need to copy const scalar vars back.  */
    1261        16791 :           OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
    1262        16791 :           goto do_private;
    1263              : 
    1264        14500 :         case OMP_CLAUSE_REDUCTION:
    1265              :           /* Collect 'reduction' clauses on OpenACC compute construct.  */
    1266        14500 :           if (is_gimple_omp_oacc (ctx->stmt)
    1267        14500 :               && is_gimple_omp_offloaded (ctx->stmt))
    1268              :             {
    1269              :               /* No 'reduction' clauses on OpenACC 'kernels'.  */
    1270          790 :               gcc_checking_assert (!is_oacc_kernels (ctx));
    1271              :               /* Likewise, on OpenACC 'kernels' decomposed parts.  */
    1272          790 :               gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));
    1273              : 
    1274          790 :               ctx->local_reduction_clauses
    1275          790 :                 = tree_cons (NULL, c, ctx->local_reduction_clauses);
    1276              :             }
    1277              :           /* FALLTHRU */
    1278              : 
    1279        16574 :         case OMP_CLAUSE_IN_REDUCTION:
    1280        16574 :           decl = OMP_CLAUSE_DECL (c);
    1281        16574 :           if (ctx->allocate_map
    1282        16574 :               && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    1283          389 :                    && (OMP_CLAUSE_REDUCTION_INSCAN (c)
    1284          389 :                        || OMP_CLAUSE_REDUCTION_TASK (c)))
    1285          397 :                   || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
    1286          389 :                   || is_task_ctx (ctx)))
    1287              :             {
    1288              :               /* For now.  */
    1289           17 :               if (ctx->allocate_map->get (decl))
    1290           17 :                 ctx->allocate_map->remove (decl);
    1291              :             }
    1292        16574 :           if (TREE_CODE (decl) == MEM_REF)
    1293              :             {
    1294         2366 :               tree t = TREE_OPERAND (decl, 0);
    1295         2366 :               if (TREE_CODE (t) == POINTER_PLUS_EXPR)
    1296          436 :                 t = TREE_OPERAND (t, 0);
    1297         2366 :               if (INDIRECT_REF_P (t)
    1298         2272 :                   || TREE_CODE (t) == ADDR_EXPR)
    1299         1378 :                 t = TREE_OPERAND (t, 0);
    1300         2366 :               if (is_omp_target (ctx->stmt))
    1301              :                 {
    1302           96 :                   if (is_variable_sized (t))
    1303              :                     {
    1304           32 :                       gcc_assert (DECL_HAS_VALUE_EXPR_P (t));
    1305           32 :                       t = DECL_VALUE_EXPR (t);
    1306           32 :                       gcc_assert (INDIRECT_REF_P (t));
    1307           32 :                       t = TREE_OPERAND (t, 0);
    1308           32 :                       gcc_assert (DECL_P (t));
    1309              :                     }
    1310           96 :                   tree at = t;
    1311           96 :                   if (ctx->outer)
    1312           96 :                     scan_omp_op (&at, ctx->outer);
    1313           96 :                   tree nt = omp_copy_decl_1 (at, ctx->outer);
    1314          192 :                   splay_tree_insert (ctx->field_map,
    1315           96 :                                      (splay_tree_key) &DECL_CONTEXT (t),
    1316              :                                      (splay_tree_value) nt);
    1317           96 :                   if (at != t)
    1318           96 :                     splay_tree_insert (ctx->field_map,
    1319           48 :                                        (splay_tree_key) &DECL_CONTEXT (at),
    1320              :                                        (splay_tree_value) nt);
    1321           96 :                   break;
    1322              :                 }
    1323         2270 :               install_var_local (t, ctx);
    1324         2270 :               if (is_taskreg_ctx (ctx)
    1325         1822 :                   && (!is_global_var (maybe_lookup_decl_in_outer_ctx (t, ctx))
    1326          387 :                       || (is_task_ctx (ctx)
    1327          310 :                           && (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
    1328          234 :                               || (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE
    1329            0 :                                   && (TREE_CODE (TREE_TYPE (TREE_TYPE (t)))
    1330              :                                       == POINTER_TYPE)))))
    1331         1511 :                   && !is_variable_sized (t)
    1332         3722 :                   && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
    1333          617 :                       || (!OMP_CLAUSE_REDUCTION_TASK (c)
    1334          578 :                           && !is_task_ctx (ctx))))
    1335              :                 {
    1336         1335 :                   by_ref = use_pointer_for_field (t, NULL);
    1337         1335 :                   if (is_task_ctx (ctx)
    1338          835 :                       && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE
    1339         1495 :                       && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) == POINTER_TYPE)
    1340              :                     {
    1341           32 :                       install_var_field (t, false, 1, ctx);
    1342           32 :                       install_var_field (t, by_ref, 2, ctx);
    1343              :                     }
    1344              :                   else
    1345         1303 :                     install_var_field (t, by_ref, 3, ctx);
    1346              :                 }
    1347              :               break;
    1348              :             }
    1349        14208 :           if (is_omp_target (ctx->stmt))
    1350              :             {
    1351          335 :               tree at = decl;
    1352          335 :               if (ctx->outer)
    1353           54 :                 scan_omp_op (&at, ctx->outer);
    1354          335 :               tree nt = omp_copy_decl_1 (at, ctx->outer);
    1355          670 :               splay_tree_insert (ctx->field_map,
    1356          335 :                                  (splay_tree_key) &DECL_CONTEXT (decl),
    1357              :                                  (splay_tree_value) nt);
    1358          335 :               if (at != decl)
    1359           24 :                 splay_tree_insert (ctx->field_map,
    1360           12 :                                    (splay_tree_key) &DECL_CONTEXT (at),
    1361              :                                    (splay_tree_value) nt);
    1362          335 :               break;
    1363              :             }
    1364        13873 :           if (is_task_ctx (ctx)
    1365        26676 :               || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    1366        12803 :                   && OMP_CLAUSE_REDUCTION_TASK (c)
    1367          373 :                   && is_parallel_ctx (ctx)))
    1368              :             {
    1369              :               /* Global variables don't need to be copied,
    1370              :                  the receiver side will use them directly.  */
    1371         1150 :               if (!is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
    1372              :                 {
    1373          462 :                   by_ref = use_pointer_for_field (decl, ctx);
    1374          462 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
    1375          304 :                     install_var_field (decl, by_ref, 3, ctx);
    1376              :                 }
    1377         1150 :               install_var_local (decl, ctx);
    1378         1150 :               break;
    1379              :             }
    1380        12723 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    1381        12723 :               && OMP_CLAUSE_REDUCTION_TASK (c))
    1382              :             {
    1383          293 :               install_var_local (decl, ctx);
    1384          293 :               break;
    1385              :             }
    1386        12430 :           goto do_private;
    1387              : 
    1388        22736 :         case OMP_CLAUSE_LASTPRIVATE:
    1389              :           /* Let the corresponding firstprivate clause create
    1390              :              the variable.  */
    1391        22736 :           if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
    1392              :             break;
    1393              :           /* FALLTHRU */
    1394              : 
    1395        59169 :         case OMP_CLAUSE_FIRSTPRIVATE:
    1396        59169 :         case OMP_CLAUSE_LINEAR:
    1397        59169 :           decl = OMP_CLAUSE_DECL (c);
    1398        88943 :         do_private:
    1399        88943 :           if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
    1400              :                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR
    1401              :                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
    1402        45574 :               && is_gimple_omp_offloaded (ctx->stmt))
    1403              :             {
    1404        16129 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
    1405        16129 :                   || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR
    1406          239 :                       && lang_hooks.decls.omp_array_data (decl, true)))
    1407              :                 {
    1408              :                   /* OpenACC firstprivate clauses are later processed with same
    1409              :                      code path as map clauses in lower_omp_target, so follow
    1410              :                      the same convention of using the whole clause expression
    1411              :                      as splay-tree key.  */
    1412        15760 :                   tree k = (is_oacc_parallel_or_serial (ctx) ? c : NULL_TREE);
    1413        15760 :                   by_ref = !omp_privatize_by_reference (decl);
    1414        15760 :                   install_var_field (decl, by_ref, 3, ctx, k);
    1415              :                 }
    1416          369 :               else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
    1417              :                 {
    1418          220 :                   if (INDIRECT_REF_P (decl))
    1419            0 :                     decl = TREE_OPERAND (decl, 0);
    1420          220 :                   install_var_field (decl, true, 3, ctx);
    1421              :                 }
    1422          149 :               else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    1423            8 :                   install_var_field (decl, true, 3, ctx);
    1424              :               else
    1425          141 :                 install_var_field (decl, false, 3, ctx);
    1426              :             }
    1427        88943 :           if (is_variable_sized (decl))
    1428              :             {
    1429           60 :               if (is_task_ctx (ctx))
    1430              :                 {
    1431           14 :                   if (ctx->allocate_map
    1432           14 :                       && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
    1433              :                     {
    1434              :                       /* For now.  */
    1435            0 :                       if (ctx->allocate_map->get (decl))
    1436            0 :                         ctx->allocate_map->remove (decl);
    1437              :                     }
    1438           14 :                   install_var_field (decl, false, 1, ctx);
    1439              :                 }
    1440              :               break;
    1441              :             }
    1442        88883 :           else if (is_taskreg_ctx (ctx))
    1443              :             {
    1444        38267 :               bool global
    1445        38267 :                 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
    1446        38267 :               by_ref = use_pointer_for_field (decl, NULL);
    1447              : 
    1448        38267 :               if (is_task_ctx (ctx)
    1449        38267 :                   && (global || by_ref || omp_privatize_by_reference (decl)))
    1450              :                 {
    1451          619 :                   if (ctx->allocate_map
    1452          619 :                       && ctx->allocate_map->get (decl))
    1453           59 :                     install_var_field (decl, by_ref, 32 | 1, ctx);
    1454              :                   else
    1455          560 :                     install_var_field (decl, false, 1, ctx);
    1456          619 :                   if (!global)
    1457          355 :                     install_var_field (decl, by_ref, 2, ctx);
    1458              :                 }
    1459        37648 :               else if (!global)
    1460        36385 :                 install_var_field (decl, by_ref, 3, ctx);
    1461              :             }
    1462        88883 :           install_var_local (decl, ctx);
    1463              :           /* For descr arrays on target: firstprivatize data + attach ptr.  */
    1464        88883 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
    1465        45139 :               && is_gimple_omp_offloaded (ctx->stmt)
    1466        15735 :               && !is_gimple_omp_oacc (ctx->stmt)
    1467       100370 :               && lang_hooks.decls.omp_array_data (decl, true))
    1468              :             {
    1469           19 :               install_var_field (decl, false, 16 | 3, ctx);
    1470           19 :               install_var_field (decl, true, 8 | 3, ctx);
    1471              :             }
    1472              :           break;
    1473              : 
    1474         2118 :         case OMP_CLAUSE_USE_DEVICE_PTR:
    1475         2118 :         case OMP_CLAUSE_USE_DEVICE_ADDR:
    1476         2118 :           decl = OMP_CLAUSE_DECL (c);
    1477              : 
    1478              :           /* Fortran array descriptors.  */
    1479         2118 :           if (lang_hooks.decls.omp_array_data (decl, true))
    1480          601 :             install_var_field (decl, false, 19, ctx);
    1481         1517 :           else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
    1482         1312 :                     && !omp_privatize_by_reference (decl)
    1483          513 :                     && !omp_is_allocatable_or_ptr (decl))
    1484         2454 :                    || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    1485          407 :             install_var_field (decl, true, 11, ctx);
    1486              :           else
    1487         1110 :             install_var_field (decl, false, 11, ctx);
    1488         2118 :           if (DECL_SIZE (decl)
    1489         2118 :               && !poly_int_tree_p (DECL_SIZE (decl)))
    1490              :             {
    1491            6 :               tree decl2 = DECL_VALUE_EXPR (decl);
    1492            6 :               gcc_assert (INDIRECT_REF_P (decl2));
    1493            6 :               decl2 = TREE_OPERAND (decl2, 0);
    1494            6 :               gcc_assert (DECL_P (decl2));
    1495            6 :               install_var_local (decl2, ctx);
    1496              :             }
    1497         2118 :           install_var_local (decl, ctx);
    1498         2118 :           break;
    1499              : 
    1500          239 :         case OMP_CLAUSE_HAS_DEVICE_ADDR:
    1501          239 :           decl = OMP_CLAUSE_DECL (c);
    1502          239 :           while (INDIRECT_REF_P (decl)
    1503          256 :                  || TREE_CODE (decl) == ARRAY_REF)
    1504           17 :             decl = TREE_OPERAND (decl, 0);
    1505          239 :           goto do_private;
    1506              : 
    1507          149 :         case OMP_CLAUSE_IS_DEVICE_PTR:
    1508          149 :           decl = OMP_CLAUSE_DECL (c);
    1509          149 :           goto do_private;
    1510              : 
    1511        20111 :         case OMP_CLAUSE__LOOPTEMP_:
    1512        20111 :         case OMP_CLAUSE__REDUCTEMP_:
    1513        20111 :           gcc_assert (is_taskreg_ctx (ctx));
    1514        20111 :           decl = OMP_CLAUSE_DECL (c);
    1515        20111 :           install_var_field (decl, false, 3, ctx);
    1516        20111 :           install_var_local (decl, ctx);
    1517        20111 :           break;
    1518              : 
    1519          892 :         case OMP_CLAUSE_COPYPRIVATE:
    1520          892 :         case OMP_CLAUSE_COPYIN:
    1521          892 :           decl = OMP_CLAUSE_DECL (c);
    1522          892 :           by_ref = use_pointer_for_field (decl, NULL);
    1523          892 :           install_var_field (decl, by_ref, 3, ctx);
    1524          892 :           break;
    1525              : 
    1526        55102 :         case OMP_CLAUSE_FINAL:
    1527        55102 :         case OMP_CLAUSE_IF:
    1528        55102 :         case OMP_CLAUSE_SELF:
    1529        55102 :         case OMP_CLAUSE_NUM_THREADS:
    1530        55102 :         case OMP_CLAUSE_NUM_TEAMS:
    1531        55102 :         case OMP_CLAUSE_THREAD_LIMIT:
    1532        55102 :         case OMP_CLAUSE_DEVICE:
    1533        55102 :         case OMP_CLAUSE_SCHEDULE:
    1534        55102 :         case OMP_CLAUSE_DIST_SCHEDULE:
    1535        55102 :         case OMP_CLAUSE_DEPEND:
    1536        55102 :         case OMP_CLAUSE_PRIORITY:
    1537        55102 :         case OMP_CLAUSE_GRAINSIZE:
    1538        55102 :         case OMP_CLAUSE_NUM_TASKS:
    1539        55102 :         case OMP_CLAUSE_NUM_GANGS:
    1540        55102 :         case OMP_CLAUSE_NUM_WORKERS:
    1541        55102 :         case OMP_CLAUSE_VECTOR_LENGTH:
    1542        55102 :         case OMP_CLAUSE_DETACH:
    1543        55102 :         case OMP_CLAUSE_FILTER:
    1544        55102 :           if (ctx->outer)
    1545        17562 :             scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
    1546              :           break;
    1547              : 
    1548        88056 :         case OMP_CLAUSE_TO:
    1549        88056 :         case OMP_CLAUSE_FROM:
    1550        88056 :         case OMP_CLAUSE_MAP:
    1551        88056 :           if (ctx->outer)
    1552        15385 :             scan_omp_op (&OMP_CLAUSE_SIZE (c), ctx->outer);
    1553        88056 :           decl = OMP_CLAUSE_DECL (c);
    1554              :           /* If requested, make 'decl' addressable.  */
    1555        88056 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
    1556        88056 :               && OMP_CLAUSE_MAP_DECL_MAKE_ADDRESSABLE (c))
    1557              :             {
    1558          433 :               gcc_checking_assert (DECL_P (decl));
    1559              : 
    1560          433 :               bool decl_addressable = TREE_ADDRESSABLE (decl);
    1561          433 :               if (!decl_addressable)
    1562              :                 {
    1563          219 :                   if (!make_addressable_vars)
    1564          131 :                     make_addressable_vars = BITMAP_ALLOC (NULL);
    1565          219 :                   bitmap_set_bit (make_addressable_vars, DECL_UID (decl));
    1566          219 :                   TREE_ADDRESSABLE (decl) = 1;
    1567              :                 }
    1568              : 
    1569          433 :               if (dump_enabled_p ())
    1570              :                 {
    1571          421 :                   location_t loc = OMP_CLAUSE_LOCATION (c);
    1572          421 :                   const dump_user_location_t d_u_loc
    1573          421 :                     = dump_user_location_t::from_location_t (loc);
    1574              :                   /* PR100695 "Format decoder, quoting in 'dump_printf' etc." */
    1575              : #if __GNUC__ >= 10
    1576          421 : # pragma GCC diagnostic push
    1577          421 : # pragma GCC diagnostic ignored "-Wformat"
    1578              : #endif
    1579          421 :                   if (!decl_addressable)
    1580          207 :                     dump_printf_loc (MSG_NOTE, d_u_loc,
    1581              :                                      "variable %<%T%>"
    1582              :                                      " made addressable\n",
    1583              :                                      decl);
    1584              :                   else
    1585          214 :                     dump_printf_loc (MSG_NOTE, d_u_loc,
    1586              :                                      "variable %<%T%>"
    1587              :                                      " already made addressable\n",
    1588              :                                      decl);
    1589              : #if __GNUC__ >= 10
    1590          421 : # pragma GCC diagnostic pop
    1591              : #endif
    1592              :                 }
    1593              : 
    1594              :               /* Done.  */
    1595          433 :               OMP_CLAUSE_MAP_DECL_MAKE_ADDRESSABLE (c) = 0;
    1596              :             }
    1597              :           /* Global variables with "omp declare target" attribute
    1598              :              don't need to be copied, the receiver side will use them
    1599              :              directly.  However, global variables with "omp declare target link"
    1600              :              attribute need to be copied.  Or when ALWAYS modifier is used.  */
    1601        88056 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
    1602        80287 :               && DECL_P (decl)
    1603        44214 :               && ((OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
    1604        40397 :                    && (OMP_CLAUSE_MAP_KIND (c)
    1605              :                        != GOMP_MAP_FIRSTPRIVATE_REFERENCE)
    1606        39968 :                    && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
    1607        39734 :                    && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH)
    1608         4545 :                   || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    1609        40872 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_TO
    1610        40737 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_FROM
    1611        40708 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_TOFROM
    1612        40220 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_PRESENT_TO
    1613        40190 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_PRESENT_FROM
    1614        40168 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_PRESENT_TOFROM
    1615        40154 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
    1616        36165 :               && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
    1617         7559 :               && varpool_node::get_create (decl)->offloadable
    1618        93322 :               && !lookup_attribute ("omp declare target link",
    1619         5266 :                                     DECL_ATTRIBUTES (decl)))
    1620              :             break;
    1621        82818 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
    1622        82818 :               && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)
    1623              :             {
    1624              :               /* Ignore GOMP_MAP_POINTER kind for arrays in regions that are
    1625              :                  not offloaded; there is nothing to map for those.  */
    1626        10485 :               if (!is_gimple_omp_offloaded (ctx->stmt)
    1627         4978 :                   && !POINTER_TYPE_P (TREE_TYPE (decl))
    1628        10749 :                   && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
    1629              :                 break;
    1630              :             }
    1631        82554 :           if (!flex_array_ptr)
    1632        82326 :             flex_array_ptr = lang_hooks.decls.omp_deep_mapping_p (ctx->stmt, c);
    1633        82554 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
    1634        74785 :               && DECL_P (decl)
    1635        38712 :               && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
    1636        38478 :                   || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
    1637        82853 :               && is_omp_target (ctx->stmt))
    1638              :             {
    1639              :               /* If this is an offloaded region, an attach operation should
    1640              :                  only exist when the pointer variable is mapped in a prior
    1641              :                  clause.  An exception is if we have a reference (to pointer):
    1642              :                  in that case we should have mapped "*decl" in a previous
    1643              :                  mapping instead of "decl".  Skip the assertion in that case.
    1644              :                  If we had an error, we may not have attempted to sort clauses
    1645              :                  properly, so avoid the test.  */
    1646          261 :               if (TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
    1647          229 :                   && is_gimple_omp_offloaded (ctx->stmt)
    1648          331 :                   && !seen_error ())
    1649           62 :                 gcc_assert
    1650              :                   (maybe_lookup_decl (decl, ctx)
    1651              :                    || (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
    1652              :                        && lookup_attribute ("omp declare target",
    1653              :                                             DECL_ATTRIBUTES (decl))));
    1654              : 
    1655              :               /* By itself, attach/detach is generated as part of pointer
    1656              :                  variable mapping and should not create new variables in the
    1657              :                  offloaded region, however sender refs for it must be created
    1658              :                  for its address to be passed to the runtime.  */
    1659          261 :               tree field
    1660          261 :                 = build_decl (OMP_CLAUSE_LOCATION (c),
    1661              :                               FIELD_DECL, NULL_TREE, ptr_type_node);
    1662          261 :               SET_DECL_ALIGN (field, TYPE_ALIGN (ptr_type_node));
    1663          261 :               insert_field_into_struct (ctx->record_type, field);
    1664              :               /* To not clash with a map of the pointer variable itself,
    1665              :                  attach/detach maps have their field looked up by the *clause*
    1666              :                  tree expression, not the decl.  */
    1667          261 :               gcc_assert (!splay_tree_lookup (ctx->field_map,
    1668              :                                               (splay_tree_key) c));
    1669          261 :               splay_tree_insert (ctx->field_map, (splay_tree_key) c,
    1670              :                                  (splay_tree_value) field);
    1671          261 :               break;
    1672              :             }
    1673        82293 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
    1674        82293 :               && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
    1675        70709 :                   || (OMP_CLAUSE_MAP_KIND (c)
    1676              :                       == GOMP_MAP_FIRSTPRIVATE_REFERENCE)))
    1677              :             {
    1678         4244 :               if (TREE_CODE (decl) == COMPONENT_REF
    1679         4244 :                   || (INDIRECT_REF_P (decl)
    1680            0 :                       && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
    1681            0 :                       && (((TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
    1682              :                             == REFERENCE_TYPE)
    1683            0 :                            || (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
    1684              :                                == POINTER_TYPE)))))
    1685              :                 break;
    1686         4244 :               if (DECL_SIZE (decl)
    1687         4244 :                   && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
    1688              :                 {
    1689          710 :                   tree decl2 = DECL_VALUE_EXPR (decl);
    1690          710 :                   gcc_assert (INDIRECT_REF_P (decl2));
    1691          710 :                   decl2 = TREE_OPERAND (decl2, 0);
    1692          710 :                   gcc_assert (DECL_P (decl2));
    1693          710 :                   install_var_local (decl2, ctx);
    1694              :                 }
    1695         4244 :               install_var_local (decl, ctx);
    1696         4244 :               break;
    1697              :             }
    1698        78049 :           if (DECL_P (decl))
    1699              :             {
    1700        40367 :               if (DECL_SIZE (decl)
    1701        40367 :                   && !poly_int_tree_p (DECL_SIZE (decl)))
    1702              :                 {
    1703            0 :                   tree decl2 = DECL_VALUE_EXPR (decl);
    1704            0 :                   gcc_assert (INDIRECT_REF_P (decl2));
    1705            0 :                   decl2 = TREE_OPERAND (decl2, 0);
    1706            0 :                   gcc_assert (DECL_P (decl2));
    1707            0 :                   install_var_field (decl2, true, 3, ctx, c);
    1708            0 :                   install_var_local (decl2, ctx);
    1709            0 :                   install_var_local (decl, ctx);
    1710              :                 }
    1711              :               else
    1712              :                 {
    1713        40367 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
    1714        34207 :                       && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
    1715         5203 :                       && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
    1716        45570 :                       && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    1717          425 :                     install_var_field (decl, true, 7, ctx, c);
    1718              :                   else
    1719        39942 :                     install_var_field (decl, true, 3, ctx, c);
    1720        40367 :                   if (is_gimple_omp_offloaded (ctx->stmt)
    1721        40367 :                       && !(is_gimple_omp_oacc (ctx->stmt)
    1722        13857 :                            && OMP_CLAUSE_MAP_IN_REDUCTION (c)))
    1723        23702 :                     install_var_local (decl, ctx);
    1724              :                 }
    1725              :             }
    1726              :           else
    1727              :             {
    1728        37682 :               tree base = get_base_address (decl);
    1729        37682 :               tree nc = OMP_CLAUSE_CHAIN (c);
    1730        37682 :               if (DECL_P (base)
    1731         9195 :                   && nc != NULL_TREE
    1732         6635 :                   && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
    1733         5475 :                   && OMP_CLAUSE_DECL (nc) == base
    1734         1184 :                   && OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
    1735        38350 :                   && integer_zerop (OMP_CLAUSE_SIZE (nc)))
    1736              :                 {
    1737            0 :                   OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c) = 1;
    1738            0 :                   OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (nc) = 1;
    1739              :                 }
    1740              :               else
    1741              :                 {
    1742        37682 :                   if (ctx->outer)
    1743              :                     {
    1744         7152 :                       scan_omp_op (&OMP_CLAUSE_DECL (c), ctx->outer);
    1745         7152 :                       decl = OMP_CLAUSE_DECL (c);
    1746              :                     }
    1747        37682 :                   gcc_assert (!splay_tree_lookup (ctx->field_map,
    1748              :                                                   (splay_tree_key) decl));
    1749        37682 :                   tree field
    1750        37682 :                     = build_decl (OMP_CLAUSE_LOCATION (c),
    1751              :                                   FIELD_DECL, NULL_TREE, ptr_type_node);
    1752        37682 :                   SET_DECL_ALIGN (field, TYPE_ALIGN (ptr_type_node));
    1753        37682 :                   insert_field_into_struct (ctx->record_type, field);
    1754        37682 :                   splay_tree_insert (ctx->field_map, (splay_tree_key) c,
    1755              :                                      (splay_tree_value) field);
    1756              :                 }
    1757              :             }
    1758              :           break;
    1759              : 
    1760         3973 :         case OMP_CLAUSE_ORDER:
    1761         3973 :           ctx->order_concurrent = true;
    1762         3973 :           break;
    1763              : 
    1764         1907 :         case OMP_CLAUSE_BIND:
    1765         1907 :           ctx->loop_p = true;
    1766         1907 :           break;
    1767              : 
    1768              :         case OMP_CLAUSE_NOWAIT:
    1769              :         case OMP_CLAUSE_ORDERED:
    1770              :         case OMP_CLAUSE_COLLAPSE:
    1771              :         case OMP_CLAUSE_UNTIED:
    1772              :         case OMP_CLAUSE_MERGEABLE:
    1773              :         case OMP_CLAUSE_PROC_BIND:
    1774              :         case OMP_CLAUSE_SAFELEN:
    1775              :         case OMP_CLAUSE_SIMDLEN:
    1776              :         case OMP_CLAUSE_THREADS:
    1777              :         case OMP_CLAUSE_SIMD:
    1778              :         case OMP_CLAUSE_NOGROUP:
    1779              :         case OMP_CLAUSE_DEFAULTMAP:
    1780              :         case OMP_CLAUSE_ASYNC:
    1781              :         case OMP_CLAUSE_WAIT:
    1782              :         case OMP_CLAUSE_GANG:
    1783              :         case OMP_CLAUSE_WORKER:
    1784              :         case OMP_CLAUSE_VECTOR:
    1785              :         case OMP_CLAUSE_INDEPENDENT:
    1786              :         case OMP_CLAUSE_AUTO:
    1787              :         case OMP_CLAUSE_SEQ:
    1788              :         case OMP_CLAUSE_TILE:
    1789              :         case OMP_CLAUSE__SIMT_:
    1790              :         case OMP_CLAUSE_DEFAULT:
    1791              :         case OMP_CLAUSE_NONTEMPORAL:
    1792              :         case OMP_CLAUSE_IF_PRESENT:
    1793              :         case OMP_CLAUSE_FINALIZE:
    1794              :         case OMP_CLAUSE_TASK_REDUCTION:
    1795              :         case OMP_CLAUSE_ALLOCATE:
    1796              :         case OMP_CLAUSE_DEVICE_TYPE:
    1797              :           break;
    1798              : 
    1799          162 :         case OMP_CLAUSE_ALIGNED:
    1800          162 :           decl = OMP_CLAUSE_DECL (c);
    1801          162 :           if (is_global_var (decl)
    1802          162 :               && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    1803           86 :             install_var_local (decl, ctx);
    1804              :           break;
    1805              : 
    1806          361 :         case OMP_CLAUSE__CONDTEMP_:
    1807          361 :           decl = OMP_CLAUSE_DECL (c);
    1808          361 :           if (is_parallel_ctx (ctx))
    1809              :             {
    1810          118 :               install_var_field (decl, false, 3, ctx);
    1811          118 :               install_var_local (decl, ctx);
    1812              :             }
    1813          243 :           else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    1814          243 :                    && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
    1815          368 :                    && !OMP_CLAUSE__CONDTEMP__ITER (c))
    1816          125 :             install_var_local (decl, ctx);
    1817              :           break;
    1818              : 
    1819              :         case OMP_CLAUSE_INIT:
    1820              :         case OMP_CLAUSE_USE:
    1821              :         case OMP_CLAUSE_DESTROY:
    1822              :           break;
    1823              : 
    1824            0 :         case OMP_CLAUSE__CACHE_:
    1825            0 :         case OMP_CLAUSE_NOHOST:
    1826            0 :         default:
    1827            0 :           gcc_unreachable ();
    1828              :         }
    1829              :     }
    1830              : 
    1831       549329 :   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    1832              :     {
    1833       419674 :       switch (OMP_CLAUSE_CODE (c))
    1834              :         {
    1835        22736 :         case OMP_CLAUSE_LASTPRIVATE:
    1836              :           /* Let the corresponding firstprivate clause create
    1837              :              the variable.  */
    1838        22736 :           if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
    1839         7245 :             scan_array_reductions = true;
    1840        22736 :           if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
    1841              :             break;
    1842              :           /* FALLTHRU */
    1843              : 
    1844       149563 :         case OMP_CLAUSE_FIRSTPRIVATE:
    1845       149563 :         case OMP_CLAUSE_PRIVATE:
    1846       149563 :         case OMP_CLAUSE_LINEAR:
    1847       149563 :         case OMP_CLAUSE_HAS_DEVICE_ADDR:
    1848       149563 :         case OMP_CLAUSE_IS_DEVICE_PTR:
    1849       149563 :           decl = OMP_CLAUSE_DECL (c);
    1850       149563 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
    1851              :             {
    1852          256 :               while (INDIRECT_REF_P (decl)
    1853          256 :                      || TREE_CODE (decl) == ARRAY_REF)
    1854           17 :                 decl = TREE_OPERAND (decl, 0);
    1855              :             }
    1856              : 
    1857       149563 :           if (is_variable_sized (decl))
    1858              :             {
    1859          423 :               if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
    1860              :                    || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR
    1861              :                    || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
    1862           53 :                   && is_gimple_omp_offloaded (ctx->stmt))
    1863              :                 {
    1864           12 :                   tree decl2 = DECL_VALUE_EXPR (decl);
    1865           12 :                   gcc_assert (INDIRECT_REF_P (decl2));
    1866           12 :                   decl2 = TREE_OPERAND (decl2, 0);
    1867           12 :                   gcc_assert (DECL_P (decl2));
    1868           12 :                   install_var_local (decl2, ctx);
    1869           12 :                   fixup_remapped_decl (decl2, ctx, false);
    1870              :                 }
    1871          423 :               install_var_local (decl, ctx);
    1872              :             }
    1873       299126 :           fixup_remapped_decl (decl, ctx,
    1874       149563 :                                OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
    1875       149563 :                                && OMP_CLAUSE_PRIVATE_DEBUG (c));
    1876       149563 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
    1877       149563 :               && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
    1878              :             scan_array_reductions = true;
    1879              :           break;
    1880              : 
    1881        16574 :         case OMP_CLAUSE_REDUCTION:
    1882        16574 :         case OMP_CLAUSE_IN_REDUCTION:
    1883        16574 :           decl = OMP_CLAUSE_DECL (c);
    1884        16574 :           if (TREE_CODE (decl) != MEM_REF && !is_omp_target (ctx->stmt))
    1885              :             {
    1886        13873 :               if (is_variable_sized (decl))
    1887            0 :                 install_var_local (decl, ctx);
    1888        13873 :               fixup_remapped_decl (decl, ctx, false);
    1889              :             }
    1890        16574 :           if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    1891         2838 :             scan_array_reductions = true;
    1892              :           break;
    1893              : 
    1894          530 :         case OMP_CLAUSE_TASK_REDUCTION:
    1895          530 :           if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    1896         2838 :             scan_array_reductions = true;
    1897              :           break;
    1898              : 
    1899        29977 :         case OMP_CLAUSE_SHARED:
    1900              :           /* Ignore shared directives in teams construct inside of
    1901              :              target construct.  */
    1902        29977 :           if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
    1903        29977 :               && !is_host_teams_ctx (ctx))
    1904              :             break;
    1905        18121 :           decl = OMP_CLAUSE_DECL (c);
    1906        18121 :           if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
    1907              :             break;
    1908        12056 :           if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
    1909              :             {
    1910           86 :               if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl,
    1911              :                                                                  ctx->outer)))
    1912              :                 break;
    1913           79 :               bool by_ref = use_pointer_for_field (decl, ctx);
    1914           79 :               install_var_field (decl, by_ref, 11, ctx);
    1915           79 :               break;
    1916              :             }
    1917        11970 :           fixup_remapped_decl (decl, ctx, false);
    1918        11970 :           break;
    1919              : 
    1920        80287 :         case OMP_CLAUSE_MAP:
    1921        80287 :           if (!is_gimple_omp_offloaded (ctx->stmt))
    1922              :             break;
    1923        53590 :           decl = OMP_CLAUSE_DECL (c);
    1924        53590 :           if (DECL_P (decl)
    1925        33758 :               && ((OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
    1926        30109 :                    && (OMP_CLAUSE_MAP_KIND (c)
    1927              :                        != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
    1928         4078 :                   || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    1929        30883 :               && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
    1930        60973 :               && varpool_node::get_create (decl)->offloadable)
    1931              :             break;
    1932        47908 :           if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
    1933        45722 :                || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
    1934         2186 :               && is_omp_target (ctx->stmt)
    1935        49885 :               && !is_gimple_omp_offloaded (ctx->stmt))
    1936              :             break;
    1937        47908 :           if (DECL_P (decl))
    1938              :             {
    1939        28076 :               if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
    1940        25024 :                    || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
    1941         6699 :                   && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
    1942        29701 :                   && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
    1943              :                 {
    1944           24 :                   tree new_decl = lookup_decl (decl, ctx);
    1945           24 :                   TREE_TYPE (new_decl)
    1946           48 :                     = remap_type (TREE_TYPE (decl), &ctx->cb);
    1947              :                 }
    1948        28052 :               else if (DECL_SIZE (decl)
    1949        28052 :                        && !poly_int_tree_p (DECL_SIZE (decl)))
    1950              :                 {
    1951          710 :                   tree decl2 = DECL_VALUE_EXPR (decl);
    1952          710 :                   gcc_assert (INDIRECT_REF_P (decl2));
    1953          710 :                   decl2 = TREE_OPERAND (decl2, 0);
    1954          710 :                   gcc_assert (DECL_P (decl2));
    1955          710 :                   fixup_remapped_decl (decl2, ctx, false);
    1956          710 :                   fixup_remapped_decl (decl, ctx, true);
    1957              :                 }
    1958              :               else
    1959        27342 :                 fixup_remapped_decl (decl, ctx, false);
    1960              :             }
    1961              :           break;
    1962              : 
    1963              :         case OMP_CLAUSE_COPYPRIVATE:
    1964              :         case OMP_CLAUSE_COPYIN:
    1965              :         case OMP_CLAUSE_DEFAULT:
    1966              :         case OMP_CLAUSE_IF:
    1967              :         case OMP_CLAUSE_SELF:
    1968              :         case OMP_CLAUSE_NUM_THREADS:
    1969              :         case OMP_CLAUSE_NUM_TEAMS:
    1970              :         case OMP_CLAUSE_THREAD_LIMIT:
    1971              :         case OMP_CLAUSE_DEVICE:
    1972              :         case OMP_CLAUSE_SCHEDULE:
    1973              :         case OMP_CLAUSE_DIST_SCHEDULE:
    1974              :         case OMP_CLAUSE_NOWAIT:
    1975              :         case OMP_CLAUSE_ORDERED:
    1976              :         case OMP_CLAUSE_COLLAPSE:
    1977              :         case OMP_CLAUSE_UNTIED:
    1978              :         case OMP_CLAUSE_FINAL:
    1979              :         case OMP_CLAUSE_MERGEABLE:
    1980              :         case OMP_CLAUSE_PROC_BIND:
    1981              :         case OMP_CLAUSE_SAFELEN:
    1982              :         case OMP_CLAUSE_SIMDLEN:
    1983              :         case OMP_CLAUSE_ALIGNED:
    1984              :         case OMP_CLAUSE_DEPEND:
    1985              :         case OMP_CLAUSE_DETACH:
    1986              :         case OMP_CLAUSE_ALLOCATE:
    1987              :         case OMP_CLAUSE__LOOPTEMP_:
    1988              :         case OMP_CLAUSE__REDUCTEMP_:
    1989              :         case OMP_CLAUSE_TO:
    1990              :         case OMP_CLAUSE_FROM:
    1991              :         case OMP_CLAUSE_PRIORITY:
    1992              :         case OMP_CLAUSE_GRAINSIZE:
    1993              :         case OMP_CLAUSE_NUM_TASKS:
    1994              :         case OMP_CLAUSE_THREADS:
    1995              :         case OMP_CLAUSE_SIMD:
    1996              :         case OMP_CLAUSE_NOGROUP:
    1997              :         case OMP_CLAUSE_DEFAULTMAP:
    1998              :         case OMP_CLAUSE_ORDER:
    1999              :         case OMP_CLAUSE_BIND:
    2000              :         case OMP_CLAUSE_USE_DEVICE_PTR:
    2001              :         case OMP_CLAUSE_USE_DEVICE_ADDR:
    2002              :         case OMP_CLAUSE_NONTEMPORAL:
    2003              :         case OMP_CLAUSE_ASYNC:
    2004              :         case OMP_CLAUSE_WAIT:
    2005              :         case OMP_CLAUSE_NUM_GANGS:
    2006              :         case OMP_CLAUSE_NUM_WORKERS:
    2007              :         case OMP_CLAUSE_VECTOR_LENGTH:
    2008              :         case OMP_CLAUSE_GANG:
    2009              :         case OMP_CLAUSE_WORKER:
    2010              :         case OMP_CLAUSE_VECTOR:
    2011              :         case OMP_CLAUSE_INDEPENDENT:
    2012              :         case OMP_CLAUSE_AUTO:
    2013              :         case OMP_CLAUSE_SEQ:
    2014              :         case OMP_CLAUSE_TILE:
    2015              :         case OMP_CLAUSE__SIMT_:
    2016              :         case OMP_CLAUSE_IF_PRESENT:
    2017              :         case OMP_CLAUSE_FINALIZE:
    2018              :         case OMP_CLAUSE_FILTER:
    2019              :         case OMP_CLAUSE__CONDTEMP_:
    2020              :         case OMP_CLAUSE_INIT:
    2021              :         case OMP_CLAUSE_USE:
    2022              :         case OMP_CLAUSE_DESTROY:
    2023              :         case OMP_CLAUSE_DEVICE_TYPE:
    2024              :           break;
    2025              : 
    2026            0 :         case OMP_CLAUSE__CACHE_:
    2027            0 :         case OMP_CLAUSE_NOHOST:
    2028            0 :         default:
    2029            0 :           gcc_unreachable ();
    2030              :         }
    2031              :     }
    2032              : 
    2033       129655 :   gcc_checking_assert (!scan_array_reductions
    2034              :                        || !is_gimple_omp_oacc (ctx->stmt));
    2035              :   if (scan_array_reductions)
    2036              :     {
    2037        34624 :       for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    2038        29436 :         if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    2039        27056 :              || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
    2040        26432 :              || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
    2041        30140 :             && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    2042              :           {
    2043         2182 :             omp_context *rctx = ctx;
    2044         2182 :             if (is_omp_target (ctx->stmt))
    2045           60 :               rctx = ctx->outer;
    2046         2182 :             scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), rctx);
    2047         2182 :             scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), rctx);
    2048              :           }
    2049        27254 :         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    2050        27254 :                  && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
    2051         7245 :           scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
    2052        20009 :         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
    2053        20009 :                  && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
    2054          656 :           scan_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
    2055              :     }
    2056       129655 :   if (flex_array_ptr)
    2057              :     {
    2058          144 :       tree field = build_range_type (size_type_node,
    2059              :                                      build_int_cstu (size_type_node, 0),
    2060              :                                      NULL_TREE);
    2061          144 :       field = build_array_type (ptr_type_node, field);
    2062          144 :       field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, field);
    2063          144 :       SET_DECL_ALIGN (field, TYPE_ALIGN (ptr_type_node));
    2064          144 :       DECL_CONTEXT (field) = ctx->record_type;
    2065          144 :       DECL_CHAIN (field) = TYPE_FIELDS (ctx->record_type);
    2066          144 :       TYPE_FIELDS (ctx->record_type) = field;
    2067              :     }
    2068       129655 : }
    2069              : 
    2070              : /* Create a new name for omp child function.  Returns an identifier. */
    2071              : 
    2072              : static tree
    2073        51302 : create_omp_child_function_name (bool task_copy)
    2074              : {
    2075       102060 :   return clone_function_name_numbered (current_function_decl,
    2076        51302 :                                        task_copy ? "_omp_cpyfn" : "_omp_fn");
    2077              : }
    2078              : 
    2079              : /* Return true if CTX may belong to offloaded code: either if current function
    2080              :    is offloaded, or any enclosing context corresponds to a target region.  */
    2081              : 
    2082              : static bool
    2083       122569 : omp_maybe_offloaded_ctx (omp_context *ctx)
    2084              : {
    2085       122569 :   if (cgraph_node::get (current_function_decl)->offloadable)
    2086              :     return true;
    2087       202984 :   for (; ctx; ctx = ctx->outer)
    2088       120103 :     if (is_gimple_omp_offloaded (ctx->stmt))
    2089              :       return true;
    2090              :   return false;
    2091              : }
    2092              : 
    2093              : /* Build a decl for the omp child function.  It'll not contain a body
    2094              :    yet, just the bare decl.  */
    2095              : 
    2096              : static void
    2097        51302 : create_omp_child_function (omp_context *ctx, bool task_copy)
    2098              : {
    2099        51302 :   tree decl, type, name, t;
    2100              : 
    2101        51302 :   name = create_omp_child_function_name (task_copy);
    2102        51302 :   if (task_copy)
    2103          544 :     type = build_function_type_list (void_type_node, ptr_type_node,
    2104              :                                      ptr_type_node, NULL_TREE);
    2105              :   else
    2106        50758 :     type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
    2107              : 
    2108        51302 :   decl = build_decl (gimple_location (ctx->stmt), FUNCTION_DECL, name, type);
    2109              : 
    2110        51302 :   gcc_checking_assert (!is_gimple_omp_oacc (ctx->stmt)
    2111              :                        || !task_copy);
    2112        39916 :   if (!task_copy)
    2113        50758 :     ctx->cb.dst_fn = decl;
    2114              :   else
    2115          544 :     gimple_omp_task_set_copy_fn (ctx->stmt, decl);
    2116              : 
    2117        51302 :   TREE_STATIC (decl) = 1;
    2118        51302 :   TREE_USED (decl) = 1;
    2119        51302 :   DECL_ARTIFICIAL (decl) = 1;
    2120        51302 :   DECL_IGNORED_P (decl) = 0;
    2121        51302 :   TREE_PUBLIC (decl) = 0;
    2122        51302 :   DECL_UNINLINABLE (decl) = 1;
    2123        51302 :   DECL_EXTERNAL (decl) = 0;
    2124        51302 :   DECL_CONTEXT (decl) = NULL_TREE;
    2125        51302 :   DECL_INITIAL (decl) = make_node (BLOCK);
    2126        51302 :   BLOCK_SUPERCONTEXT (DECL_INITIAL (decl)) = decl;
    2127        51302 :   DECL_ATTRIBUTES (decl) = DECL_ATTRIBUTES (current_function_decl);
    2128              :   /* Remove omp declare simd attribute from the new attributes.  */
    2129        51302 :   if (tree a = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (decl)))
    2130              :     {
    2131            9 :       while (tree a2 = lookup_attribute ("omp declare simd", TREE_CHAIN (a)))
    2132              :         a = a2;
    2133            9 :       a = TREE_CHAIN (a);
    2134           22 :       for (tree *p = &DECL_ATTRIBUTES (decl); *p != a;)
    2135           13 :         if (is_attribute_p ("omp declare simd", get_attribute_name (*p)))
    2136            9 :           *p = TREE_CHAIN (*p);
    2137              :         else
    2138              :           {
    2139            4 :             tree chain = TREE_CHAIN (*p);
    2140            4 :             *p = copy_node (*p);
    2141            4 :             p = &TREE_CHAIN (*p);
    2142            4 :             *p = chain;
    2143              :           }
    2144              :     }
    2145       102604 :   DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl)
    2146        51302 :     = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (current_function_decl);
    2147       102604 :   DECL_FUNCTION_SPECIFIC_TARGET (decl)
    2148        51302 :     = DECL_FUNCTION_SPECIFIC_TARGET (current_function_decl);
    2149       102604 :   DECL_FUNCTION_VERSIONED (decl)
    2150        51302 :     = DECL_FUNCTION_VERSIONED (current_function_decl);
    2151              : 
    2152        51302 :   if (omp_maybe_offloaded_ctx (ctx))
    2153              :     {
    2154        30959 :       cgraph_node::get_create (decl)->offloadable = 1;
    2155        30959 :       if (ENABLE_OFFLOADING)
    2156              :         g->have_offload = true;
    2157              :     }
    2158              : 
    2159        51302 :   if (cgraph_node::get_create (decl)->offloadable)
    2160              :     {
    2161        30959 :       const char *target_attr = (is_gimple_omp_offloaded (ctx->stmt)
    2162        30959 :                                  ? "omp target entrypoint"
    2163         6199 :                                  : "omp declare target");
    2164        30959 :       if (lookup_attribute ("omp declare target",
    2165        30959 :                             DECL_ATTRIBUTES (current_function_decl)))
    2166              :         {
    2167         3032 :           if (is_gimple_omp_offloaded (ctx->stmt))
    2168         1620 :             DECL_ATTRIBUTES (decl)
    2169         1620 :               = remove_attribute ("omp declare target",
    2170         1620 :                                   copy_list (DECL_ATTRIBUTES (decl)));
    2171              :           else
    2172              :             target_attr = NULL;
    2173              :         }
    2174         1620 :       if (target_attr
    2175        29547 :           && is_gimple_omp_offloaded (ctx->stmt)
    2176        24760 :           && lookup_attribute ("noclone", DECL_ATTRIBUTES (decl)) == NULL_TREE)
    2177        19253 :         DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("noclone"),
    2178        19253 :                                            NULL_TREE, DECL_ATTRIBUTES (decl));
    2179        30959 :       if (target_attr)
    2180        29547 :         DECL_ATTRIBUTES (decl)
    2181        59094 :           = tree_cons (get_identifier (target_attr),
    2182        29547 :                        NULL_TREE, DECL_ATTRIBUTES (decl));
    2183              :     }
    2184              : 
    2185        51302 :   t = build_decl (DECL_SOURCE_LOCATION (decl),
    2186              :                   RESULT_DECL, NULL_TREE, void_type_node);
    2187        51302 :   DECL_ARTIFICIAL (t) = 1;
    2188        51302 :   DECL_IGNORED_P (t) = 1;
    2189        51302 :   DECL_CONTEXT (t) = decl;
    2190        51302 :   DECL_RESULT (decl) = t;
    2191              : 
    2192        51302 :   tree data_name = get_identifier (".omp_data_i");
    2193        51302 :   t = build_decl (DECL_SOURCE_LOCATION (decl), PARM_DECL, data_name,
    2194              :                   ptr_type_node);
    2195        51302 :   DECL_ARTIFICIAL (t) = 1;
    2196        51302 :   DECL_NAMELESS (t) = 1;
    2197        51302 :   DECL_ARG_TYPE (t) = ptr_type_node;
    2198        51302 :   DECL_CONTEXT (t) = current_function_decl;
    2199        51302 :   TREE_USED (t) = 1;
    2200        51302 :   TREE_READONLY (t) = 1;
    2201        51302 :   DECL_ARGUMENTS (decl) = t;
    2202        51302 :   if (!task_copy)
    2203        50758 :     ctx->receiver_decl = t;
    2204              :   else
    2205              :     {
    2206          544 :       t = build_decl (DECL_SOURCE_LOCATION (decl),
    2207              :                       PARM_DECL, get_identifier (".omp_data_o"),
    2208              :                       ptr_type_node);
    2209          544 :       DECL_ARTIFICIAL (t) = 1;
    2210          544 :       DECL_NAMELESS (t) = 1;
    2211          544 :       DECL_ARG_TYPE (t) = ptr_type_node;
    2212          544 :       DECL_CONTEXT (t) = current_function_decl;
    2213          544 :       TREE_USED (t) = 1;
    2214          544 :       TREE_ADDRESSABLE (t) = 1;
    2215          544 :       DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
    2216          544 :       DECL_ARGUMENTS (decl) = t;
    2217              :     }
    2218              : 
    2219              :   /* Allocate memory for the function structure.  The call to
    2220              :      allocate_struct_function clobbers CFUN, so we need to restore
    2221              :      it afterward.  */
    2222        51302 :   push_struct_function (decl);
    2223        51302 :   cfun->function_end_locus = gimple_location (ctx->stmt);
    2224        51302 :   init_tree_ssa (cfun);
    2225        51302 :   pop_cfun ();
    2226        51302 : }
    2227              : 
    2228              : /* Callback for walk_gimple_seq.  Check if combined parallel
    2229              :    contains gimple_omp_for_combined_into_p OMP_FOR.  */
    2230              : 
    2231              : tree
    2232        35661 : omp_find_combined_for (gimple_stmt_iterator *gsi_p,
    2233              :                        bool *handled_ops_p,
    2234              :                        struct walk_stmt_info *wi)
    2235              : {
    2236        35661 :   gimple *stmt = gsi_stmt (*gsi_p);
    2237              : 
    2238        35661 :   *handled_ops_p = true;
    2239        35661 :   switch (gimple_code (stmt))
    2240              :     {
    2241        19979 :     WALK_SUBSTMTS;
    2242              : 
    2243        13509 :     case GIMPLE_OMP_FOR:
    2244        13509 :       if (gimple_omp_for_combined_into_p (stmt)
    2245        13509 :           && gimple_omp_for_kind (stmt)
    2246         7960 :              == *(const enum gf_mask *) (wi->info))
    2247              :         {
    2248         7960 :           wi->info = stmt;
    2249         7960 :           return integer_zero_node;
    2250              :         }
    2251              :       break;
    2252              :     default:
    2253              :       break;
    2254              :     }
    2255              :   return NULL;
    2256              : }
    2257              : 
    2258              : /* Add _LOOPTEMP_/_REDUCTEMP_ clauses on OpenMP parallel or task.  */
    2259              : 
    2260              : static void
    2261        14094 : add_taskreg_looptemp_clauses (enum gf_mask msk, gimple *stmt,
    2262              :                               omp_context *outer_ctx)
    2263              : {
    2264        14094 :   struct walk_stmt_info wi;
    2265              : 
    2266        14094 :   memset (&wi, 0, sizeof (wi));
    2267        14094 :   wi.val_only = true;
    2268        14094 :   wi.info = (void *) &msk;
    2269        14094 :   walk_gimple_seq (gimple_omp_body (stmt), omp_find_combined_for, NULL, &wi);
    2270        14094 :   if (wi.info != (void *) &msk)
    2271              :     {
    2272         7960 :       gomp_for *for_stmt = as_a <gomp_for *> ((gimple *) wi.info);
    2273         7960 :       struct omp_for_data fd;
    2274         7960 :       omp_extract_for_data (for_stmt, &fd, NULL);
    2275              :       /* We need two temporaries with fd.loop.v type (istart/iend)
    2276              :          and then (fd.collapse - 1) temporaries with the same
    2277              :          type for count2 ... countN-1 vars if not constant.  */
    2278         7960 :       size_t count = 2, i;
    2279         7960 :       tree type = fd.iter_type;
    2280         7960 :       if (fd.collapse > 1
    2281         2648 :           && TREE_CODE (fd.loop.n2) != INTEGER_CST)
    2282              :         {
    2283         1466 :           count += fd.collapse - 1;
    2284              :           /* If there are lastprivate clauses on the inner
    2285              :              GIMPLE_OMP_FOR, add one more temporaries for the total number
    2286              :              of iterations (product of count1 ... countN-1).  */
    2287         1466 :           if (omp_find_clause (gimple_omp_for_clauses (for_stmt),
    2288              :                                OMP_CLAUSE_LASTPRIVATE)
    2289         1466 :               || (msk == GF_OMP_FOR_KIND_FOR
    2290         1335 :                   && omp_find_clause (gimple_omp_parallel_clauses (stmt),
    2291              :                                       OMP_CLAUSE_LASTPRIVATE)))
    2292              :             {
    2293          726 :               tree temp = create_tmp_var (type);
    2294          726 :               tree c = build_omp_clause (UNKNOWN_LOCATION,
    2295              :                                          OMP_CLAUSE__LOOPTEMP_);
    2296          726 :               insert_decl_map (&outer_ctx->cb, temp, temp);
    2297          726 :               OMP_CLAUSE_DECL (c) = temp;
    2298          726 :               OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
    2299          726 :               gimple_omp_taskreg_set_clauses (stmt, c);
    2300              :             }
    2301         1466 :           if (fd.non_rect
    2302           24 :               && fd.last_nonrect == fd.first_nonrect + 1)
    2303           12 :             if (tree v = gimple_omp_for_index (for_stmt, fd.last_nonrect))
    2304           12 :               if (!TYPE_UNSIGNED (TREE_TYPE (v)))
    2305              :                 {
    2306           12 :                   v = gimple_omp_for_index (for_stmt, fd.first_nonrect);
    2307           12 :                   tree type2 = TREE_TYPE (v);
    2308           12 :                   count++;
    2309           48 :                   for (i = 0; i < 3; i++)
    2310              :                     {
    2311           36 :                       tree temp = create_tmp_var (type2);
    2312           36 :                       tree c = build_omp_clause (UNKNOWN_LOCATION,
    2313              :                                                  OMP_CLAUSE__LOOPTEMP_);
    2314           36 :                       insert_decl_map (&outer_ctx->cb, temp, temp);
    2315           36 :                       OMP_CLAUSE_DECL (c) = temp;
    2316           36 :                       OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
    2317           36 :                       gimple_omp_taskreg_set_clauses (stmt, c);
    2318              :                     }
    2319              :                 }
    2320              :         }
    2321        26725 :       for (i = 0; i < count; i++)
    2322              :         {
    2323        18765 :           tree temp = create_tmp_var (type);
    2324        18765 :           tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_);
    2325        18765 :           insert_decl_map (&outer_ctx->cb, temp, temp);
    2326        18765 :           OMP_CLAUSE_DECL (c) = temp;
    2327        18765 :           OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
    2328        18765 :           gimple_omp_taskreg_set_clauses (stmt, c);
    2329              :         }
    2330              :     }
    2331        14094 :   if (msk == GF_OMP_FOR_KIND_TASKLOOP
    2332        15661 :       && omp_find_clause (gimple_omp_task_clauses (stmt),
    2333              :                           OMP_CLAUSE_REDUCTION))
    2334              :     {
    2335          517 :       tree type = build_pointer_type (pointer_sized_int_node);
    2336          517 :       tree temp = create_tmp_var (type);
    2337          517 :       tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
    2338          517 :       insert_decl_map (&outer_ctx->cb, temp, temp);
    2339          517 :       OMP_CLAUSE_DECL (c) = temp;
    2340          517 :       OMP_CLAUSE_CHAIN (c) = gimple_omp_task_clauses (stmt);
    2341          517 :       gimple_omp_task_set_clauses (stmt, c);
    2342              :     }
    2343        14094 : }
    2344              : 
    2345              : /* Scan an OpenMP parallel directive.  */
    2346              : 
    2347              : static void
    2348        18158 : scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
    2349              : {
    2350        18158 :   omp_context *ctx;
    2351        18158 :   tree name;
    2352        18158 :   gomp_parallel *stmt = as_a <gomp_parallel *> (gsi_stmt (*gsi));
    2353              : 
    2354              :   /* Ignore parallel directives with empty bodies, unless there
    2355              :      are copyin clauses.  */
    2356        18158 :   if (optimize > 0
    2357        12472 :       && empty_body_p (gimple_omp_body (stmt))
    2358        18203 :       && omp_find_clause (gimple_omp_parallel_clauses (stmt),
    2359              :                           OMP_CLAUSE_COPYIN) == NULL)
    2360              :     {
    2361           39 :       gsi_replace (gsi, gimple_build_nop (), false);
    2362           39 :       return;
    2363              :     }
    2364              : 
    2365        18119 :   if (gimple_omp_parallel_combined_p (stmt))
    2366        12527 :     add_taskreg_looptemp_clauses (GF_OMP_FOR_KIND_FOR, stmt, outer_ctx);
    2367        18119 :   for (tree c = omp_find_clause (gimple_omp_parallel_clauses (stmt),
    2368              :                                  OMP_CLAUSE_REDUCTION);
    2369        20947 :        c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE_REDUCTION))
    2370         3907 :     if (OMP_CLAUSE_REDUCTION_TASK (c))
    2371              :       {
    2372           67 :         tree type = build_pointer_type (pointer_sized_int_node);
    2373           67 :         tree temp = create_tmp_var (type);
    2374           67 :         tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
    2375           67 :         if (outer_ctx)
    2376           18 :           insert_decl_map (&outer_ctx->cb, temp, temp);
    2377           67 :         OMP_CLAUSE_DECL (c) = temp;
    2378           67 :         OMP_CLAUSE_CHAIN (c) = gimple_omp_parallel_clauses (stmt);
    2379           67 :         gimple_omp_parallel_set_clauses (stmt, c);
    2380           67 :         break;
    2381              :       }
    2382         3840 :     else if (OMP_CLAUSE_CHAIN (c) == NULL_TREE)
    2383              :       break;
    2384              : 
    2385        18119 :   ctx = new_omp_context (stmt, outer_ctx);
    2386        18119 :   taskreg_contexts.safe_push (ctx);
    2387        18119 :   if (taskreg_nesting_level > 1)
    2388         6191 :     ctx->is_nested = true;
    2389        18119 :   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
    2390        18119 :   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
    2391        18119 :   name = create_tmp_var_name (".omp_data_s");
    2392        18119 :   name = build_decl (gimple_location (stmt),
    2393              :                      TYPE_DECL, name, ctx->record_type);
    2394        18119 :   DECL_ARTIFICIAL (name) = 1;
    2395        18119 :   DECL_NAMELESS (name) = 1;
    2396        18119 :   TYPE_NAME (ctx->record_type) = name;
    2397        18119 :   TYPE_ARTIFICIAL (ctx->record_type) = 1;
    2398        18119 :   create_omp_child_function (ctx, false);
    2399        18119 :   gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
    2400              : 
    2401        18119 :   scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
    2402        18119 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    2403              : 
    2404        18119 :   if (TYPE_FIELDS (ctx->record_type) == NULL)
    2405         3572 :     ctx->record_type = ctx->receiver_decl = NULL;
    2406              : }
    2407              : 
    2408              : /* Scan an OpenMP task directive.  */
    2409              : 
    2410              : static void
    2411         5372 : scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
    2412              : {
    2413         5372 :   omp_context *ctx;
    2414         5372 :   tree name, t;
    2415         5372 :   gomp_task *stmt = as_a <gomp_task *> (gsi_stmt (*gsi));
    2416              : 
    2417              :   /* Ignore task directives with empty bodies, unless they have depend
    2418              :      clause.  */
    2419         5372 :   if (optimize > 0
    2420         2582 :       && gimple_omp_body (stmt)
    2421         2539 :       && empty_body_p (gimple_omp_body (stmt))
    2422         5426 :       && !omp_find_clause (gimple_omp_task_clauses (stmt), OMP_CLAUSE_DEPEND))
    2423              :     {
    2424           19 :       gsi_replace (gsi, gimple_build_nop (), false);
    2425          130 :       return;
    2426              :     }
    2427              : 
    2428         5353 :   if (gimple_omp_task_taskloop_p (stmt))
    2429         1567 :     add_taskreg_looptemp_clauses (GF_OMP_FOR_KIND_TASKLOOP, stmt, outer_ctx);
    2430              : 
    2431         5353 :   ctx = new_omp_context (stmt, outer_ctx);
    2432              : 
    2433         5353 :   if (gimple_omp_task_taskwait_p (stmt))
    2434              :     {
    2435           92 :       scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
    2436           92 :       return;
    2437              :     }
    2438              : 
    2439         5261 :   taskreg_contexts.safe_push (ctx);
    2440         5261 :   if (taskreg_nesting_level > 1)
    2441         2325 :     ctx->is_nested = true;
    2442         5261 :   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
    2443         5261 :   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
    2444         5261 :   name = create_tmp_var_name (".omp_data_s");
    2445         5261 :   name = build_decl (gimple_location (stmt),
    2446              :                      TYPE_DECL, name, ctx->record_type);
    2447         5261 :   DECL_ARTIFICIAL (name) = 1;
    2448         5261 :   DECL_NAMELESS (name) = 1;
    2449         5261 :   TYPE_NAME (ctx->record_type) = name;
    2450         5261 :   TYPE_ARTIFICIAL (ctx->record_type) = 1;
    2451         5261 :   create_omp_child_function (ctx, false);
    2452         5261 :   gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
    2453              : 
    2454         5261 :   scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
    2455              : 
    2456         5261 :   if (ctx->srecord_type)
    2457              :     {
    2458          544 :       name = create_tmp_var_name (".omp_data_a");
    2459          544 :       name = build_decl (gimple_location (stmt),
    2460              :                          TYPE_DECL, name, ctx->srecord_type);
    2461          544 :       DECL_ARTIFICIAL (name) = 1;
    2462          544 :       DECL_NAMELESS (name) = 1;
    2463          544 :       TYPE_NAME (ctx->srecord_type) = name;
    2464          544 :       TYPE_ARTIFICIAL (ctx->srecord_type) = 1;
    2465          544 :       create_omp_child_function (ctx, true);
    2466              :     }
    2467              : 
    2468         5261 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    2469              : 
    2470         5261 :   if (TYPE_FIELDS (ctx->record_type) == NULL)
    2471              :     {
    2472         1838 :       ctx->record_type = ctx->receiver_decl = NULL;
    2473         1838 :       t = build_int_cst (long_integer_type_node, 0);
    2474         1838 :       gimple_omp_task_set_arg_size (stmt, t);
    2475         1838 :       t = build_int_cst (long_integer_type_node, 1);
    2476         1838 :       gimple_omp_task_set_arg_align (stmt, t);
    2477              :     }
    2478              : }
    2479              : 
    2480              : /* Helper function for finish_taskreg_scan, called through walk_tree.
    2481              :    If maybe_lookup_decl_in_outer_context returns non-NULL for some
    2482              :    tree, replace it in the expression.  */
    2483              : 
    2484              : static tree
    2485          276 : finish_taskreg_remap (tree *tp, int *walk_subtrees, void *data)
    2486              : {
    2487          276 :   if (VAR_P (*tp))
    2488              :     {
    2489           96 :       omp_context *ctx = (omp_context *) data;
    2490           96 :       tree t = maybe_lookup_decl_in_outer_ctx (*tp, ctx);
    2491           96 :       if (t != *tp)
    2492              :         {
    2493            9 :           if (DECL_HAS_VALUE_EXPR_P (t))
    2494            0 :             t = unshare_expr (DECL_VALUE_EXPR (t));
    2495            9 :           *tp = t;
    2496              :         }
    2497           96 :       *walk_subtrees = 0;
    2498              :     }
    2499          180 :   else if (IS_TYPE_OR_DECL_P (*tp))
    2500            0 :     *walk_subtrees = 0;
    2501          276 :   return NULL_TREE;
    2502              : }
    2503              : 
    2504              : /* If any decls have been made addressable during scan_omp,
    2505              :    adjust their fields if needed, and layout record types
    2506              :    of parallel/task constructs.  */
    2507              : 
    2508              : static void
    2509        25998 : finish_taskreg_scan (omp_context *ctx)
    2510              : {
    2511        25998 :   if (ctx->record_type == NULL_TREE)
    2512              :     return;
    2513              : 
    2514              :   /* If any make_addressable_vars were needed, verify all
    2515              :      OMP_CLAUSE_SHARED clauses on GIMPLE_OMP_{PARALLEL,TASK,TEAMS}
    2516              :      statements if use_pointer_for_field hasn't changed
    2517              :      because of that.  If it did, update field types now.  */
    2518        19142 :   if (make_addressable_vars)
    2519              :     {
    2520         2209 :       tree c;
    2521              : 
    2522        12338 :       for (c = gimple_omp_taskreg_clauses (ctx->stmt);
    2523        12338 :            c; c = OMP_CLAUSE_CHAIN (c))
    2524        10129 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
    2525        10129 :             && !OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
    2526              :           {
    2527         2617 :             tree decl = OMP_CLAUSE_DECL (c);
    2528              : 
    2529              :             /* Global variables don't need to be copied,
    2530              :                the receiver side will use them directly.  */
    2531         2617 :             if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
    2532          281 :               continue;
    2533         2336 :             if (!bitmap_bit_p (make_addressable_vars, DECL_UID (decl))
    2534         2336 :                 || !use_pointer_for_field (decl, ctx))
    2535         1787 :               continue;
    2536          549 :             tree field = lookup_field (decl, ctx);
    2537          549 :             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
    2538          549 :                 && TREE_TYPE (TREE_TYPE (field)) == TREE_TYPE (decl))
    2539          495 :               continue;
    2540           54 :             TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
    2541           54 :             TREE_THIS_VOLATILE (field) = 0;
    2542           54 :             DECL_USER_ALIGN (field) = 0;
    2543           54 :             SET_DECL_ALIGN (field, TYPE_ALIGN (TREE_TYPE (field)));
    2544           54 :             if (TYPE_ALIGN (ctx->record_type) < DECL_ALIGN (field))
    2545           16 :               SET_TYPE_ALIGN (ctx->record_type, DECL_ALIGN (field));
    2546           54 :             if (ctx->srecord_type)
    2547              :               {
    2548            0 :                 tree sfield = lookup_sfield (decl, ctx);
    2549            0 :                 TREE_TYPE (sfield) = TREE_TYPE (field);
    2550            0 :                 TREE_THIS_VOLATILE (sfield) = 0;
    2551            0 :                 DECL_USER_ALIGN (sfield) = 0;
    2552            0 :                 SET_DECL_ALIGN (sfield, DECL_ALIGN (field));
    2553            0 :                 if (TYPE_ALIGN (ctx->srecord_type) < DECL_ALIGN (sfield))
    2554            0 :                   SET_TYPE_ALIGN (ctx->srecord_type, DECL_ALIGN (sfield));
    2555              :               }
    2556              :           }
    2557              :     }
    2558              : 
    2559        19142 :   if (gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
    2560              :     {
    2561        14547 :       tree clauses = gimple_omp_parallel_clauses (ctx->stmt);
    2562        14547 :       tree c = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
    2563        14547 :       if (c)
    2564              :         {
    2565              :           /* Move the _reductemp_ clause first.  GOMP_parallel_reductions
    2566              :              expects to find it at the start of data.  */
    2567           67 :           tree f = lookup_field (OMP_CLAUSE_DECL (c), ctx);
    2568           67 :           tree *p = &TYPE_FIELDS (ctx->record_type);
    2569          153 :           while (*p)
    2570          153 :             if (*p == f)
    2571              :               {
    2572           67 :                 *p = DECL_CHAIN (*p);
    2573           67 :                 break;
    2574              :               }
    2575              :             else
    2576           86 :               p = &DECL_CHAIN (*p);
    2577           67 :           DECL_CHAIN (f) = TYPE_FIELDS (ctx->record_type);
    2578           67 :           TYPE_FIELDS (ctx->record_type) = f;
    2579              :         }
    2580        14547 :       layout_type (ctx->record_type);
    2581        14547 :       fixup_child_record_type (ctx);
    2582              :     }
    2583         4595 :   else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
    2584              :     {
    2585         1172 :       layout_type (ctx->record_type);
    2586         1172 :       fixup_child_record_type (ctx);
    2587              :     }
    2588              :   else
    2589              :     {
    2590         3423 :       location_t loc = gimple_location (ctx->stmt);
    2591         3423 :       tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
    2592         3423 :       tree detach_clause
    2593         3423 :         = omp_find_clause (gimple_omp_task_clauses (ctx->stmt),
    2594              :                            OMP_CLAUSE_DETACH);
    2595              :       /* Move VLA fields to the end.  */
    2596         3423 :       p = &TYPE_FIELDS (ctx->record_type);
    2597        15322 :       while (*p)
    2598        11899 :         if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
    2599        11899 :             || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
    2600              :           {
    2601           96 :             *q = *p;
    2602           96 :             *p = TREE_CHAIN (*p);
    2603           96 :             TREE_CHAIN (*q) = NULL_TREE;
    2604           96 :             q = &TREE_CHAIN (*q);
    2605              :           }
    2606              :         else
    2607        11803 :           p = &DECL_CHAIN (*p);
    2608         3423 :       *p = vla_fields;
    2609         3423 :       if (gimple_omp_task_taskloop_p (ctx->stmt))
    2610              :         {
    2611              :           /* Move fields corresponding to first and second _looptemp_
    2612              :              clause first.  There are filled by GOMP_taskloop
    2613              :              and thus need to be in specific positions.  */
    2614         1567 :           tree clauses = gimple_omp_task_clauses (ctx->stmt);
    2615         1567 :           tree c1 = omp_find_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
    2616         1567 :           tree c2 = omp_find_clause (OMP_CLAUSE_CHAIN (c1),
    2617              :                                      OMP_CLAUSE__LOOPTEMP_);
    2618         1567 :           tree c3 = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
    2619         1567 :           tree f1 = lookup_field (OMP_CLAUSE_DECL (c1), ctx);
    2620         1567 :           tree f2 = lookup_field (OMP_CLAUSE_DECL (c2), ctx);
    2621         2084 :           tree f3 = c3 ? lookup_field (OMP_CLAUSE_DECL (c3), ctx) : NULL_TREE;
    2622         1567 :           p = &TYPE_FIELDS (ctx->record_type);
    2623         8871 :           while (*p)
    2624         7304 :             if (*p == f1 || *p == f2 || *p == f3)
    2625         3651 :               *p = DECL_CHAIN (*p);
    2626              :             else
    2627         3653 :               p = &DECL_CHAIN (*p);
    2628         1567 :           DECL_CHAIN (f1) = f2;
    2629         1567 :           if (c3)
    2630              :             {
    2631          517 :               DECL_CHAIN (f2) = f3;
    2632          517 :               DECL_CHAIN (f3) = TYPE_FIELDS (ctx->record_type);
    2633              :             }
    2634              :           else
    2635         1050 :             DECL_CHAIN (f2) = TYPE_FIELDS (ctx->record_type);
    2636         1567 :           TYPE_FIELDS (ctx->record_type) = f1;
    2637         1567 :           if (ctx->srecord_type)
    2638              :             {
    2639          389 :               f1 = lookup_sfield (OMP_CLAUSE_DECL (c1), ctx);
    2640          389 :               f2 = lookup_sfield (OMP_CLAUSE_DECL (c2), ctx);
    2641          389 :               if (c3)
    2642          186 :                 f3 = lookup_sfield (OMP_CLAUSE_DECL (c3), ctx);
    2643          389 :               p = &TYPE_FIELDS (ctx->srecord_type);
    2644         2097 :               while (*p)
    2645         1708 :                 if (*p == f1 || *p == f2 || *p == f3)
    2646          964 :                   *p = DECL_CHAIN (*p);
    2647              :                 else
    2648          744 :                   p = &DECL_CHAIN (*p);
    2649          389 :               DECL_CHAIN (f1) = f2;
    2650          389 :               DECL_CHAIN (f2) = TYPE_FIELDS (ctx->srecord_type);
    2651          389 :               if (c3)
    2652              :                 {
    2653          186 :                   DECL_CHAIN (f2) = f3;
    2654          186 :                   DECL_CHAIN (f3) = TYPE_FIELDS (ctx->srecord_type);
    2655              :                 }
    2656              :               else
    2657          203 :                 DECL_CHAIN (f2) = TYPE_FIELDS (ctx->srecord_type);
    2658          389 :               TYPE_FIELDS (ctx->srecord_type) = f1;
    2659              :             }
    2660              :         }
    2661         3423 :       if (detach_clause)
    2662              :         {
    2663          189 :           tree c, field;
    2664              : 
    2665              :           /* Look for a firstprivate clause with the detach event handle.  */
    2666          540 :           for (c = gimple_omp_taskreg_clauses (ctx->stmt);
    2667          540 :                c; c = OMP_CLAUSE_CHAIN (c))
    2668              :             {
    2669          540 :               if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
    2670          347 :                 continue;
    2671          193 :               if (maybe_lookup_decl_in_outer_ctx (OMP_CLAUSE_DECL (c), ctx)
    2672          193 :                   == OMP_CLAUSE_DECL (detach_clause))
    2673              :                 break;
    2674              :             }
    2675              : 
    2676          189 :           gcc_assert (c);
    2677          189 :           field = lookup_field (OMP_CLAUSE_DECL (c), ctx);
    2678              : 
    2679              :           /* Move field corresponding to the detach clause first.
    2680              :              This is filled by GOMP_task and needs to be in a
    2681              :              specific position.  */
    2682          189 :           p = &TYPE_FIELDS (ctx->record_type);
    2683          518 :           while (*p)
    2684          329 :             if (*p == field)
    2685          189 :               *p = DECL_CHAIN (*p);
    2686              :             else
    2687          140 :               p = &DECL_CHAIN (*p);
    2688          189 :           DECL_CHAIN (field) = TYPE_FIELDS (ctx->record_type);
    2689          189 :           TYPE_FIELDS (ctx->record_type) = field;
    2690          189 :           if (ctx->srecord_type)
    2691              :             {
    2692            3 :               field = lookup_sfield (OMP_CLAUSE_DECL (c), ctx);
    2693            3 :               p = &TYPE_FIELDS (ctx->srecord_type);
    2694            9 :               while (*p)
    2695            6 :                 if (*p == field)
    2696            3 :                   *p = DECL_CHAIN (*p);
    2697              :                 else
    2698            3 :                   p = &DECL_CHAIN (*p);
    2699            3 :               DECL_CHAIN (field) = TYPE_FIELDS (ctx->srecord_type);
    2700            3 :               TYPE_FIELDS (ctx->srecord_type) = field;
    2701              :             }
    2702              :         }
    2703         3423 :       layout_type (ctx->record_type);
    2704         3423 :       fixup_child_record_type (ctx);
    2705         3423 :       if (ctx->srecord_type)
    2706          544 :         layout_type (ctx->srecord_type);
    2707         3423 :       tree t = fold_convert_loc (loc, long_integer_type_node,
    2708         3423 :                                  TYPE_SIZE_UNIT (ctx->record_type));
    2709         3423 :       if (TREE_CODE (t) != INTEGER_CST)
    2710              :         {
    2711           21 :           t = unshare_expr (t);
    2712           21 :           walk_tree (&t, finish_taskreg_remap, ctx, NULL);
    2713              :         }
    2714         3423 :       gimple_omp_task_set_arg_size (ctx->stmt, t);
    2715         3423 :       t = build_int_cst (long_integer_type_node,
    2716         3423 :                          TYPE_ALIGN_UNIT (ctx->record_type));
    2717         3423 :       gimple_omp_task_set_arg_align (ctx->stmt, t);
    2718              :     }
    2719              : }
    2720              : 
    2721              : /* Find the enclosing offload context.  */
    2722              : 
    2723              : static omp_context *
    2724         9665 : enclosing_target_ctx (omp_context *ctx)
    2725              : {
    2726        43359 :   for (; ctx; ctx = ctx->outer)
    2727        41745 :     if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET)
    2728              :       break;
    2729              : 
    2730        22111 :   return ctx;
    2731              : }
    2732              : 
    2733              : /* Return whether CTX's parent compute construct is an OpenACC 'kernels'
    2734              :    construct.
    2735              :    (This doesn't include OpenACC 'kernels' decomposed parts.)  */
    2736              : 
    2737              : static bool
    2738        11325 : ctx_in_oacc_kernels_region (omp_context *ctx)
    2739              : {
    2740        39137 :   for (;ctx != NULL; ctx = ctx->outer)
    2741              :     {
    2742        29472 :       gimple *stmt = ctx->stmt;
    2743        29472 :       if (gimple_code (stmt) == GIMPLE_OMP_TARGET
    2744        29472 :           && gimple_omp_target_kind (stmt) == GF_OMP_TARGET_KIND_OACC_KERNELS)
    2745              :         return true;
    2746              :     }
    2747              : 
    2748              :   return false;
    2749              : }
    2750              : 
    2751              : /* Check the parallelism clauses inside a OpenACC 'kernels' region.
    2752              :    (This doesn't include OpenACC 'kernels' decomposed parts.)
    2753              :    Until kernels handling moves to use the same loop indirection
    2754              :    scheme as parallel, we need to do this checking early.  */
    2755              : 
    2756              : static unsigned
    2757         7151 : check_oacc_kernel_gwv (gomp_for *stmt, omp_context *ctx)
    2758              : {
    2759         7151 :   bool checking = true;
    2760         7151 :   unsigned outer_mask = 0;
    2761         7151 :   unsigned this_mask = 0;
    2762         7151 :   bool has_seq = false, has_auto = false;
    2763              : 
    2764         7151 :   if (ctx->outer)
    2765         4819 :     outer_mask = check_oacc_kernel_gwv (NULL,  ctx->outer);
    2766         7151 :   if (!stmt)
    2767              :     {
    2768         4819 :       checking = false;
    2769         4819 :       if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR)
    2770              :         return outer_mask;
    2771         1730 :       stmt = as_a <gomp_for *> (ctx->stmt);
    2772              :     }
    2773              : 
    2774        11330 :   for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
    2775              :     {
    2776         7268 :       switch (OMP_CLAUSE_CODE (c))
    2777              :         {
    2778          645 :         case OMP_CLAUSE_GANG:
    2779          645 :           this_mask |= GOMP_DIM_MASK (GOMP_DIM_GANG);
    2780          645 :           break;
    2781          439 :         case OMP_CLAUSE_WORKER:
    2782          439 :           this_mask |= GOMP_DIM_MASK (GOMP_DIM_WORKER);
    2783          439 :           break;
    2784          342 :         case OMP_CLAUSE_VECTOR:
    2785          342 :           this_mask |= GOMP_DIM_MASK (GOMP_DIM_VECTOR);
    2786          342 :           break;
    2787           63 :         case OMP_CLAUSE_SEQ:
    2788           63 :           has_seq = true;
    2789           63 :           break;
    2790           94 :         case OMP_CLAUSE_AUTO:
    2791           94 :           has_auto = true;
    2792           94 :           break;
    2793              :         default:
    2794              :           break;
    2795              :         }
    2796              :     }
    2797              : 
    2798         4062 :   if (checking)
    2799              :     {
    2800         2332 :       if (has_seq && (this_mask || has_auto))
    2801           36 :         error_at (gimple_location (stmt), "%<seq%> overrides other"
    2802              :                   " OpenACC loop specifiers");
    2803         2296 :       else if (has_auto && this_mask)
    2804           30 :         error_at (gimple_location (stmt), "%<auto%> conflicts with other"
    2805              :                   " OpenACC loop specifiers");
    2806              : 
    2807         2332 :       if (this_mask & outer_mask)
    2808           15 :         error_at (gimple_location (stmt), "inner loop uses same"
    2809              :                   " OpenACC parallelism as containing loop");
    2810              :     }
    2811              : 
    2812         4062 :   return outer_mask | this_mask;
    2813              : }
    2814              : 
    2815              : /* Scan a GIMPLE_OMP_FOR.  */
    2816              : 
    2817              : static omp_context *
    2818        52641 : scan_omp_for (gomp_for *stmt, omp_context *outer_ctx)
    2819              : {
    2820        52641 :   omp_context *ctx;
    2821        52641 :   size_t i;
    2822        52641 :   tree clauses = gimple_omp_for_clauses (stmt);
    2823              : 
    2824        52641 :   ctx = new_omp_context (stmt, outer_ctx);
    2825              : 
    2826        52641 :   if (is_gimple_omp_oacc (stmt))
    2827              :     {
    2828        12446 :       omp_context *tgt = enclosing_target_ctx (outer_ctx);
    2829              : 
    2830        12446 :       if (!(tgt && is_oacc_kernels (tgt)))
    2831        32251 :         for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    2832              :           {
    2833        22137 :             tree c_op0;
    2834        22137 :             switch (OMP_CLAUSE_CODE (c))
    2835              :               {
    2836         1952 :               case OMP_CLAUSE_GANG:
    2837         1952 :                 c_op0 = OMP_CLAUSE_GANG_EXPR (c);
    2838         1952 :                 break;
    2839              : 
    2840         1426 :               case OMP_CLAUSE_WORKER:
    2841         1426 :                 c_op0 = OMP_CLAUSE_WORKER_EXPR (c);
    2842         1426 :                 break;
    2843              : 
    2844         1627 :               case OMP_CLAUSE_VECTOR:
    2845         1627 :                 c_op0 = OMP_CLAUSE_VECTOR_EXPR (c);
    2846         1627 :                 break;
    2847              : 
    2848        17132 :               default:
    2849        17132 :                 continue;
    2850              :               }
    2851              : 
    2852         5005 :             if (c_op0)
    2853              :               {
    2854              :                 /* By construction, this is impossible for OpenACC 'kernels'
    2855              :                    decomposed parts.  */
    2856          210 :                 gcc_assert (!(tgt && is_oacc_kernels_decomposed_part (tgt)));
    2857              : 
    2858          210 :                 error_at (OMP_CLAUSE_LOCATION (c),
    2859              :                           "argument not permitted on %qs clause",
    2860          210 :                           omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
    2861          210 :                 if (tgt)
    2862          180 :                   inform (gimple_location (tgt->stmt),
    2863              :                           "enclosing parent compute construct");
    2864           30 :                 else if (oacc_get_fn_attrib (current_function_decl))
    2865           30 :                   inform (DECL_SOURCE_LOCATION (current_function_decl),
    2866              :                           "enclosing routine");
    2867              :                 else
    2868            0 :                   gcc_unreachable ();
    2869              :               }
    2870              :           }
    2871              : 
    2872        12446 :       if (tgt && is_oacc_kernels (tgt))
    2873         2332 :         check_oacc_kernel_gwv (stmt, ctx);
    2874              : 
    2875              :       /* Collect all variables named in reductions on this loop.  Ensure
    2876              :          that, if this loop has a reduction on some variable v, and there is
    2877              :          a reduction on v somewhere in an outer context, then there is a
    2878              :          reduction on v on all intervening loops as well.  */
    2879        12446 :       tree local_reduction_clauses = NULL;
    2880        39374 :       for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
    2881              :         {
    2882        26928 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
    2883         4712 :             local_reduction_clauses
    2884         4712 :               = tree_cons (NULL, c, local_reduction_clauses);
    2885              :         }
    2886        12446 :       if (ctx->outer_reduction_clauses == NULL && ctx->outer != NULL)
    2887        11920 :         ctx->outer_reduction_clauses
    2888        11920 :           = chainon (unshare_expr (ctx->outer->local_reduction_clauses),
    2889              :                      ctx->outer->outer_reduction_clauses);
    2890        12446 :       tree outer_reduction_clauses = ctx->outer_reduction_clauses;
    2891        12446 :       tree local_iter = local_reduction_clauses;
    2892        17158 :       for (; local_iter; local_iter = TREE_CHAIN (local_iter))
    2893              :         {
    2894         4712 :           tree local_clause = TREE_VALUE (local_iter);
    2895         4712 :           tree local_var = OMP_CLAUSE_DECL (local_clause);
    2896         4712 :           tree_code local_op = OMP_CLAUSE_REDUCTION_CODE (local_clause);
    2897         4712 :           bool have_outer_reduction = false;
    2898         4712 :           tree ctx_iter = outer_reduction_clauses;
    2899         5826 :           for (; ctx_iter; ctx_iter = TREE_CHAIN (ctx_iter))
    2900              :             {
    2901         3325 :               tree outer_clause = TREE_VALUE (ctx_iter);
    2902         3325 :               tree outer_var = OMP_CLAUSE_DECL (outer_clause);
    2903         3325 :               tree_code outer_op = OMP_CLAUSE_REDUCTION_CODE (outer_clause);
    2904         3325 :               if (outer_var == local_var && outer_op != local_op)
    2905              :                 {
    2906          535 :                   if (warning_at (OMP_CLAUSE_LOCATION (local_clause),
    2907          535 :                                   OPT_Wopenmp, "conflicting reduction "
    2908              :                                                "operations for %qE",
    2909              :                                   local_var))
    2910          535 :                     inform (OMP_CLAUSE_LOCATION (outer_clause),
    2911              :                             "location of the previous reduction for %qE",
    2912              :                             outer_var);
    2913              :                 }
    2914         3325 :               if (outer_var == local_var)
    2915              :                 {
    2916              :                   have_outer_reduction = true;
    2917              :                   break;
    2918              :                 }
    2919              :             }
    2920         4712 :           if (have_outer_reduction)
    2921              :             {
    2922              :               /* There is a reduction on outer_var both on this loop and on
    2923              :                  some enclosing loop.  Walk up the context tree until such a
    2924              :                  loop with a reduction on outer_var is found, and complain
    2925              :                  about all intervening loops that do not have such a
    2926              :                  reduction.  */
    2927         2211 :               struct omp_context *curr_loop = ctx->outer;
    2928         2211 :               bool found = false;
    2929         2826 :               while (curr_loop != NULL)
    2930              :                 {
    2931         2826 :                   tree curr_iter = curr_loop->local_reduction_clauses;
    2932         3460 :                   for (; curr_iter; curr_iter = TREE_CHAIN (curr_iter))
    2933              :                     {
    2934         2845 :                       tree curr_clause = TREE_VALUE (curr_iter);
    2935         2845 :                       tree curr_var = OMP_CLAUSE_DECL (curr_clause);
    2936         2845 :                       if (curr_var == local_var)
    2937              :                         {
    2938              :                           found = true;
    2939              :                           break;
    2940              :                         }
    2941              :                     }
    2942         2826 :                   if (!found)
    2943          615 :                     warning_at (gimple_location (curr_loop->stmt), OPT_Wopenmp,
    2944              :                                 "nested loop in reduction needs "
    2945              :                                 "reduction clause for %qE",
    2946              :                                 local_var);
    2947              :                   else
    2948              :                     break;
    2949          615 :                   curr_loop = curr_loop->outer;
    2950              :                 }
    2951              :             }
    2952              :         }
    2953        12446 :       ctx->local_reduction_clauses = local_reduction_clauses;
    2954        12446 :       ctx->outer_reduction_clauses
    2955        12446 :         = chainon (unshare_expr (ctx->local_reduction_clauses),
    2956              :                    ctx->outer_reduction_clauses);
    2957              : 
    2958        12446 :       if (tgt && is_oacc_kernels (tgt))
    2959              :         {
    2960              :           /* Strip out reductions, as they are not handled yet.  */
    2961              :           tree *prev_ptr = &clauses;
    2962              : 
    2963         7123 :           while (tree probe = *prev_ptr)
    2964              :             {
    2965         4791 :               tree *next_ptr = &OMP_CLAUSE_CHAIN (probe);
    2966              : 
    2967         4791 :               if (OMP_CLAUSE_CODE (probe) == OMP_CLAUSE_REDUCTION)
    2968          718 :                 *prev_ptr = *next_ptr;
    2969              :               else
    2970              :                 prev_ptr = next_ptr;
    2971              :             }
    2972              : 
    2973         2332 :           gimple_omp_for_set_clauses (stmt, clauses);
    2974              :         }
    2975              :     }
    2976              : 
    2977        52641 :   scan_sharing_clauses (clauses, ctx);
    2978              : 
    2979        52641 :   scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
    2980       179961 :   for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
    2981              :     {
    2982        74679 :       scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
    2983        74679 :       scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
    2984        74679 :       scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
    2985        74679 :       scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
    2986              :     }
    2987        52641 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    2988        52641 :   return ctx;
    2989              : }
    2990              : 
    2991              : /* Duplicate #pragma omp simd, one for SIMT, another one for SIMD.  */
    2992              : 
    2993              : static void
    2994            0 : scan_omp_simd (gimple_stmt_iterator *gsi, gomp_for *stmt,
    2995              :                omp_context *outer_ctx)
    2996              : {
    2997            0 :   gbind *bind = gimple_build_bind (NULL, NULL, NULL);
    2998            0 :   gsi_replace (gsi, bind, false);
    2999            0 :   gimple_seq seq = NULL;
    3000            0 :   gimple *g = gimple_build_call_internal (IFN_GOMP_USE_SIMT, 0);
    3001            0 :   tree cond = create_tmp_var_raw (integer_type_node);
    3002            0 :   DECL_CONTEXT (cond) = current_function_decl;
    3003            0 :   DECL_SEEN_IN_BIND_EXPR_P (cond) = 1;
    3004            0 :   gimple_bind_set_vars (bind, cond);
    3005            0 :   gimple_call_set_lhs (g, cond);
    3006            0 :   gimple_seq_add_stmt (&seq, g);
    3007            0 :   tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
    3008            0 :   tree lab2 = create_artificial_label (UNKNOWN_LOCATION);
    3009            0 :   tree lab3 = create_artificial_label (UNKNOWN_LOCATION);
    3010            0 :   g = gimple_build_cond (NE_EXPR, cond, integer_zero_node, lab1, lab2);
    3011            0 :   gimple_seq_add_stmt (&seq, g);
    3012            0 :   g = gimple_build_label (lab1);
    3013            0 :   gimple_seq_add_stmt (&seq, g);
    3014            0 :   gimple_seq new_seq = copy_gimple_seq_and_replace_locals (stmt);
    3015            0 :   gomp_for *new_stmt = as_a <gomp_for *> (new_seq);
    3016            0 :   tree clause = build_omp_clause (gimple_location (stmt), OMP_CLAUSE__SIMT_);
    3017            0 :   OMP_CLAUSE_CHAIN (clause) = gimple_omp_for_clauses (new_stmt);
    3018            0 :   gimple_omp_for_set_clauses (new_stmt, clause);
    3019            0 :   gimple_seq_add_stmt (&seq, new_stmt);
    3020            0 :   g = gimple_build_goto (lab3);
    3021            0 :   gimple_seq_add_stmt (&seq, g);
    3022            0 :   g = gimple_build_label (lab2);
    3023            0 :   gimple_seq_add_stmt (&seq, g);
    3024            0 :   gimple_seq_add_stmt (&seq, stmt);
    3025            0 :   g = gimple_build_label (lab3);
    3026            0 :   gimple_seq_add_stmt (&seq, g);
    3027            0 :   gimple_bind_set_body (bind, seq);
    3028            0 :   update_stmt (bind);
    3029            0 :   scan_omp_for (new_stmt, outer_ctx);
    3030            0 :   scan_omp_for (stmt, outer_ctx)->simt_stmt = new_stmt;
    3031            0 : }
    3032              : 
    3033              : static tree omp_find_scan (gimple_stmt_iterator *, bool *,
    3034              :                            struct walk_stmt_info *);
    3035              : static omp_context *maybe_lookup_ctx (gimple *);
    3036              : 
    3037              : /* Duplicate #pragma omp simd, one for the scan input phase loop and one
    3038              :    for scan phase loop.  */
    3039              : 
    3040              : static void
    3041           83 : scan_omp_simd_scan (gimple_stmt_iterator *gsi, gomp_for *stmt,
    3042              :                     omp_context *outer_ctx)
    3043              : {
    3044              :   /* The only change between inclusive and exclusive scan will be
    3045              :      within the first simd loop, so just use inclusive in the
    3046              :      worksharing loop.  */
    3047           83 :   outer_ctx->scan_inclusive = true;
    3048           83 :   tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_INCLUSIVE);
    3049           83 :   OMP_CLAUSE_DECL (c) = integer_zero_node;
    3050              : 
    3051           83 :   gomp_scan *input_stmt = gimple_build_omp_scan (NULL, NULL_TREE);
    3052           83 :   gomp_scan *scan_stmt = gimple_build_omp_scan (NULL, c);
    3053           83 :   gsi_replace (gsi, input_stmt, false);
    3054           83 :   gimple_seq input_body = NULL;
    3055           83 :   gimple_seq_add_stmt (&input_body, stmt);
    3056           83 :   gsi_insert_after (gsi, scan_stmt, GSI_NEW_STMT);
    3057              : 
    3058           83 :   gimple_stmt_iterator input1_gsi = gsi_none ();
    3059           83 :   struct walk_stmt_info wi;
    3060           83 :   memset (&wi, 0, sizeof (wi));
    3061           83 :   wi.val_only = true;
    3062           83 :   wi.info = (void *) &input1_gsi;
    3063           83 :   walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), omp_find_scan, NULL, &wi);
    3064           83 :   gcc_assert (!gsi_end_p (input1_gsi));
    3065              : 
    3066           83 :   gimple *input_stmt1 = gsi_stmt (input1_gsi);
    3067           83 :   gsi_next (&input1_gsi);
    3068           83 :   gimple *scan_stmt1 = gsi_stmt (input1_gsi);
    3069           83 :   gcc_assert (scan_stmt1 && gimple_code (scan_stmt1) == GIMPLE_OMP_SCAN);
    3070           83 :   c = gimple_omp_scan_clauses (as_a <gomp_scan *> (scan_stmt1));
    3071          166 :   if (c && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_EXCLUSIVE)
    3072              :     std::swap (input_stmt1, scan_stmt1);
    3073              : 
    3074           83 :   gimple_seq input_body1 = gimple_omp_body (input_stmt1);
    3075           83 :   gimple_omp_set_body (input_stmt1, NULL);
    3076              : 
    3077           83 :   gimple_seq scan_body = copy_gimple_seq_and_replace_locals (stmt);
    3078           83 :   gomp_for *new_stmt = as_a <gomp_for *> (scan_body);
    3079              : 
    3080           83 :   gimple_omp_set_body (input_stmt1, input_body1);
    3081           83 :   gimple_omp_set_body (scan_stmt1, NULL);
    3082              : 
    3083           83 :   gimple_stmt_iterator input2_gsi = gsi_none ();
    3084           83 :   memset (&wi, 0, sizeof (wi));
    3085           83 :   wi.val_only = true;
    3086           83 :   wi.info = (void *) &input2_gsi;
    3087           83 :   walk_gimple_seq_mod (gimple_omp_body_ptr (new_stmt), omp_find_scan,
    3088              :                        NULL, &wi);
    3089           83 :   gcc_assert (!gsi_end_p (input2_gsi));
    3090              : 
    3091           83 :   gimple *input_stmt2 = gsi_stmt (input2_gsi);
    3092           83 :   gsi_next (&input2_gsi);
    3093           83 :   gimple *scan_stmt2 = gsi_stmt (input2_gsi);
    3094           83 :   gcc_assert (scan_stmt2 && gimple_code (scan_stmt2) == GIMPLE_OMP_SCAN);
    3095          166 :   if (c && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_EXCLUSIVE)
    3096              :     std::swap (input_stmt2, scan_stmt2);
    3097              : 
    3098           83 :   gimple_omp_set_body (input_stmt2, NULL);
    3099              : 
    3100           83 :   gimple_omp_set_body (input_stmt, input_body);
    3101           83 :   gimple_omp_set_body (scan_stmt, scan_body);
    3102              : 
    3103           83 :   omp_context *ctx = new_omp_context (input_stmt, outer_ctx);
    3104           83 :   scan_omp (gimple_omp_body_ptr (input_stmt), ctx);
    3105              : 
    3106           83 :   ctx = new_omp_context (scan_stmt, outer_ctx);
    3107           83 :   scan_omp (gimple_omp_body_ptr (scan_stmt), ctx);
    3108              : 
    3109           83 :   maybe_lookup_ctx (new_stmt)->for_simd_scan_phase = true;
    3110           83 : }
    3111              : 
    3112              : /* Scan an OpenMP sections directive.  */
    3113              : 
    3114              : static void
    3115          581 : scan_omp_sections (gomp_sections *stmt, omp_context *outer_ctx)
    3116              : {
    3117          581 :   omp_context *ctx;
    3118              : 
    3119          581 :   ctx = new_omp_context (stmt, outer_ctx);
    3120          581 :   scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
    3121          581 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    3122          581 : }
    3123              : 
    3124              : /* Scan an OpenMP single directive.  */
    3125              : 
    3126              : static void
    3127         1228 : scan_omp_single (gomp_single *stmt, omp_context *outer_ctx)
    3128              : {
    3129         1228 :   omp_context *ctx;
    3130         1228 :   tree name;
    3131              : 
    3132         1228 :   ctx = new_omp_context (stmt, outer_ctx);
    3133         1228 :   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
    3134         1228 :   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
    3135         1228 :   name = create_tmp_var_name (".omp_copy_s");
    3136         1228 :   name = build_decl (gimple_location (stmt),
    3137              :                      TYPE_DECL, name, ctx->record_type);
    3138         1228 :   TYPE_NAME (ctx->record_type) = name;
    3139              : 
    3140         1228 :   scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
    3141         1228 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    3142              : 
    3143         1228 :   if (TYPE_FIELDS (ctx->record_type) == NULL)
    3144         1081 :     ctx->record_type = NULL;
    3145              :   else
    3146          147 :     layout_type (ctx->record_type);
    3147         1228 : }
    3148              : 
    3149              : /* Scan a GIMPLE_OMP_TARGET.  */
    3150              : 
    3151              : static void
    3152        41759 : scan_omp_target (gomp_target *stmt, omp_context *outer_ctx)
    3153              : {
    3154        41759 :   omp_context *ctx;
    3155        41759 :   tree name;
    3156        41759 :   bool offloaded = is_gimple_omp_offloaded (stmt);
    3157        41759 :   tree clauses = gimple_omp_target_clauses (stmt);
    3158              : 
    3159        41759 :   ctx = new_omp_context (stmt, outer_ctx);
    3160        41759 :   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
    3161        41759 :   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
    3162        41759 :   name = create_tmp_var_name (".omp_data_t");
    3163        41759 :   name = build_decl (gimple_location (stmt),
    3164              :                      TYPE_DECL, name, ctx->record_type);
    3165        41759 :   DECL_ARTIFICIAL (name) = 1;
    3166        41759 :   DECL_NAMELESS (name) = 1;
    3167        41759 :   TYPE_NAME (ctx->record_type) = name;
    3168        41759 :   TYPE_ARTIFICIAL (ctx->record_type) = 1;
    3169              : 
    3170        41759 :   if (offloaded)
    3171              :     {
    3172        24760 :       create_omp_child_function (ctx, false);
    3173        24760 :       gimple_omp_target_set_child_fn (stmt, ctx->cb.dst_fn);
    3174              :     }
    3175              : 
    3176        41759 :   scan_sharing_clauses (clauses, ctx);
    3177        41759 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    3178              : 
    3179        41759 :   if (TYPE_FIELDS (ctx->record_type) == NULL)
    3180         7854 :     ctx->record_type = ctx->receiver_decl = NULL;
    3181              :   else
    3182              :     {
    3183        33905 :       TYPE_FIELDS (ctx->record_type)
    3184        33905 :         = nreverse (TYPE_FIELDS (ctx->record_type));
    3185        33905 :       if (flag_checking)
    3186              :         {
    3187        33905 :           unsigned int align = DECL_ALIGN (TYPE_FIELDS (ctx->record_type));
    3188        33905 :           for (tree field = TYPE_FIELDS (ctx->record_type);
    3189       130644 :                field;
    3190        96739 :                field = DECL_CHAIN (field))
    3191        96739 :             gcc_assert (DECL_ALIGN (field) == align);
    3192              :         }
    3193        33905 :       layout_type (ctx->record_type);
    3194        33905 :       if (offloaded)
    3195        17465 :         fixup_child_record_type (ctx);
    3196              :     }
    3197              : 
    3198        41759 :   if (ctx->teams_nested_p && ctx->nonteams_nested_p)
    3199              :     {
    3200            4 :       error_at (gimple_location (stmt),
    3201              :                 "%<target%> construct with nested %<teams%> construct "
    3202              :                 "contains directives outside of the %<teams%> construct");
    3203            4 :       gimple_omp_set_body (stmt, gimple_build_bind (NULL, NULL, NULL));
    3204              :     }
    3205        41759 : }
    3206              : 
    3207              : /* Scan an OpenMP teams directive.  */
    3208              : 
    3209              : static void
    3210         8736 : scan_omp_teams (gomp_teams *stmt, omp_context *outer_ctx)
    3211              : {
    3212         8736 :   omp_context *ctx = new_omp_context (stmt, outer_ctx);
    3213              : 
    3214         8736 :   if (!gimple_omp_teams_host (stmt))
    3215              :     {
    3216         6118 :       scan_sharing_clauses (gimple_omp_teams_clauses (stmt), ctx);
    3217         6118 :       scan_omp (gimple_omp_body_ptr (stmt), ctx);
    3218         6118 :       return;
    3219              :     }
    3220         2618 :   taskreg_contexts.safe_push (ctx);
    3221         2618 :   gcc_assert (taskreg_nesting_level == 1);
    3222         2618 :   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
    3223         2618 :   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
    3224         2618 :   tree name = create_tmp_var_name (".omp_data_s");
    3225         2618 :   name = build_decl (gimple_location (stmt),
    3226              :                      TYPE_DECL, name, ctx->record_type);
    3227         2618 :   DECL_ARTIFICIAL (name) = 1;
    3228         2618 :   DECL_NAMELESS (name) = 1;
    3229         2618 :   TYPE_NAME (ctx->record_type) = name;
    3230         2618 :   TYPE_ARTIFICIAL (ctx->record_type) = 1;
    3231         2618 :   create_omp_child_function (ctx, false);
    3232         2618 :   gimple_omp_teams_set_child_fn (stmt, ctx->cb.dst_fn);
    3233              : 
    3234         2618 :   scan_sharing_clauses (gimple_omp_teams_clauses (stmt), ctx);
    3235         2618 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    3236              : 
    3237         2618 :   if (TYPE_FIELDS (ctx->record_type) == NULL)
    3238         1446 :     ctx->record_type = ctx->receiver_decl = NULL;
    3239              : }
    3240              : 
    3241              : /* Check nesting restrictions.  */
    3242              : static bool
    3243       156772 : check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
    3244              : {
    3245       156772 :   tree c;
    3246              : 
    3247              :   /* No nesting of non-OpenACC STMT (that is, an OpenMP one, or a GOMP builtin)
    3248              :      inside an OpenACC CTX.  */
    3249       156772 :   if (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
    3250       156772 :       || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE)
    3251              :     /* ..., except for the atomic codes that OpenACC shares with OpenMP.  */
    3252              :     ;
    3253       281683 :   else if (!(is_gimple_omp (stmt)
    3254       138731 :              && is_gimple_omp_oacc (stmt)))
    3255              :     {
    3256       112688 :       if (oacc_get_fn_attrib (cfun->decl) != NULL)
    3257              :         {
    3258           48 :           error_at (gimple_location (stmt),
    3259              :                     "non-OpenACC construct inside of OpenACC routine");
    3260           48 :           return false;
    3261              :         }
    3262              :       else
    3263       236074 :         for (omp_context *octx = ctx; octx != NULL; octx = octx->outer)
    3264       247044 :           if (is_gimple_omp (octx->stmt)
    3265       123610 :               && is_gimple_omp_oacc (octx->stmt))
    3266              :             {
    3267          176 :               error_at (gimple_location (stmt),
    3268              :                         "non-OpenACC construct inside of OpenACC region");
    3269          176 :               return false;
    3270              :             }
    3271              :     }
    3272              : 
    3273       156548 :   if (ctx != NULL)
    3274              :     {
    3275        84132 :       if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
    3276        84132 :           && gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_REGION)
    3277              :         {
    3278         8314 :           c = omp_find_clause (gimple_omp_target_clauses (ctx->stmt),
    3279              :                                OMP_CLAUSE_DEVICE);
    3280         8314 :           if (c && OMP_CLAUSE_DEVICE_ANCESTOR (c))
    3281              :             {
    3282            9 :               error_at (gimple_location (stmt),
    3283              :                         "OpenMP constructs are not allowed in target region "
    3284              :                         "with %<ancestor%>");
    3285            9 :               return false;
    3286              :             }
    3287              : 
    3288         8305 :           if (gimple_code (stmt) == GIMPLE_OMP_TEAMS && !ctx->teams_nested_p)
    3289         6114 :             ctx->teams_nested_p = true;
    3290              :           else
    3291         2191 :             ctx->nonteams_nested_p = true;
    3292              :         }
    3293        84123 :       if (gimple_code (ctx->stmt) == GIMPLE_OMP_SCAN
    3294          172 :           && ctx->outer
    3295        84295 :           && gimple_code (ctx->outer->stmt) == GIMPLE_OMP_FOR)
    3296              :         ctx = ctx->outer;
    3297        84123 :       if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    3298        28308 :           && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
    3299        85932 :           && !ctx->loop_p)
    3300              :         {
    3301         1589 :           c = NULL_TREE;
    3302         1589 :           if (ctx->order_concurrent
    3303         1589 :               && (gimple_code (stmt) == GIMPLE_OMP_ORDERED
    3304          280 :                   || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
    3305          190 :                   || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE))
    3306              :             {
    3307          210 :               error_at (gimple_location (stmt),
    3308              :                         "OpenMP constructs other than %<parallel%>, %<loop%>"
    3309              :                         " or %<simd%> may not be nested inside a region with"
    3310              :                         " the %<order(concurrent)%> clause");
    3311          210 :               return false;
    3312              :             }
    3313         1379 :           if (gimple_code (stmt) == GIMPLE_OMP_ORDERED)
    3314              :             {
    3315          133 :               c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
    3316          133 :               if (omp_find_clause (c, OMP_CLAUSE_SIMD))
    3317              :                 {
    3318          133 :                   if (omp_find_clause (c, OMP_CLAUSE_THREADS)
    3319          133 :                       && (ctx->outer == NULL
    3320           29 :                           || !gimple_omp_for_combined_into_p (ctx->stmt)
    3321           25 :                           || gimple_code (ctx->outer->stmt) != GIMPLE_OMP_FOR
    3322           25 :                           || (gimple_omp_for_kind (ctx->outer->stmt)
    3323              :                               != GF_OMP_FOR_KIND_FOR)
    3324           25 :                           || !gimple_omp_for_combined_p (ctx->outer->stmt)))
    3325              :                     {
    3326            8 :                       error_at (gimple_location (stmt),
    3327              :                                 "%<ordered simd threads%> must be closely "
    3328              :                                 "nested inside of %<%s simd%> region",
    3329            8 :                                 lang_GNU_Fortran () ? "do" : "for");
    3330            8 :                       return false;
    3331              :                     }
    3332              :                   return true;
    3333              :                 }
    3334              :             }
    3335              :           else if (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
    3336              :                    || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE
    3337              :                    || gimple_code (stmt) == GIMPLE_OMP_SCAN
    3338              :                    || gimple_code (stmt) == GIMPLE_OMP_STRUCTURED_BLOCK)
    3339              :             return true;
    3340              :           else if (gimple_code (stmt) == GIMPLE_OMP_FOR
    3341              :                    && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
    3342              :             return true;
    3343           60 :           error_at (gimple_location (stmt),
    3344              :                     "OpenMP constructs other than "
    3345              :                     "%<ordered simd%>, %<simd%>, %<loop%> or %<atomic%> may "
    3346              :                     "not be nested inside %<simd%> region");
    3347           60 :           return false;
    3348              :         }
    3349        82534 :       else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
    3350              :         {
    3351         5829 :           if ((gimple_code (stmt) != GIMPLE_OMP_FOR
    3352         5525 :                || (gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_DISTRIBUTE
    3353           25 :                    && omp_find_clause (gimple_omp_for_clauses (stmt),
    3354              :                                        OMP_CLAUSE_BIND) == NULL_TREE))
    3355         5845 :               && gimple_code (stmt) != GIMPLE_OMP_PARALLEL)
    3356              :             {
    3357          132 :               error_at (gimple_location (stmt),
    3358              :                         "only %<distribute%>, %<parallel%> or %<loop%> "
    3359              :                         "regions are allowed to be strictly nested inside "
    3360              :                         "%<teams%> region");
    3361          132 :               return false;
    3362              :             }
    3363              :         }
    3364        76705 :       else if (ctx->order_concurrent
    3365         1944 :                && gimple_code (stmt) != GIMPLE_OMP_PARALLEL
    3366         1465 :                && (gimple_code (stmt) != GIMPLE_OMP_FOR
    3367         1191 :                    || gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_SIMD)
    3368          289 :                && gimple_code (stmt) != GIMPLE_OMP_SCAN
    3369        76994 :                && gimple_code (stmt) != GIMPLE_OMP_STRUCTURED_BLOCK)
    3370              :         {
    3371          285 :           if (ctx->loop_p)
    3372          135 :             error_at (gimple_location (stmt),
    3373              :                       "OpenMP constructs other than %<parallel%>, %<loop%> or "
    3374              :                       "%<simd%> may not be nested inside a %<loop%> region");
    3375              :           else
    3376          150 :             error_at (gimple_location (stmt),
    3377              :                       "OpenMP constructs other than %<parallel%>, %<loop%> or "
    3378              :                       "%<simd%> may not be nested inside a region with "
    3379              :                       "the %<order(concurrent)%> clause");
    3380          285 :           return false;
    3381              :         }
    3382              :     }
    3383       154533 :   switch (gimple_code (stmt))
    3384              :     {
    3385        52760 :     case GIMPLE_OMP_FOR:
    3386        52760 :       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD)
    3387              :         return true;
    3388        42002 :       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
    3389              :         {
    3390         8217 :           if (ctx != NULL && gimple_code (ctx->stmt) != GIMPLE_OMP_TEAMS)
    3391              :             {
    3392            0 :               error_at (gimple_location (stmt),
    3393              :                         "%<distribute%> region must be strictly nested "
    3394              :                         "inside %<teams%> construct");
    3395            0 :               return false;
    3396              :             }
    3397              :           return true;
    3398              :         }
    3399              :       /* We split taskloop into task and nested taskloop in it.  */
    3400        33785 :       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_TASKLOOP)
    3401              :         return true;
    3402              :       /* For now, hope this will change and loop bind(parallel) will not
    3403              :          be allowed in lots of contexts.  */
    3404        30651 :       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR
    3405        48791 :           && omp_find_clause (gimple_omp_for_clauses (stmt), OMP_CLAUSE_BIND))
    3406              :         return true;
    3407        30022 :       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
    3408              :         {
    3409        12511 :           bool ok = false;
    3410              : 
    3411        12511 :           if (ctx)
    3412        11964 :             switch (gimple_code (ctx->stmt))
    3413              :               {
    3414         4049 :               case GIMPLE_OMP_FOR:
    3415         4049 :                 ok = (gimple_omp_for_kind (ctx->stmt)
    3416              :                       == GF_OMP_FOR_KIND_OACC_LOOP);
    3417         4049 :                 break;
    3418              : 
    3419         7887 :               case GIMPLE_OMP_TARGET:
    3420         7887 :                 switch (gimple_omp_target_kind (ctx->stmt))
    3421              :                   {
    3422              :                   case GF_OMP_TARGET_KIND_OACC_PARALLEL:
    3423              :                   case GF_OMP_TARGET_KIND_OACC_KERNELS:
    3424              :                   case GF_OMP_TARGET_KIND_OACC_SERIAL:
    3425              :                   case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
    3426              :                   case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
    3427              :                     ok = true;
    3428              :                     break;
    3429              : 
    3430              :                   default:
    3431              :                     break;
    3432              :                   }
    3433              : 
    3434              :               default:
    3435              :                 break;
    3436              :               }
    3437          547 :           else if (oacc_get_fn_attrib (current_function_decl))
    3438              :             ok = true;
    3439         4049 :           if (!ok)
    3440              :             {
    3441           65 :               error_at (gimple_location (stmt),
    3442              :                         "OpenACC loop directive must be associated with"
    3443              :                         " an OpenACC compute region");
    3444           65 :               return false;
    3445              :             }
    3446              :         }
    3447              :       /* FALLTHRU */
    3448        34118 :     case GIMPLE_CALL:
    3449        34118 :       if (is_gimple_call (stmt)
    3450        34118 :           && (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3451              :               == BUILT_IN_GOMP_CANCEL
    3452         3057 :               || DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3453              :                  == BUILT_IN_GOMP_CANCELLATION_POINT))
    3454              :         {
    3455         1907 :           const char *bad = NULL;
    3456         1907 :           const char *kind = NULL;
    3457         1907 :           const char *construct
    3458         1907 :             = (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3459              :                == BUILT_IN_GOMP_CANCEL)
    3460         1907 :               ? "cancel"
    3461          803 :               : "cancellation point";
    3462         1907 :           if (ctx == NULL)
    3463              :             {
    3464           41 :               error_at (gimple_location (stmt), "orphaned %qs construct",
    3465              :                         construct);
    3466           41 :               return false;
    3467              :             }
    3468         1866 :           switch (tree_fits_shwi_p (gimple_call_arg (stmt, 0))
    3469         1866 :                   ? tree_to_shwi (gimple_call_arg (stmt, 0))
    3470              :                   : 0)
    3471              :             {
    3472          528 :             case 1:
    3473          528 :               if (gimple_code (ctx->stmt) != GIMPLE_OMP_PARALLEL)
    3474              :                 bad = "parallel";
    3475          208 :               else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3476              :                        == BUILT_IN_GOMP_CANCEL
    3477          208 :                        && !integer_zerop (gimple_call_arg (stmt, 1)))
    3478          164 :                 ctx->cancellable = true;
    3479          164 :               kind = "parallel";
    3480          164 :               break;
    3481          427 :             case 2:
    3482          427 :               if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
    3483          427 :                   || gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR)
    3484              :                 bad = "for";
    3485          117 :               else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3486              :                        == BUILT_IN_GOMP_CANCEL
    3487          117 :                        && !integer_zerop (gimple_call_arg (stmt, 1)))
    3488              :                 {
    3489          106 :                   ctx->cancellable = true;
    3490          106 :                   if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    3491              :                                        OMP_CLAUSE_NOWAIT))
    3492            5 :                     warning_at (gimple_location (stmt), OPT_Wopenmp,
    3493              :                                 "%<cancel for%> inside "
    3494              :                                 "%<nowait%> for construct");
    3495          106 :                   if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    3496              :                                        OMP_CLAUSE_ORDERED))
    3497            5 :                     warning_at (gimple_location (stmt), OPT_Wopenmp,
    3498              :                                 "%<cancel for%> inside "
    3499              :                                 "%<ordered%> for construct");
    3500              :                 }
    3501            5 :               kind = "for";
    3502            5 :               break;
    3503          383 :             case 4:
    3504          383 :               if (gimple_code (ctx->stmt) != GIMPLE_OMP_SECTIONS
    3505          383 :                   && gimple_code (ctx->stmt) != GIMPLE_OMP_SECTION)
    3506              :                 bad = "sections";
    3507           93 :               else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3508              :                        == BUILT_IN_GOMP_CANCEL
    3509           93 :                        && !integer_zerop (gimple_call_arg (stmt, 1)))
    3510              :                 {
    3511           73 :                   if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
    3512              :                     {
    3513            0 :                       ctx->cancellable = true;
    3514            0 :                       if (omp_find_clause (gimple_omp_sections_clauses
    3515            0 :                                                                 (ctx->stmt),
    3516              :                                            OMP_CLAUSE_NOWAIT))
    3517            0 :                         warning_at (gimple_location (stmt), OPT_Wopenmp,
    3518              :                                     "%<cancel sections%> inside "
    3519              :                                     "%<nowait%> sections construct");
    3520              :                     }
    3521              :                   else
    3522              :                     {
    3523           73 :                       gcc_assert (ctx->outer
    3524              :                                   && gimple_code (ctx->outer->stmt)
    3525              :                                      == GIMPLE_OMP_SECTIONS);
    3526           73 :                       ctx->outer->cancellable = true;
    3527           73 :                       if (omp_find_clause (gimple_omp_sections_clauses
    3528           73 :                                                         (ctx->outer->stmt),
    3529              :                                            OMP_CLAUSE_NOWAIT))
    3530           10 :                         warning_at (gimple_location (stmt), OPT_Wopenmp,
    3531              :                                     "%<cancel sections%> inside "
    3532              :                                     "%<nowait%> sections construct");
    3533              :                     }
    3534              :                 }
    3535           10 :               kind = "sections";
    3536           10 :               break;
    3537          528 :             case 8:
    3538          528 :               if (!is_task_ctx (ctx)
    3539          528 :                   && (!is_taskloop_ctx (ctx)
    3540           54 :                       || ctx->outer == NULL
    3541           54 :                       || !is_task_ctx (ctx->outer)))
    3542              :                 bad = "task";
    3543              :               else
    3544              :                 {
    3545          248 :                   for (omp_context *octx = ctx->outer;
    3546          439 :                        octx; octx = octx->outer)
    3547              :                     {
    3548          425 :                       switch (gimple_code (octx->stmt))
    3549              :                         {
    3550              :                         case GIMPLE_OMP_TASKGROUP:
    3551              :                           break;
    3552           40 :                         case GIMPLE_OMP_TARGET:
    3553           40 :                           if (gimple_omp_target_kind (octx->stmt)
    3554              :                               != GF_OMP_TARGET_KIND_REGION)
    3555           20 :                             continue;
    3556              :                           /* FALLTHRU */
    3557           99 :                         case GIMPLE_OMP_PARALLEL:
    3558           99 :                         case GIMPLE_OMP_TEAMS:
    3559           99 :                           error_at (gimple_location (stmt),
    3560              :                                     "%<%s taskgroup%> construct not closely "
    3561              :                                     "nested inside of %<taskgroup%> region",
    3562              :                                     construct);
    3563           99 :                           return false;
    3564          104 :                         case GIMPLE_OMP_TASK:
    3565          104 :                           if (gimple_omp_task_taskloop_p (octx->stmt)
    3566           94 :                               && octx->outer
    3567          198 :                               && is_taskloop_ctx (octx->outer))
    3568              :                             {
    3569           94 :                               tree clauses
    3570           94 :                                 = gimple_omp_for_clauses (octx->outer->stmt);
    3571           94 :                               if (!omp_find_clause (clauses, OMP_CLAUSE_NOGROUP))
    3572              :                                 break;
    3573              :                             }
    3574           60 :                           continue;
    3575          111 :                         default:
    3576          111 :                           continue;
    3577          171 :                         }
    3578              :                       break;
    3579              :                     }
    3580          149 :                   ctx->cancellable = true;
    3581              :                 }
    3582          149 :               kind = "taskgroup";
    3583          149 :               break;
    3584            0 :             default:
    3585            0 :               error_at (gimple_location (stmt), "invalid arguments");
    3586            0 :               return false;
    3587              :             }
    3588          328 :           if (bad)
    3589              :             {
    3590         1200 :               error_at (gimple_location (stmt),
    3591              :                         "%<%s %s%> construct not closely nested inside of %qs",
    3592              :                         construct, kind, bad);
    3593         1200 :               return false;
    3594              :             }
    3595              :         }
    3596              :       /* FALLTHRU */
    3597              :     case GIMPLE_OMP_SECTIONS:
    3598              :     case GIMPLE_OMP_SINGLE:
    3599        55578 :       for (; ctx != NULL; ctx = ctx->outer)
    3600        37515 :         switch (gimple_code (ctx->stmt))
    3601              :           {
    3602         6873 :           case GIMPLE_OMP_FOR:
    3603         6873 :             if (gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR
    3604         6873 :                 && gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
    3605              :               break;
    3606              :             /* FALLTHRU */
    3607          778 :           case GIMPLE_OMP_SECTIONS:
    3608          778 :           case GIMPLE_OMP_SINGLE:
    3609          778 :           case GIMPLE_OMP_ORDERED:
    3610          778 :           case GIMPLE_OMP_MASTER:
    3611          778 :           case GIMPLE_OMP_MASKED:
    3612          778 :           case GIMPLE_OMP_TASK:
    3613          778 :           case GIMPLE_OMP_CRITICAL:
    3614          778 :             if (is_gimple_call (stmt))
    3615              :               {
    3616          707 :                 if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3617              :                     != BUILT_IN_GOMP_BARRIER)
    3618              :                   return true;
    3619           23 :                 error_at (gimple_location (stmt),
    3620              :                           "barrier region may not be closely nested inside "
    3621              :                           "of work-sharing, %<loop%>, %<critical%>, "
    3622              :                           "%<ordered%>, %<master%>, %<masked%>, explicit "
    3623              :                           "%<task%> or %<taskloop%> region");
    3624           23 :                 return false;
    3625              :               }
    3626           71 :             error_at (gimple_location (stmt),
    3627              :                       "work-sharing region may not be closely nested inside "
    3628              :                       "of work-sharing, %<loop%>, %<critical%>, %<ordered%>, "
    3629              :                       "%<master%>, %<masked%>, explicit %<task%> or "
    3630              :                       "%<taskloop%> region");
    3631           71 :             return false;
    3632              :           case GIMPLE_OMP_PARALLEL:
    3633              :           case GIMPLE_OMP_TEAMS:
    3634              :             return true;
    3635        13437 :           case GIMPLE_OMP_TARGET:
    3636        13437 :             if (gimple_omp_target_kind (ctx->stmt)
    3637              :                 == GF_OMP_TARGET_KIND_REGION)
    3638              :               return true;
    3639              :             break;
    3640              :           default:
    3641              :             break;
    3642              :           }
    3643              :       break;
    3644              :     case GIMPLE_OMP_MASTER:
    3645              :     case GIMPLE_OMP_MASKED:
    3646         1513 :       for (; ctx != NULL; ctx = ctx->outer)
    3647         1008 :         switch (gimple_code (ctx->stmt))
    3648              :           {
    3649           14 :           case GIMPLE_OMP_FOR:
    3650           14 :             if (gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR
    3651           14 :                 && gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
    3652              :               break;
    3653              :             /* FALLTHRU */
    3654           30 :           case GIMPLE_OMP_SECTIONS:
    3655           30 :           case GIMPLE_OMP_SINGLE:
    3656           30 :           case GIMPLE_OMP_TASK:
    3657           60 :             error_at (gimple_location (stmt),
    3658              :                       "%qs region may not be closely nested inside "
    3659              :                       "of work-sharing, %<loop%>, explicit %<task%> or "
    3660              :                       "%<taskloop%> region",
    3661           30 :                       gimple_code (stmt) == GIMPLE_OMP_MASTER
    3662              :                       ? "master" : "masked");
    3663           30 :             return false;
    3664              :           case GIMPLE_OMP_PARALLEL:
    3665              :           case GIMPLE_OMP_TEAMS:
    3666              :             return true;
    3667           10 :           case GIMPLE_OMP_TARGET:
    3668           10 :             if (gimple_omp_target_kind (ctx->stmt)
    3669              :                 == GF_OMP_TARGET_KIND_REGION)
    3670              :               return true;
    3671              :             break;
    3672              :           default:
    3673              :             break;
    3674              :           }
    3675              :       break;
    3676              :     case GIMPLE_OMP_SCOPE:
    3677          274 :       for (; ctx != NULL; ctx = ctx->outer)
    3678          175 :         switch (gimple_code (ctx->stmt))
    3679              :           {
    3680            7 :           case GIMPLE_OMP_FOR:
    3681            7 :             if (gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR
    3682            7 :                 && gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
    3683              :               break;
    3684              :             /* FALLTHRU */
    3685           25 :           case GIMPLE_OMP_SECTIONS:
    3686           25 :           case GIMPLE_OMP_SINGLE:
    3687           25 :           case GIMPLE_OMP_TASK:
    3688           25 :           case GIMPLE_OMP_CRITICAL:
    3689           25 :           case GIMPLE_OMP_ORDERED:
    3690           25 :           case GIMPLE_OMP_MASTER:
    3691           25 :           case GIMPLE_OMP_MASKED:
    3692           25 :             error_at (gimple_location (stmt),
    3693              :                       "%<scope%> region may not be closely nested inside "
    3694              :                       "of work-sharing, %<loop%>, explicit %<task%>, "
    3695              :                       "%<taskloop%>, %<critical%>, %<ordered%>, %<master%>, "
    3696              :                       "or %<masked%> region");
    3697           25 :             return false;
    3698              :           case GIMPLE_OMP_PARALLEL:
    3699              :           case GIMPLE_OMP_TEAMS:
    3700              :             return true;
    3701            5 :           case GIMPLE_OMP_TARGET:
    3702            5 :             if (gimple_omp_target_kind (ctx->stmt)
    3703              :                 == GF_OMP_TARGET_KIND_REGION)
    3704              :               return true;
    3705              :             break;
    3706              :           default:
    3707              :             break;
    3708              :           }
    3709              :       break;
    3710         5376 :     case GIMPLE_OMP_TASK:
    3711        22932 :       for (c = gimple_omp_task_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
    3712        17560 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS)
    3713              :           {
    3714            4 :             enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_KIND (c);
    3715            4 :             error_at (OMP_CLAUSE_LOCATION (c),
    3716              :                       "%<%s(%s)%> is only allowed in %<omp ordered%>",
    3717            4 :                       OMP_CLAUSE_DOACROSS_DEPEND (c) ? "depend" : "doacross",
    3718              :                       kind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
    3719            4 :             return false;
    3720              :           }
    3721              :       break;
    3722         1631 :     case GIMPLE_OMP_ORDERED:
    3723         2873 :       for (c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
    3724         2873 :            c; c = OMP_CLAUSE_CHAIN (c))
    3725              :         {
    3726         1258 :           if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DOACROSS)
    3727              :             {
    3728          169 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
    3729              :                 {
    3730            4 :                   error_at (OMP_CLAUSE_LOCATION (c),
    3731              :                             "invalid depend kind in omp %<ordered%> %<depend%>");
    3732            4 :                   return false;
    3733              :                 }
    3734          165 :               gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREADS
    3735              :                           || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SIMD);
    3736          165 :               continue;
    3737              :             }
    3738              : 
    3739         1089 :           tree oclause;
    3740              :           /* Look for containing ordered(N) loop.  */
    3741         1089 :           if (ctx == NULL
    3742         1077 :               || gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
    3743         1089 :               || (oclause
    3744         1077 :                   = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    3745              :                                      OMP_CLAUSE_ORDERED)) == NULL_TREE)
    3746              :             {
    3747           12 :               error_at (OMP_CLAUSE_LOCATION (c),
    3748              :                         "%<ordered%> construct with %<depend%> clause "
    3749              :                         "must be closely nested inside an %<ordered%> loop");
    3750           12 :               return false;
    3751              :             }
    3752              :         }
    3753         1615 :       c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
    3754         1615 :       if (omp_find_clause (c, OMP_CLAUSE_SIMD))
    3755              :         {
    3756              :           /* ordered simd must be closely nested inside of simd region,
    3757              :              and simd region must not encounter constructs other than
    3758              :              ordered simd, therefore ordered simd may be either orphaned,
    3759              :              or ctx->stmt must be simd.  The latter case is handled already
    3760              :              earlier.  */
    3761           34 :           if (ctx != NULL)
    3762              :             {
    3763           10 :               error_at (gimple_location (stmt),
    3764              :                         "%<ordered%> %<simd%> must be closely nested inside "
    3765              :                         "%<simd%> region");
    3766           10 :               return false;
    3767              :             }
    3768              :         }
    3769         1605 :       for (; ctx != NULL; ctx = ctx->outer)
    3770         1474 :         switch (gimple_code (ctx->stmt))
    3771              :           {
    3772           38 :           case GIMPLE_OMP_CRITICAL:
    3773           38 :           case GIMPLE_OMP_TASK:
    3774           38 :           case GIMPLE_OMP_ORDERED:
    3775           38 :           ordered_in_taskloop:
    3776           38 :             error_at (gimple_location (stmt),
    3777              :                       "%<ordered%> region may not be closely nested inside "
    3778              :                       "of %<critical%>, %<ordered%>, explicit %<task%> or "
    3779              :                       "%<taskloop%> region");
    3780           38 :             return false;
    3781         1416 :           case GIMPLE_OMP_FOR:
    3782         1416 :             if (gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_TASKLOOP)
    3783           10 :               goto ordered_in_taskloop;
    3784         1406 :             tree o;
    3785         1406 :             o = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    3786              :                                  OMP_CLAUSE_ORDERED);
    3787         1406 :             if (o == NULL)
    3788              :               {
    3789           22 :                 error_at (gimple_location (stmt),
    3790              :                           "%<ordered%> region must be closely nested inside "
    3791              :                           "a loop region with an %<ordered%> clause");
    3792           22 :                 return false;
    3793              :               }
    3794         1384 :             if (!gimple_omp_ordered_standalone_p (stmt))
    3795              :               {
    3796          375 :                 if (OMP_CLAUSE_ORDERED_DOACROSS (o))
    3797              :                   {
    3798           10 :                     error_at (gimple_location (stmt),
    3799              :                               "%<ordered%> construct without %<doacross%> or "
    3800              :                               "%<depend%> clauses must not have the same "
    3801              :                               "binding region as %<ordered%> construct with "
    3802              :                               "those clauses");
    3803           10 :                     return false;
    3804              :                   }
    3805          365 :                 else if (OMP_CLAUSE_ORDERED_EXPR (o))
    3806              :                   {
    3807           23 :                     tree co
    3808           23 :                       = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    3809              :                                          OMP_CLAUSE_COLLAPSE);
    3810           23 :                     HOST_WIDE_INT
    3811           23 :                       o_n = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (o));
    3812           23 :                     HOST_WIDE_INT c_n = 1;
    3813           23 :                     if (co)
    3814            5 :                       c_n = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (co));
    3815           23 :                     if (o_n != c_n)
    3816              :                       {
    3817           10 :                         error_at (gimple_location (stmt),
    3818              :                                   "%<ordered%> construct without %<doacross%> "
    3819              :                                   "or %<depend%> clauses binds to loop where "
    3820              :                                   "%<collapse%> argument %wd is different from "
    3821              :                                   "%<ordered%> argument %wd", c_n, o_n);
    3822           10 :                         return false;
    3823              :                       }
    3824              :                   }
    3825              :               }
    3826              :             return true;
    3827           10 :           case GIMPLE_OMP_TARGET:
    3828           10 :             if (gimple_omp_target_kind (ctx->stmt)
    3829              :                 != GF_OMP_TARGET_KIND_REGION)
    3830              :               break;
    3831              :             /* FALLTHRU */
    3832           30 :           case GIMPLE_OMP_PARALLEL:
    3833           30 :           case GIMPLE_OMP_TEAMS:
    3834           30 :             error_at (gimple_location (stmt),
    3835              :                       "%<ordered%> region must be closely nested inside "
    3836              :                       "a loop region with an %<ordered%> clause");
    3837           30 :             return false;
    3838              :           default:
    3839              :             break;
    3840              :           }
    3841              :       break;
    3842          462 :     case GIMPLE_OMP_CRITICAL:
    3843          462 :       {
    3844          462 :         tree this_stmt_name
    3845          462 :           = gimple_omp_critical_name (as_a <gomp_critical *> (stmt));
    3846          888 :         for (; ctx != NULL; ctx = ctx->outer)
    3847          432 :           if (gomp_critical *other_crit
    3848          451 :                 = dyn_cast <gomp_critical *> (ctx->stmt))
    3849           25 :             if (this_stmt_name == gimple_omp_critical_name (other_crit))
    3850              :               {
    3851            6 :                 error_at (gimple_location (stmt),
    3852              :                           "%<critical%> region may not be nested inside "
    3853              :                            "a %<critical%> region with the same name");
    3854            6 :                 return false;
    3855              :               }
    3856              :       }
    3857              :       break;
    3858         8780 :     case GIMPLE_OMP_TEAMS:
    3859         8780 :       if (ctx == NULL)
    3860              :         break;
    3861         6162 :       else if (gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET
    3862         6162 :                || (gimple_omp_target_kind (ctx->stmt)
    3863              :                    != GF_OMP_TARGET_KIND_REGION))
    3864              :         {
    3865              :           /* Teams construct can appear either strictly nested inside of
    3866              :              target construct with no intervening stmts, or can be encountered
    3867              :              only by initial task (so must not appear inside any OpenMP
    3868              :              construct.  */
    3869           44 :           error_at (gimple_location (stmt),
    3870              :                     "%<teams%> construct must be closely nested inside of "
    3871              :                     "%<target%> construct or not nested in any OpenMP "
    3872              :                     "construct");
    3873           44 :           return false;
    3874              :         }
    3875              :       break;
    3876        42142 :     case GIMPLE_OMP_TARGET:
    3877       188620 :       for (c = gimple_omp_target_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
    3878       146482 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS)
    3879              :           {
    3880            4 :             enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_KIND (c);
    3881            4 :             error_at (OMP_CLAUSE_LOCATION (c),
    3882              :                       "%<depend(%s)%> is only allowed in %<omp ordered%>",
    3883              :                       kind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
    3884            4 :             return false;
    3885              :           }
    3886        42138 :       if (is_gimple_omp_offloaded (stmt)
    3887        42138 :           && oacc_get_fn_attrib (cfun->decl) != NULL)
    3888              :         {
    3889            4 :           error_at (gimple_location (stmt),
    3890              :                     "OpenACC region inside of OpenACC routine, nested "
    3891              :                     "parallelism not supported yet");
    3892            4 :           return false;
    3893              :         }
    3894        49548 :       for (; ctx != NULL; ctx = ctx->outer)
    3895              :         {
    3896         7820 :           if (gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET)
    3897              :             {
    3898          768 :               if (is_gimple_omp (stmt)
    3899          768 :                   && is_gimple_omp_oacc (stmt)
    3900          242 :                   && is_gimple_omp (ctx->stmt))
    3901              :                 {
    3902          242 :                   error_at (gimple_location (stmt),
    3903              :                             "OpenACC construct inside of non-OpenACC region");
    3904          242 :                   return false;
    3905              :                 }
    3906          526 :               continue;
    3907              :             }
    3908              : 
    3909         7052 :           const char *stmt_name, *ctx_stmt_name;
    3910         7052 :           switch (gimple_omp_target_kind (stmt))
    3911              :             {
    3912              :             case GF_OMP_TARGET_KIND_REGION: stmt_name = "target"; break;
    3913          399 :             case GF_OMP_TARGET_KIND_DATA: stmt_name = "target data"; break;
    3914         1688 :             case GF_OMP_TARGET_KIND_UPDATE: stmt_name = "target update"; break;
    3915           12 :             case GF_OMP_TARGET_KIND_ENTER_DATA:
    3916           12 :               stmt_name = "target enter data"; break;
    3917           18 :             case GF_OMP_TARGET_KIND_EXIT_DATA:
    3918           18 :               stmt_name = "target exit data"; break;
    3919         1442 :             case GF_OMP_TARGET_KIND_OACC_PARALLEL: stmt_name = "parallel"; break;
    3920         1621 :             case GF_OMP_TARGET_KIND_OACC_KERNELS: stmt_name = "kernels"; break;
    3921          183 :             case GF_OMP_TARGET_KIND_OACC_SERIAL: stmt_name = "serial"; break;
    3922          386 :             case GF_OMP_TARGET_KIND_OACC_DATA: stmt_name = "data"; break;
    3923          256 :             case GF_OMP_TARGET_KIND_OACC_UPDATE: stmt_name = "update"; break;
    3924           94 :             case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
    3925           94 :               stmt_name = "enter data"; break;
    3926           86 :             case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
    3927           86 :               stmt_name = "exit data"; break;
    3928           64 :             case GF_OMP_TARGET_KIND_OACC_DECLARE: stmt_name = "declare"; break;
    3929          128 :             case GF_OMP_TARGET_KIND_OACC_HOST_DATA: stmt_name = "host_data";
    3930          128 :               break;
    3931              :             case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
    3932              :             case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
    3933              :             case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
    3934              :               /* OpenACC 'kernels' decomposed parts.  */
    3935         1621 :               stmt_name = "kernels"; break;
    3936            0 :             default: gcc_unreachable ();
    3937              :             }
    3938         7052 :           switch (gimple_omp_target_kind (ctx->stmt))
    3939              :             {
    3940              :             case GF_OMP_TARGET_KIND_REGION: ctx_stmt_name = "target"; break;
    3941         2712 :             case GF_OMP_TARGET_KIND_DATA: ctx_stmt_name = "target data"; break;
    3942           35 :             case GF_OMP_TARGET_KIND_OACC_PARALLEL:
    3943           35 :               ctx_stmt_name = "parallel"; break;
    3944              :             case GF_OMP_TARGET_KIND_OACC_KERNELS:
    3945         1037 :               ctx_stmt_name = "kernels"; break;
    3946           35 :             case GF_OMP_TARGET_KIND_OACC_SERIAL:
    3947           35 :               ctx_stmt_name = "serial"; break;
    3948         3117 :             case GF_OMP_TARGET_KIND_OACC_DATA: ctx_stmt_name = "data"; break;
    3949            8 :             case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
    3950            8 :               ctx_stmt_name = "host_data"; break;
    3951              :             case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
    3952              :             case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
    3953              :             case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
    3954              :               /* OpenACC 'kernels' decomposed parts.  */
    3955         1037 :               ctx_stmt_name = "kernels"; break;
    3956            0 :             default: gcc_unreachable ();
    3957              :             }
    3958              : 
    3959              :           /* OpenACC/OpenMP mismatch?  */
    3960        14104 :           if (is_gimple_omp_oacc (stmt)
    3961         7052 :               != is_gimple_omp_oacc (ctx->stmt))
    3962              :             {
    3963           56 :               error_at (gimple_location (stmt),
    3964              :                         "%s %qs construct inside of %s %qs region",
    3965              :                         (is_gimple_omp_oacc (stmt)
    3966              :                          ? "OpenACC" : "OpenMP"), stmt_name,
    3967              :                         (is_gimple_omp_oacc (ctx->stmt)
    3968              :                          ? "OpenACC" : "OpenMP"), ctx_stmt_name);
    3969           28 :               return false;
    3970              :             }
    3971         7024 :           if (is_gimple_omp_offloaded (ctx->stmt))
    3972              :             {
    3973              :               /* No GIMPLE_OMP_TARGET inside offloaded OpenACC CTX.  */
    3974          185 :               if (is_gimple_omp_oacc (ctx->stmt))
    3975              :                 {
    3976          105 :                   error_at (gimple_location (stmt),
    3977              :                             "%qs construct inside of %qs region",
    3978              :                             stmt_name, ctx_stmt_name);
    3979          105 :                   return false;
    3980              :                 }
    3981              :               else
    3982              :                 {
    3983           80 :                   if ((gimple_omp_target_kind (ctx->stmt)
    3984              :                        == GF_OMP_TARGET_KIND_REGION)
    3985           80 :                       && (gimple_omp_target_kind (stmt)
    3986              :                           == GF_OMP_TARGET_KIND_REGION))
    3987              :                     {
    3988           58 :                       c = omp_find_clause (gimple_omp_target_clauses (stmt),
    3989              :                                            OMP_CLAUSE_DEVICE);
    3990           58 :                       if (c && OMP_CLAUSE_DEVICE_ANCESTOR (c))
    3991              :                         break;
    3992              :                     }
    3993           49 :                   warning_at (gimple_location (stmt), OPT_Wopenmp,
    3994              :                               "%qs construct inside of %qs region",
    3995              :                               stmt_name, ctx_stmt_name);
    3996              :                 }
    3997              :             }
    3998              :         }
    3999              :       break;
    4000              :     default:
    4001              :       break;
    4002              :     }
    4003              :   return true;
    4004              : }
    4005              : 
    4006              : 
    4007              : /* Helper function scan_omp.
    4008              : 
    4009              :    Callback for walk_tree or operators in walk_gimple_stmt used to
    4010              :    scan for OMP directives in TP.  */
    4011              : 
    4012              : static tree
    4013      9784906 : scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
    4014              : {
    4015      9784906 :   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
    4016      9784906 :   omp_context *ctx = (omp_context *) wi->info;
    4017      9784906 :   tree t = *tp;
    4018      9784906 :   tree tmp;
    4019              : 
    4020      9784906 :   switch (TREE_CODE (t))
    4021              :     {
    4022      4140303 :     case VAR_DECL:
    4023      4140303 :     case PARM_DECL:
    4024      4140303 :     case LABEL_DECL:
    4025      4140303 :     case RESULT_DECL:
    4026      4140303 :       if (ctx)
    4027              :         {
    4028      2121103 :           tmp = NULL_TREE;
    4029      2121103 :           if (TREE_CODE (t) == VAR_DECL
    4030      3800016 :               && (tmp = lookup_attribute ("omp allocate var",
    4031      1678913 :                                           DECL_ATTRIBUTES (t))) != NULL_TREE)
    4032           69 :             t = TREE_VALUE (TREE_VALUE (tmp));
    4033      2121103 :           tree repl = remap_decl (t, &ctx->cb);
    4034      2121103 :           gcc_checking_assert (TREE_CODE (repl) != ERROR_MARK);
    4035      2121103 :           if (tmp != NULL_TREE  && t != repl)
    4036           31 :             *tp = build_fold_addr_expr (repl);
    4037      2121072 :           else if (tmp == NULL_TREE)
    4038      2121034 :             *tp = repl;
    4039              :         }
    4040              :       break;
    4041              : 
    4042       192104 :     case INDIRECT_REF:
    4043       192104 :     case MEM_REF:
    4044       192104 :       if (ctx
    4045        77905 :           && TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL
    4046       250992 :           && ((tmp = lookup_attribute ("omp allocate var",
    4047        58888 :                                        DECL_ATTRIBUTES (TREE_OPERAND (t, 0))))
    4048              :                != NULL_TREE))
    4049              :         {
    4050          131 :           tmp = TREE_VALUE (TREE_VALUE (tmp));
    4051          131 :           tree repl = remap_decl (tmp, &ctx->cb);
    4052          131 :           gcc_checking_assert (TREE_CODE (repl) != ERROR_MARK);
    4053          131 :           if (tmp != repl)
    4054          120 :             *tp = repl;
    4055              :           break;
    4056              :         }
    4057      5644472 :       gcc_fallthrough ();
    4058              : 
    4059      5644472 :     default:
    4060      5644472 :       if (ctx && TYPE_P (t))
    4061            5 :         *tp = remap_type (t, &ctx->cb);
    4062      5644467 :       else if (!DECL_P (t))
    4063              :         {
    4064      4682032 :           *walk_subtrees = 1;
    4065      4682032 :           if (ctx)
    4066              :             {
    4067      1424867 :               tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
    4068      1424867 :               if (tem != TREE_TYPE (t))
    4069              :                 {
    4070         9874 :                   if (TREE_CODE (t) == INTEGER_CST)
    4071         4166 :                     *tp = wide_int_to_tree (tem, wi::to_wide (t));
    4072              :                   else
    4073         5708 :                     TREE_TYPE (t) = tem;
    4074              :                 }
    4075              :             }
    4076              :         }
    4077              :       break;
    4078              :     }
    4079              : 
    4080      9784906 :   return NULL_TREE;
    4081              : }
    4082              : 
    4083              : /* Return true if FNDECL is a setjmp or a longjmp.  */
    4084              : 
    4085              : static bool
    4086         3042 : setjmp_or_longjmp_p (const_tree fndecl)
    4087              : {
    4088         3042 :   if (fndecl_built_in_p (fndecl, BUILT_IN_SETJMP, BUILT_IN_LONGJMP))
    4089              :     return true;
    4090              : 
    4091         3042 :   tree declname = DECL_NAME (fndecl);
    4092         3042 :   if (!declname
    4093         3042 :       || (DECL_CONTEXT (fndecl) != NULL_TREE
    4094         2347 :           && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL)
    4095         5833 :       || !TREE_PUBLIC (fndecl))
    4096              :     return false;
    4097              : 
    4098         2629 :   const char *name = IDENTIFIER_POINTER (declname);
    4099         2629 :   return !strcmp (name, "setjmp") || !strcmp (name, "longjmp");
    4100              : }
    4101              : 
    4102              : /* Helper function for scan_omp.
    4103              : 
    4104              :    Callback for walk_gimple_stmt used to scan for OMP directives in
    4105              :    the current statement in GSI.  */
    4106              : 
    4107              : static tree
    4108      3397896 : scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
    4109              :                  struct walk_stmt_info *wi)
    4110              : {
    4111      3397896 :   gimple *stmt = gsi_stmt (*gsi);
    4112      3397896 :   omp_context *ctx = (omp_context *) wi->info;
    4113              : 
    4114      3397896 :   if (gimple_has_location (stmt))
    4115      2772521 :     input_location = gimple_location (stmt);
    4116              : 
    4117              :   /* Check the nesting restrictions.  */
    4118      3397896 :   bool remove = false;
    4119      3397896 :   if (is_gimple_omp (stmt))
    4120       152551 :     remove = !check_omp_nesting_restrictions (stmt, ctx);
    4121      3245345 :   else if (is_gimple_call (stmt))
    4122              :     {
    4123       230798 :       tree fndecl = gimple_call_fndecl (stmt);
    4124       230798 :       if (fndecl)
    4125              :         {
    4126       215019 :           if (ctx
    4127        67739 :               && gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    4128        14654 :               && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
    4129         3042 :               && setjmp_or_longjmp_p (fndecl)
    4130       215027 :               && !ctx->loop_p)
    4131              :             {
    4132            4 :               remove = true;
    4133            4 :               error_at (gimple_location (stmt),
    4134              :                         "setjmp/longjmp inside %<simd%> construct");
    4135              :             }
    4136       215015 :           else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
    4137        63293 :             switch (DECL_FUNCTION_CODE (fndecl))
    4138              :               {
    4139         4221 :               case BUILT_IN_GOMP_BARRIER:
    4140         4221 :               case BUILT_IN_GOMP_CANCEL:
    4141         4221 :               case BUILT_IN_GOMP_CANCELLATION_POINT:
    4142         4221 :               case BUILT_IN_GOMP_TASKYIELD:
    4143         4221 :               case BUILT_IN_GOMP_TASKWAIT:
    4144         4221 :               case BUILT_IN_GOMP_TASKGROUP_START:
    4145         4221 :               case BUILT_IN_GOMP_TASKGROUP_END:
    4146         4221 :                 remove = !check_omp_nesting_restrictions (stmt, ctx);
    4147         4221 :                 break;
    4148              :               default:
    4149              :                 break;
    4150              :               }
    4151       151722 :           else if (ctx)
    4152              :             {
    4153        45802 :               omp_context *octx = ctx;
    4154        45802 :               if (gimple_code (ctx->stmt) == GIMPLE_OMP_SCAN && ctx->outer)
    4155        45802 :                 octx = ctx->outer;
    4156        45802 :               if (octx->order_concurrent && omp_runtime_api_call (fndecl))
    4157              :                 {
    4158          240 :                   remove = true;
    4159          240 :                   error_at (gimple_location (stmt),
    4160              :                             "OpenMP runtime API call %qD in a region with "
    4161              :                             "%<order(concurrent)%> clause", fndecl);
    4162              :                 }
    4163        45802 :               if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
    4164         3293 :                   && omp_runtime_api_call (fndecl)
    4165          315 :                   && ((IDENTIFIER_LENGTH (DECL_NAME (fndecl))
    4166              :                        != strlen ("omp_get_num_teams"))
    4167          182 :                       || strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)),
    4168              :                                  "omp_get_num_teams") != 0)
    4169        45950 :                   && ((IDENTIFIER_LENGTH (DECL_NAME (fndecl))
    4170              :                        != strlen ("omp_get_team_num"))
    4171          121 :                       || strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)),
    4172              :                                  "omp_get_team_num") != 0))
    4173              :                 {
    4174           27 :                   remove = true;
    4175           27 :                   error_at (gimple_location (stmt),
    4176              :                             "OpenMP runtime API call %qD strictly nested in a "
    4177              :                             "%<teams%> region", fndecl);
    4178              :                 }
    4179        45802 :               if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
    4180        13287 :                   && (gimple_omp_target_kind (ctx->stmt)
    4181              :                       == GF_OMP_TARGET_KIND_REGION)
    4182        50703 :                   && omp_runtime_api_call (fndecl))
    4183              :                 {
    4184          365 :                   tree tgt_clauses = gimple_omp_target_clauses (ctx->stmt);
    4185          365 :                   tree c = omp_find_clause (tgt_clauses, OMP_CLAUSE_DEVICE);
    4186          365 :                   if (c && OMP_CLAUSE_DEVICE_ANCESTOR (c))
    4187            5 :                     error_at (gimple_location (stmt),
    4188              :                               "OpenMP runtime API call %qD in a region with "
    4189              :                               "%<device(ancestor)%> clause", fndecl);
    4190              :                 }
    4191              :             }
    4192              :         }
    4193              :     }
    4194       202578 :   if (remove)
    4195              :     {
    4196         3326 :       stmt = gimple_build_nop ();
    4197         3326 :       gsi_replace (gsi, stmt, false);
    4198              :     }
    4199              : 
    4200      3397896 :   *handled_ops_p = true;
    4201              : 
    4202      3397896 :   switch (gimple_code (stmt))
    4203              :     {
    4204        18158 :     case GIMPLE_OMP_PARALLEL:
    4205        18158 :       taskreg_nesting_level++;
    4206        18158 :       scan_omp_parallel (gsi, ctx);
    4207        18158 :       taskreg_nesting_level--;
    4208        18158 :       break;
    4209              : 
    4210         5372 :     case GIMPLE_OMP_TASK:
    4211         5372 :       taskreg_nesting_level++;
    4212         5372 :       scan_omp_task (gsi, ctx);
    4213         5372 :       taskreg_nesting_level--;
    4214         5372 :       break;
    4215              : 
    4216        52724 :     case GIMPLE_OMP_FOR:
    4217        52724 :       if ((gimple_omp_for_kind (as_a <gomp_for *> (stmt))
    4218              :            == GF_OMP_FOR_KIND_SIMD)
    4219        10810 :           && gimple_omp_for_combined_into_p (stmt)
    4220        60416 :           && gimple_code (ctx->stmt) != GIMPLE_OMP_SCAN)
    4221              :         {
    4222         7526 :           tree clauses = gimple_omp_for_clauses (as_a <gomp_for *> (stmt));
    4223         7526 :           tree c = omp_find_clause (clauses, OMP_CLAUSE_REDUCTION);
    4224         7526 :           if (c && OMP_CLAUSE_REDUCTION_INSCAN (c) && !seen_error ())
    4225              :             {
    4226           83 :               scan_omp_simd_scan (gsi, as_a <gomp_for *> (stmt), ctx);
    4227           83 :               break;
    4228              :             }
    4229              :         }
    4230        52641 :       if ((gimple_omp_for_kind (as_a <gomp_for *> (stmt))
    4231              :            == GF_OMP_FOR_KIND_SIMD)
    4232        10727 :           && omp_maybe_offloaded_ctx (ctx)
    4233         3641 :           && omp_max_simt_vf ()
    4234        52641 :           && gimple_omp_for_collapse (stmt) == 1)
    4235            0 :         scan_omp_simd (gsi, as_a <gomp_for *> (stmt), ctx);
    4236              :       else
    4237        52641 :         scan_omp_for (as_a <gomp_for *> (stmt), ctx);
    4238              :       break;
    4239              : 
    4240          184 :     case GIMPLE_OMP_SCOPE:
    4241          184 :       ctx = new_omp_context (stmt, ctx);
    4242          184 :       scan_sharing_clauses (gimple_omp_scope_clauses (stmt), ctx);
    4243          184 :       scan_omp (gimple_omp_body_ptr (stmt), ctx);
    4244          184 :       break;
    4245              : 
    4246          852 :     case GIMPLE_OMP_DISPATCH:
    4247          852 :       ctx = new_omp_context (stmt, ctx);
    4248          852 :       scan_omp (gimple_omp_body_ptr (stmt), ctx);
    4249          852 :       break;
    4250              : 
    4251          612 :     case GIMPLE_OMP_INTEROP:
    4252          612 :       ctx = new_omp_context (stmt, ctx);
    4253          612 :       break;
    4254              : 
    4255          581 :     case GIMPLE_OMP_SECTIONS:
    4256          581 :       scan_omp_sections (as_a <gomp_sections *> (stmt), ctx);
    4257          581 :       break;
    4258              : 
    4259         1228 :     case GIMPLE_OMP_SINGLE:
    4260         1228 :       scan_omp_single (as_a <gomp_single *> (stmt), ctx);
    4261         1228 :       break;
    4262              : 
    4263         1284 :     case GIMPLE_OMP_SCAN:
    4264         1284 :       if (tree clauses = gimple_omp_scan_clauses (as_a <gomp_scan *> (stmt)))
    4265              :         {
    4266          606 :           if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_INCLUSIVE)
    4267          304 :             ctx->scan_inclusive = true;
    4268          302 :           else if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_EXCLUSIVE)
    4269          302 :             ctx->scan_exclusive = true;
    4270              :         }
    4271              :       /* FALLTHRU */
    4272         6207 :     case GIMPLE_OMP_SECTION:
    4273         6207 :     case GIMPLE_OMP_STRUCTURED_BLOCK:
    4274         6207 :     case GIMPLE_OMP_MASTER:
    4275         6207 :     case GIMPLE_OMP_ORDERED:
    4276         6207 :     case GIMPLE_OMP_CRITICAL:
    4277         6207 :       ctx = new_omp_context (stmt, ctx);
    4278         6207 :       scan_omp (gimple_omp_body_ptr (stmt), ctx);
    4279         6207 :       break;
    4280              : 
    4281          447 :     case GIMPLE_OMP_MASKED:
    4282          447 :       ctx = new_omp_context (stmt, ctx);
    4283          447 :       scan_sharing_clauses (gimple_omp_masked_clauses (stmt), ctx);
    4284          447 :       scan_omp (gimple_omp_body_ptr (stmt), ctx);
    4285          447 :       break;
    4286              : 
    4287          607 :     case GIMPLE_OMP_TASKGROUP:
    4288          607 :       ctx = new_omp_context (stmt, ctx);
    4289          607 :       scan_sharing_clauses (gimple_omp_taskgroup_clauses (stmt), ctx);
    4290          607 :       scan_omp (gimple_omp_body_ptr (stmt), ctx);
    4291          607 :       break;
    4292              : 
    4293        41759 :     case GIMPLE_OMP_TARGET:
    4294        41759 :       if (is_gimple_omp_offloaded (stmt))
    4295              :         {
    4296        24760 :           taskreg_nesting_level++;
    4297        24760 :           scan_omp_target (as_a <gomp_target *> (stmt), ctx);
    4298        24760 :           taskreg_nesting_level--;
    4299              :         }
    4300              :       else
    4301        16999 :         scan_omp_target (as_a <gomp_target *> (stmt), ctx);
    4302              :       break;
    4303              : 
    4304         8736 :     case GIMPLE_OMP_TEAMS:
    4305         8736 :       if (gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
    4306              :         {
    4307         2618 :           taskreg_nesting_level++;
    4308         2618 :           scan_omp_teams (as_a <gomp_teams *> (stmt), ctx);
    4309         2618 :           taskreg_nesting_level--;
    4310              :         }
    4311              :       else
    4312         6118 :         scan_omp_teams (as_a <gomp_teams *> (stmt), ctx);
    4313              :       break;
    4314              : 
    4315       280663 :     case GIMPLE_BIND:
    4316       280663 :       {
    4317       280663 :         tree var;
    4318              : 
    4319       280663 :         *handled_ops_p = false;
    4320       280663 :         if (ctx)
    4321       152230 :           for (var = gimple_bind_vars (as_a <gbind *> (stmt));
    4322       576922 :                var ;
    4323       424692 :                var = DECL_CHAIN (var))
    4324       424692 :             insert_decl_map (&ctx->cb, var, var);
    4325              :       }
    4326              :       break;
    4327      2979766 :     default:
    4328      2979766 :       *handled_ops_p = false;
    4329      2979766 :       break;
    4330              :     }
    4331              : 
    4332      3397896 :   return NULL_TREE;
    4333              : }
    4334              : 
    4335              : 
    4336              : /* Scan all the statements starting at the current statement.  CTX
    4337              :    contains context information about the OMP directives and
    4338              :    clauses found during the scan.  */
    4339              : 
    4340              : static void
    4341       258355 : scan_omp (gimple_seq *body_p, omp_context *ctx)
    4342              : {
    4343       258355 :   location_t saved_location;
    4344       258355 :   struct walk_stmt_info wi;
    4345              : 
    4346       258355 :   memset (&wi, 0, sizeof (wi));
    4347       258355 :   wi.info = ctx;
    4348       258355 :   wi.want_locations = true;
    4349              : 
    4350       258355 :   saved_location = input_location;
    4351       258355 :   walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
    4352       258355 :   input_location = saved_location;
    4353       258355 : }
    4354              : 
    4355              : /* Re-gimplification and code generation routines.  */
    4356              : 
    4357              : /* Remove omp_member_access_dummy_var variables from gimple_bind_vars
    4358              :    of BIND if in a method.  */
    4359              : 
    4360              : static void
    4361       257714 : maybe_remove_omp_member_access_dummy_vars (gbind *bind)
    4362              : {
    4363       257714 :   if (DECL_ARGUMENTS (current_function_decl)
    4364        97607 :       && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl))
    4365       268206 :       && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl)))
    4366              :           == POINTER_TYPE))
    4367              :     {
    4368         3520 :       tree vars = gimple_bind_vars (bind);
    4369        19340 :       for (tree *pvar = &vars; *pvar; )
    4370        15820 :         if (omp_member_access_dummy_var (*pvar))
    4371          719 :           *pvar = DECL_CHAIN (*pvar);
    4372              :         else
    4373        15101 :           pvar = &DECL_CHAIN (*pvar);
    4374         3520 :       gimple_bind_set_vars (bind, vars);
    4375              :     }
    4376       257714 : }
    4377              : 
    4378              : /* Remove omp_member_access_dummy_var variables from BLOCK_VARS of
    4379              :    block and its subblocks.  */
    4380              : 
    4381              : static void
    4382        12876 : remove_member_access_dummy_vars (tree block)
    4383              : {
    4384        22435 :   for (tree *pvar = &BLOCK_VARS (block); *pvar; )
    4385         9559 :     if (omp_member_access_dummy_var (*pvar))
    4386          108 :       *pvar = DECL_CHAIN (*pvar);
    4387              :     else
    4388         9451 :       pvar = &DECL_CHAIN (*pvar);
    4389              : 
    4390        16761 :   for (block = BLOCK_SUBBLOCKS (block); block; block = BLOCK_CHAIN (block))
    4391         3885 :     remove_member_access_dummy_vars (block);
    4392        12876 : }
    4393              : 
    4394              : /* If a context was created for STMT when it was scanned, return it.  */
    4395              : 
    4396              : static omp_context *
    4397       121079 : maybe_lookup_ctx (gimple *stmt)
    4398              : {
    4399       121079 :   splay_tree_node n;
    4400       121079 :   n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
    4401       121079 :   return n ? (omp_context *) n->value : NULL;
    4402              : }
    4403              : 
    4404              : 
    4405              : /* Find the mapping for DECL in CTX or the immediately enclosing
    4406              :    context that has a mapping for DECL.
    4407              : 
    4408              :    If CTX is a nested parallel directive, we may have to use the decl
    4409              :    mappings created in CTX's parent context.  Suppose that we have the
    4410              :    following parallel nesting (variable UIDs showed for clarity):
    4411              : 
    4412              :         iD.1562 = 0;
    4413              :         #omp parallel shared(iD.1562)           -> outer parallel
    4414              :           iD.1562 = iD.1562 + 1;
    4415              : 
    4416              :           #omp parallel shared (iD.1562)        -> inner parallel
    4417              :              iD.1562 = iD.1562 - 1;
    4418              : 
    4419              :    Each parallel structure will create a distinct .omp_data_s structure
    4420              :    for copying iD.1562 in/out of the directive:
    4421              : 
    4422              :         outer parallel          .omp_data_s.1.i -> iD.1562
    4423              :         inner parallel          .omp_data_s.2.i -> iD.1562
    4424              : 
    4425              :    A shared variable mapping will produce a copy-out operation before
    4426              :    the parallel directive and a copy-in operation after it.  So, in
    4427              :    this case we would have:
    4428              : 
    4429              :         iD.1562 = 0;
    4430              :         .omp_data_o.1.i = iD.1562;
    4431              :         #omp parallel shared(iD.1562)           -> outer parallel
    4432              :           .omp_data_i.1 = &.omp_data_o.1
    4433              :           .omp_data_i.1->i = .omp_data_i.1->i + 1;
    4434              : 
    4435              :           .omp_data_o.2.i = iD.1562;            -> **
    4436              :           #omp parallel shared(iD.1562)         -> inner parallel
    4437              :             .omp_data_i.2 = &.omp_data_o.2
    4438              :             .omp_data_i.2->i = .omp_data_i.2->i - 1;
    4439              : 
    4440              : 
    4441              :     ** This is a problem.  The symbol iD.1562 cannot be referenced
    4442              :        inside the body of the outer parallel region.  But since we are
    4443              :        emitting this copy operation while expanding the inner parallel
    4444              :        directive, we need to access the CTX structure of the outer
    4445              :        parallel directive to get the correct mapping:
    4446              : 
    4447              :           .omp_data_o.2.i = .omp_data_i.1->i
    4448              : 
    4449              :     Since there may be other workshare or parallel directives enclosing
    4450              :     the parallel directive, it may be necessary to walk up the context
    4451              :     parent chain.  This is not a problem in general because nested
    4452              :     parallelism happens only rarely.  */
    4453              : 
    4454              : static tree
    4455       125952 : lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
    4456              : {
    4457       125952 :   tree t;
    4458       125952 :   omp_context *up;
    4459              : 
    4460       182680 :   for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
    4461        56728 :     t = maybe_lookup_decl (decl, up);
    4462              : 
    4463       125952 :   gcc_assert (!ctx->is_nested || t || is_global_var (decl));
    4464              : 
    4465        97631 :   return t ? t : decl;
    4466              : }
    4467              : 
    4468              : 
    4469              : /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
    4470              :    in outer contexts.  */
    4471              : 
    4472              : static tree
    4473       356619 : maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
    4474              : {
    4475       356619 :   tree t = NULL;
    4476       356619 :   omp_context *up;
    4477              : 
    4478       627749 :   for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
    4479       271130 :     t = maybe_lookup_decl (decl, up);
    4480              : 
    4481       356619 :   return t ? t : decl;
    4482              : }
    4483              : 
    4484              : 
    4485              : /* Construct the initialization value for reduction operation OP.  */
    4486              : 
    4487              : tree
    4488        13078 : omp_reduction_init_op (location_t loc, enum tree_code op, tree type)
    4489              : {
    4490        13078 :   switch (op)
    4491              :     {
    4492        10743 :     case PLUS_EXPR:
    4493        10743 :     case MINUS_EXPR:
    4494        10743 :     case BIT_IOR_EXPR:
    4495        10743 :     case BIT_XOR_EXPR:
    4496        10743 :     case TRUTH_OR_EXPR:
    4497        10743 :     case TRUTH_ORIF_EXPR:
    4498        10743 :     case TRUTH_XOR_EXPR:
    4499        10743 :     case NE_EXPR:
    4500        10743 :       return build_zero_cst (type);
    4501              : 
    4502         1431 :     case MULT_EXPR:
    4503         1431 :     case TRUTH_AND_EXPR:
    4504         1431 :     case TRUTH_ANDIF_EXPR:
    4505         1431 :     case EQ_EXPR:
    4506         1431 :       return fold_convert_loc (loc, type, integer_one_node);
    4507              : 
    4508          208 :     case BIT_AND_EXPR:
    4509          208 :       return fold_convert_loc (loc, type, integer_minus_one_node);
    4510              : 
    4511          388 :     case MAX_EXPR:
    4512          388 :       if (SCALAR_FLOAT_TYPE_P (type))
    4513              :         {
    4514          158 :           REAL_VALUE_TYPE min;
    4515          158 :           if (HONOR_INFINITIES (type))
    4516          158 :             real_arithmetic (&min, NEGATE_EXPR, &dconstinf, NULL);
    4517              :           else
    4518            0 :             real_maxval (&min, 1, TYPE_MODE (type));
    4519          158 :           return build_real (type, min);
    4520              :         }
    4521          230 :       else if (POINTER_TYPE_P (type))
    4522              :         {
    4523            2 :           wide_int min
    4524            2 :             = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    4525            2 :           return wide_int_to_tree (type, min);
    4526            2 :         }
    4527              :       else
    4528              :         {
    4529          228 :           gcc_assert (INTEGRAL_TYPE_P (type));
    4530          228 :           return TYPE_MIN_VALUE (type);
    4531              :         }
    4532              : 
    4533          308 :     case MIN_EXPR:
    4534          308 :       if (SCALAR_FLOAT_TYPE_P (type))
    4535              :         {
    4536          108 :           REAL_VALUE_TYPE max;
    4537          108 :           if (HONOR_INFINITIES (type))
    4538          108 :             max = dconstinf;
    4539              :           else
    4540            0 :             real_maxval (&max, 0, TYPE_MODE (type));
    4541          108 :           return build_real (type, max);
    4542              :         }
    4543          200 :       else if (POINTER_TYPE_P (type))
    4544              :         {
    4545            2 :           wide_int max
    4546            2 :             = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    4547            2 :           return wide_int_to_tree (type, max);
    4548            2 :         }
    4549              :       else
    4550              :         {
    4551          198 :           gcc_assert (INTEGRAL_TYPE_P (type));
    4552          198 :           return TYPE_MAX_VALUE (type);
    4553              :         }
    4554              : 
    4555            0 :     default:
    4556            0 :       gcc_unreachable ();
    4557              :     }
    4558              : }
    4559              : 
    4560              : /* Construct the initialization value for reduction CLAUSE.  */
    4561              : 
    4562              : tree
    4563        10457 : omp_reduction_init (tree clause, tree type)
    4564              : {
    4565        10457 :   return omp_reduction_init_op (OMP_CLAUSE_LOCATION (clause),
    4566        10457 :                                 OMP_CLAUSE_REDUCTION_CODE (clause), type);
    4567              : }
    4568              : 
    4569              : /* Return alignment to be assumed for var in CLAUSE, which should be
    4570              :    OMP_CLAUSE_ALIGNED.  */
    4571              : 
    4572              : static tree
    4573          140 : omp_clause_aligned_alignment (tree clause)
    4574              : {
    4575          140 :   if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
    4576          123 :     return OMP_CLAUSE_ALIGNED_ALIGNMENT (clause);
    4577              : 
    4578              :   /* Otherwise return implementation defined alignment.  */
    4579           17 :   unsigned int al = 1;
    4580           17 :   opt_scalar_mode mode_iter;
    4581           17 :   auto_vector_modes modes;
    4582           17 :   targetm.vectorize.autovectorize_vector_modes (&modes, true);
    4583           17 :   static enum mode_class classes[]
    4584              :     = { MODE_INT, MODE_VECTOR_INT, MODE_FLOAT, MODE_VECTOR_FLOAT };
    4585           51 :   for (int i = 0; i < 4; i += 2)
    4586              :     /* The for loop above dictates that we only walk through scalar classes.  */
    4587          255 :     FOR_EACH_MODE_IN_CLASS (mode_iter, classes[i])
    4588              :       {
    4589          221 :         scalar_mode mode = mode_iter.require ();
    4590          221 :         machine_mode vmode = targetm.vectorize.preferred_simd_mode (mode);
    4591          221 :         if (GET_MODE_CLASS (vmode) != classes[i + 1])
    4592          323 :           continue;
    4593              :         machine_mode alt_vmode;
    4594          476 :         for (unsigned int j = 0; j < modes.length (); ++j)
    4595          527 :           if (related_vector_mode (modes[j], mode).exists (&alt_vmode)
    4596          578 :               && known_ge (GET_MODE_SIZE (alt_vmode), GET_MODE_SIZE (vmode)))
    4597          119 :             vmode = alt_vmode;
    4598              : 
    4599          119 :         tree type = lang_hooks.types.type_for_mode (mode, 1);
    4600          119 :         if (type == NULL_TREE || TYPE_MODE (type) != mode)
    4601           17 :           continue;
    4602          102 :         type = build_vector_type_for_mode (type, vmode);
    4603          102 :         if (TYPE_MODE (type) != vmode)
    4604            0 :           continue;
    4605          102 :         if (TYPE_ALIGN_UNIT (type) > al)
    4606           17 :           al = TYPE_ALIGN_UNIT (type);
    4607              :       }
    4608           17 :   return build_int_cst (integer_type_node, al);
    4609           17 : }
    4610              : 
    4611              : 
    4612              : /* This structure is part of the interface between lower_rec_simd_input_clauses
    4613              :    and lower_rec_input_clauses.  */
    4614              : 
    4615              : class omplow_simd_context {
    4616              : public:
    4617        77126 :   omplow_simd_context () { memset (this, 0, sizeof (*this)); }
    4618              :   tree idx;
    4619              :   tree lane;
    4620              :   tree lastlane;
    4621              :   vec<tree, va_heap> simt_eargs;
    4622              :   gimple_seq simt_dlist;
    4623              :   poly_uint64 max_vf;
    4624              :   bool is_simt;
    4625              : };
    4626              : 
    4627              : /* Helper function of lower_rec_input_clauses, used for #pragma omp simd
    4628              :    privatization.  */
    4629              : 
    4630              : static bool
    4631        10228 : lower_rec_simd_input_clauses (tree new_var, omp_context *ctx,
    4632              :                               omplow_simd_context *sctx, tree &ivar,
    4633              :                               tree &lvar, tree *rvar = NULL,
    4634              :                               tree *rvar2 = NULL)
    4635              : {
    4636        10228 :   if (known_eq (sctx->max_vf, 0U))
    4637              :     {
    4638         4790 :       sctx->max_vf = (sctx->is_simt ? omp_max_simt_vf ()
    4639         4790 :                       : omp_max_vf (omp_maybe_offloaded_ctx (ctx)));
    4640         4790 :       if (maybe_gt (sctx->max_vf, 1U))
    4641              :         {
    4642         3459 :           tree c = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    4643              :                                     OMP_CLAUSE_SAFELEN);
    4644         3459 :           if (c)
    4645              :             {
    4646           89 :               poly_uint64 safe_len;
    4647           89 :               if (!poly_int_tree_p (OMP_CLAUSE_SAFELEN_EXPR (c), &safe_len)
    4648           89 :                   || maybe_lt (safe_len, 1U))
    4649            6 :                 sctx->max_vf = 1;
    4650              :               else
    4651           83 :                 sctx->max_vf = lower_bound (sctx->max_vf, safe_len);
    4652              :             }
    4653              :         }
    4654         4790 :       if (sctx->is_simt && !known_eq (sctx->max_vf, 1U))
    4655              :         {
    4656            0 :           for (tree c = gimple_omp_for_clauses (ctx->stmt); c;
    4657            0 :                c = OMP_CLAUSE_CHAIN (c))
    4658              :             {
    4659            0 :               if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
    4660            0 :                 continue;
    4661              : 
    4662            0 :               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    4663              :                 {
    4664              :                   /* UDR reductions are not supported yet for SIMT, disable
    4665              :                      SIMT.  */
    4666            0 :                   sctx->max_vf = 1;
    4667            0 :                   break;
    4668              :                 }
    4669              : 
    4670            0 :               if (truth_value_p (OMP_CLAUSE_REDUCTION_CODE (c))
    4671            0 :                   && !INTEGRAL_TYPE_P (TREE_TYPE (new_var)))
    4672              :                 {
    4673              :                   /* Doing boolean operations on non-integral types is
    4674              :                      for conformance only, it's not worth supporting this
    4675              :                      for SIMT.  */
    4676            0 :                   sctx->max_vf = 1;
    4677            0 :                   break;
    4678              :               }
    4679              :             }
    4680              :         }
    4681         4790 :       if (maybe_gt (sctx->max_vf, 1U))
    4682              :         {
    4683         3440 :           sctx->idx = create_tmp_var (unsigned_type_node);
    4684         3440 :           sctx->lane = create_tmp_var (unsigned_type_node);
    4685              :         }
    4686              :     }
    4687        10228 :   if (known_eq (sctx->max_vf, 1U))
    4688              :     return false;
    4689              : 
    4690         7189 :   if (sctx->is_simt)
    4691              :     {
    4692            0 :       if (is_gimple_reg (new_var))
    4693              :         {
    4694            0 :           ivar = lvar = new_var;
    4695            0 :           return true;
    4696              :         }
    4697            0 :       tree type = TREE_TYPE (new_var), ptype = build_pointer_type (type);
    4698            0 :       ivar = lvar = create_tmp_var (type);
    4699            0 :       TREE_ADDRESSABLE (ivar) = 1;
    4700            0 :       DECL_ATTRIBUTES (ivar) = tree_cons (get_identifier ("omp simt private"),
    4701            0 :                                           NULL, DECL_ATTRIBUTES (ivar));
    4702            0 :       sctx->simt_eargs.safe_push (build1 (ADDR_EXPR, ptype, ivar));
    4703            0 :       tree clobber = build_clobber (type);
    4704            0 :       gimple *g = gimple_build_assign (ivar, clobber);
    4705            0 :       gimple_seq_add_stmt (&sctx->simt_dlist, g);
    4706              :     }
    4707              :   else
    4708              :     {
    4709         7189 :       tree atype = build_array_type_nelts (TREE_TYPE (new_var), sctx->max_vf);
    4710         7189 :       tree avar = create_tmp_var_raw (atype);
    4711         7189 :       if (TREE_ADDRESSABLE (new_var))
    4712          912 :         TREE_ADDRESSABLE (avar) = 1;
    4713         7189 :       DECL_ATTRIBUTES (avar)
    4714         7189 :         = tree_cons (get_identifier ("omp simd array"), NULL,
    4715         7189 :                      DECL_ATTRIBUTES (avar));
    4716         7189 :       gimple_add_tmp_var (avar);
    4717         7189 :       tree iavar = avar;
    4718         7189 :       if (rvar && !ctx->for_simd_scan_phase)
    4719              :         {
    4720              :           /* For inscan reductions, create another array temporary,
    4721              :              which will hold the reduced value.  */
    4722          232 :           iavar = create_tmp_var_raw (atype);
    4723          232 :           if (TREE_ADDRESSABLE (new_var))
    4724           33 :             TREE_ADDRESSABLE (iavar) = 1;
    4725          232 :           DECL_ATTRIBUTES (iavar)
    4726          232 :             = tree_cons (get_identifier ("omp simd array"), NULL,
    4727              :                          tree_cons (get_identifier ("omp simd inscan"), NULL,
    4728          232 :                                     DECL_ATTRIBUTES (iavar)));
    4729          232 :           gimple_add_tmp_var (iavar);
    4730          232 :           ctx->cb.decl_map->put (avar, iavar);
    4731          232 :           if (sctx->lastlane == NULL_TREE)
    4732          184 :             sctx->lastlane = create_tmp_var (unsigned_type_node);
    4733          232 :           *rvar = build4 (ARRAY_REF, TREE_TYPE (new_var), iavar,
    4734              :                           sctx->lastlane, NULL_TREE, NULL_TREE);
    4735          232 :           TREE_THIS_NOTRAP (*rvar) = 1;
    4736              : 
    4737          232 :           if (ctx->scan_exclusive)
    4738              :             {
    4739              :               /* And for exclusive scan yet another one, which will
    4740              :                  hold the value during the scan phase.  */
    4741          114 :               tree savar = create_tmp_var_raw (atype);
    4742          114 :               if (TREE_ADDRESSABLE (new_var))
    4743           17 :                 TREE_ADDRESSABLE (savar) = 1;
    4744          114 :               DECL_ATTRIBUTES (savar)
    4745          114 :                 = tree_cons (get_identifier ("omp simd array"), NULL,
    4746              :                              tree_cons (get_identifier ("omp simd inscan "
    4747              :                                                         "exclusive"), NULL,
    4748          114 :                                         DECL_ATTRIBUTES (savar)));
    4749          114 :               gimple_add_tmp_var (savar);
    4750          114 :               ctx->cb.decl_map->put (iavar, savar);
    4751          114 :               *rvar2 = build4 (ARRAY_REF, TREE_TYPE (new_var), savar,
    4752              :                                sctx->idx, NULL_TREE, NULL_TREE);
    4753          114 :               TREE_THIS_NOTRAP (*rvar2) = 1;
    4754              :             }
    4755              :         }
    4756         7189 :       ivar = build4 (ARRAY_REF, TREE_TYPE (new_var), iavar, sctx->idx,
    4757              :                      NULL_TREE, NULL_TREE);
    4758         7189 :       lvar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, sctx->lane,
    4759              :                      NULL_TREE, NULL_TREE);
    4760         7189 :       TREE_THIS_NOTRAP (ivar) = 1;
    4761         7189 :       TREE_THIS_NOTRAP (lvar) = 1;
    4762              :     }
    4763         7189 :   if (DECL_P (new_var))
    4764              :     {
    4765         7035 :       SET_DECL_VALUE_EXPR (new_var, lvar);
    4766         7035 :       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    4767              :     }
    4768              :   return true;
    4769              : }
    4770              : 
    4771              : /* Helper function of lower_rec_input_clauses.  For a reference
    4772              :    in simd reduction, add an underlying variable it will reference.  */
    4773              : 
    4774              : static void
    4775           64 : handle_simd_reference (location_t loc, tree new_vard, gimple_seq *ilist)
    4776              : {
    4777           64 :   tree z = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
    4778           64 :   if (TREE_CONSTANT (z))
    4779              :     {
    4780           64 :       z = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_vard)),
    4781              :                               get_name (new_vard));
    4782           64 :       gimple_add_tmp_var (z);
    4783           64 :       TREE_ADDRESSABLE (z) = 1;
    4784           64 :       z = build_fold_addr_expr_loc (loc, z);
    4785           64 :       gimplify_assign (new_vard, z, ilist);
    4786              :     }
    4787           64 : }
    4788              : 
    4789              : /* Helper function for lower_rec_input_clauses.  Emit into ilist sequence
    4790              :    code to emit (type) (tskred_temp[idx]).  */
    4791              : 
    4792              : static tree
    4793         1120 : task_reduction_read (gimple_seq *ilist, tree tskred_temp, tree type,
    4794              :                      unsigned idx)
    4795              : {
    4796         1120 :   unsigned HOST_WIDE_INT sz
    4797         1120 :     = tree_to_uhwi (TYPE_SIZE_UNIT (pointer_sized_int_node));
    4798         1120 :   tree r = build2 (MEM_REF, pointer_sized_int_node,
    4799         1120 :                    tskred_temp, build_int_cst (TREE_TYPE (tskred_temp),
    4800         1120 :                                                idx * sz));
    4801         1120 :   tree v = create_tmp_var (pointer_sized_int_node);
    4802         1120 :   gimple *g = gimple_build_assign (v, r);
    4803         1120 :   gimple_seq_add_stmt (ilist, g);
    4804         1120 :   if (!useless_type_conversion_p (type, pointer_sized_int_node))
    4805              :     {
    4806          872 :       v = create_tmp_var (type);
    4807          872 :       g = gimple_build_assign (v, NOP_EXPR, gimple_assign_lhs (g));
    4808          872 :       gimple_seq_add_stmt (ilist, g);
    4809              :     }
    4810         1120 :   return v;
    4811              : }
    4812              : 
    4813              : /* Lower early initialization of privatized variable NEW_VAR
    4814              :    if it needs an allocator (has allocate clause).  */
    4815              : 
    4816              : static bool
    4817       144349 : lower_private_allocate (tree var, tree new_var, tree &allocator,
    4818              :                         tree &allocate_ptr, gimple_seq *ilist,
    4819              :                         omp_context *ctx, bool is_ref, tree size)
    4820              : {
    4821       144349 :   if (allocator)
    4822              :     return false;
    4823       144255 :   gcc_assert (allocate_ptr == NULL_TREE);
    4824       144255 :   if (ctx->allocate_map
    4825         3082 :       && (DECL_P (new_var) || (TYPE_P (new_var) && size)))
    4826         3079 :     if (tree *allocatorp = ctx->allocate_map->get (var))
    4827         1140 :       allocator = *allocatorp;
    4828       144255 :   if (allocator == NULL_TREE)
    4829              :     return false;
    4830         1140 :   if (!is_ref && omp_privatize_by_reference (var))
    4831              :     {
    4832            0 :       allocator = NULL_TREE;
    4833            0 :       return false;
    4834              :     }
    4835              : 
    4836         1140 :   unsigned HOST_WIDE_INT ialign = 0;
    4837         1140 :   if (TREE_CODE (allocator) == TREE_LIST)
    4838              :     {
    4839          236 :       ialign = tree_to_uhwi (TREE_VALUE (allocator));
    4840          236 :       allocator = TREE_PURPOSE (allocator);
    4841              :     }
    4842         1140 :   if (TREE_CODE (allocator) != INTEGER_CST)
    4843          428 :     allocator = build_outer_var_ref (allocator, ctx, OMP_CLAUSE_ALLOCATE);
    4844         1140 :   allocator = fold_convert (pointer_sized_int_node, allocator);
    4845         1140 :   if (TREE_CODE (allocator) != INTEGER_CST)
    4846              :     {
    4847          428 :       tree var = create_tmp_var (TREE_TYPE (allocator));
    4848          428 :       gimplify_assign (var, allocator, ilist);
    4849          428 :       allocator = var;
    4850              :     }
    4851              : 
    4852         1140 :   tree ptr_type, align, sz = size;
    4853         1140 :   if (TYPE_P (new_var))
    4854              :     {
    4855          225 :       ptr_type = build_pointer_type (new_var);
    4856          225 :       ialign = MAX (ialign, TYPE_ALIGN_UNIT (new_var));
    4857              :     }
    4858          915 :   else if (is_ref)
    4859              :     {
    4860          114 :       ptr_type = build_pointer_type (TREE_TYPE (TREE_TYPE (new_var)));
    4861          114 :       ialign = MAX (ialign, TYPE_ALIGN_UNIT (TREE_TYPE (ptr_type)));
    4862              :     }
    4863              :   else
    4864              :     {
    4865          801 :       ptr_type = build_pointer_type (TREE_TYPE (new_var));
    4866          801 :       ialign = MAX (ialign, DECL_ALIGN_UNIT (new_var));
    4867          801 :       if (sz == NULL_TREE)
    4868          703 :         sz = fold_convert (size_type_node, DECL_SIZE_UNIT (new_var));
    4869              :     }
    4870         1140 :   align = build_int_cst (size_type_node, ialign);
    4871         1140 :   if (TREE_CODE (sz) != INTEGER_CST)
    4872              :     {
    4873           54 :       tree szvar = create_tmp_var (size_type_node);
    4874           54 :       gimplify_assign (szvar, sz, ilist);
    4875           54 :       sz = szvar;
    4876              :     }
    4877         1140 :   allocate_ptr = create_tmp_var (ptr_type);
    4878         1140 :   tree a = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
    4879         1140 :   gimple *g = gimple_build_call (a, 3, align, sz, allocator);
    4880         1140 :   gimple_call_set_lhs (g, allocate_ptr);
    4881         1140 :   gimple_seq_add_stmt (ilist, g);
    4882         1140 :   if (!is_ref)
    4883              :     {
    4884          801 :       tree x = build_simple_mem_ref (allocate_ptr);
    4885          801 :       TREE_THIS_NOTRAP (x) = 1;
    4886          801 :       SET_DECL_VALUE_EXPR (new_var, x);
    4887          801 :       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    4888              :     }
    4889              :   return true;
    4890              : }
    4891              : 
    4892              : /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
    4893              :    from the receiver (aka child) side and initializers for REFERENCE_TYPE
    4894              :    private variables.  Initialization statements go in ILIST, while calls
    4895              :    to destructors go in DLIST.  */
    4896              : 
    4897              : static void
    4898        77126 : lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
    4899              :                          omp_context *ctx, struct omp_for_data *fd)
    4900              : {
    4901        77126 :   tree c, copyin_seq, x, ptr;
    4902        77126 :   bool copyin_by_ref = false;
    4903        77126 :   bool lastprivate_firstprivate = false;
    4904        77126 :   bool reduction_omp_orig_ref = false;
    4905        77126 :   int pass;
    4906        77126 :   bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    4907        77126 :                   && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD);
    4908        77126 :   omplow_simd_context sctx = omplow_simd_context ();
    4909        77126 :   tree simt_lane = NULL_TREE, simtrec = NULL_TREE;
    4910        77126 :   tree ivar = NULL_TREE, lvar = NULL_TREE, uid = NULL_TREE;
    4911        77126 :   gimple_seq llist[4] = { };
    4912        77126 :   tree nonconst_simd_if = NULL_TREE;
    4913              : 
    4914        77126 :   copyin_seq = NULL;
    4915        77126 :   sctx.is_simt = is_simd && omp_find_clause (clauses, OMP_CLAUSE__SIMT_);
    4916              : 
    4917              :   /* Set max_vf=1 (which will later enforce safelen=1) in simd loops
    4918              :      with data sharing clauses referencing variable sized vars.  That
    4919              :      is unnecessarily hard to support and very unlikely to result in
    4920              :      vectorized code anyway.  */
    4921         9355 :   if (is_simd)
    4922        61463 :     for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    4923        52108 :       switch (OMP_CLAUSE_CODE (c))
    4924              :         {
    4925         7579 :         case OMP_CLAUSE_LINEAR:
    4926         7579 :           if (OMP_CLAUSE_LINEAR_ARRAY (c))
    4927          216 :             sctx.max_vf = 1;
    4928              :           /* FALLTHRU */
    4929        25155 :         case OMP_CLAUSE_PRIVATE:
    4930        25155 :         case OMP_CLAUSE_FIRSTPRIVATE:
    4931        25155 :         case OMP_CLAUSE_LASTPRIVATE:
    4932        25155 :           if (is_variable_sized (OMP_CLAUSE_DECL (c)))
    4933            0 :             sctx.max_vf = 1;
    4934        25155 :           else if (omp_privatize_by_reference (OMP_CLAUSE_DECL (c)))
    4935              :             {
    4936          279 :               tree rtype = TREE_TYPE (TREE_TYPE (OMP_CLAUSE_DECL (c)));
    4937          279 :               if (!TREE_CONSTANT (TYPE_SIZE_UNIT (rtype)))
    4938           96 :                 sctx.max_vf = 1;
    4939              :             }
    4940              :           break;
    4941         2578 :         case OMP_CLAUSE_REDUCTION:
    4942         2578 :         case OMP_CLAUSE_IN_REDUCTION:
    4943         2578 :           if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
    4944         2578 :               || is_variable_sized (OMP_CLAUSE_DECL (c)))
    4945          180 :             sctx.max_vf = 1;
    4946         2398 :           else if (omp_privatize_by_reference (OMP_CLAUSE_DECL (c)))
    4947              :             {
    4948          144 :               tree rtype = TREE_TYPE (TREE_TYPE (OMP_CLAUSE_DECL (c)));
    4949          144 :               if (!TREE_CONSTANT (TYPE_SIZE_UNIT (rtype)))
    4950            0 :                 sctx.max_vf = 1;
    4951              :             }
    4952              :           break;
    4953          759 :         case OMP_CLAUSE_IF:
    4954          759 :           if (integer_zerop (OMP_CLAUSE_IF_EXPR (c)))
    4955          124 :             sctx.max_vf = 1;
    4956          635 :           else if (TREE_CODE (OMP_CLAUSE_IF_EXPR (c)) != INTEGER_CST)
    4957          625 :             nonconst_simd_if = OMP_CLAUSE_IF_EXPR (c);
    4958              :           break;
    4959          626 :         case OMP_CLAUSE_SIMDLEN:
    4960          626 :           if (integer_onep (OMP_CLAUSE_SIMDLEN_EXPR (c)))
    4961          110 :             sctx.max_vf = 1;
    4962              :           break;
    4963          184 :         case OMP_CLAUSE__CONDTEMP_:
    4964              :           /* FIXME: lastprivate(conditional:) not handled for SIMT yet.  */
    4965          184 :           if (sctx.is_simt)
    4966            0 :             sctx.max_vf = 1;
    4967              :           break;
    4968        22806 :         default:
    4969        22806 :           continue;
    4970        22806 :         }
    4971              : 
    4972              :   /* Add a placeholder for simduid.  */
    4973        77126 :   if (sctx.is_simt && maybe_ne (sctx.max_vf, 1U))
    4974            0 :     sctx.simt_eargs.safe_push (NULL_TREE);
    4975              : 
    4976              :   unsigned task_reduction_cnt = 0;
    4977              :   unsigned task_reduction_cntorig = 0;
    4978              :   unsigned task_reduction_cnt_full = 0;
    4979              :   unsigned task_reduction_cntorig_full = 0;
    4980              :   unsigned task_reduction_other_cnt = 0;
    4981       234433 :   tree tskred_atype = NULL_TREE, tskred_avar = NULL_TREE;
    4982              :   tree tskred_base = NULL_TREE, tskred_temp = NULL_TREE;
    4983              :   /* Do all the fixed sized types in the first pass, and the variable sized
    4984              :      types in the second pass.  This makes sure that the scalar arguments to
    4985              :      the variable sized types are processed before we use them in the
    4986              :      variable sized operations.  For task reductions we use 4 passes, in the
    4987              :      first two we ignore them, in the third one gather arguments for
    4988              :      GOMP_task_reduction_remap call and in the last pass actually handle
    4989              :      the task reductions.  */
    4990       391740 :   for (pass = 0; pass < ((task_reduction_cnt || task_reduction_other_cnt)
    4991       234433 :                          ? 4 : 2); ++pass)
    4992              :     {
    4993       157311 :       if (pass == 2 && task_reduction_cnt)
    4994              :         {
    4995          871 :           tskred_atype
    4996          871 :             = build_array_type_nelts (ptr_type_node, task_reduction_cnt
    4997          871 :                                                      + task_reduction_cntorig);
    4998          871 :           tskred_avar = create_tmp_var_raw (tskred_atype);
    4999          871 :           gimple_add_tmp_var (tskred_avar);
    5000          871 :           TREE_ADDRESSABLE (tskred_avar) = 1;
    5001          871 :           task_reduction_cnt_full = task_reduction_cnt;
    5002          871 :           task_reduction_cntorig_full = task_reduction_cntorig;
    5003              :         }
    5004       156440 :       else if (pass == 3 && task_reduction_cnt)
    5005              :         {
    5006          871 :           x = builtin_decl_explicit (BUILT_IN_GOMP_TASK_REDUCTION_REMAP);
    5007          871 :           gimple *g
    5008          871 :             = gimple_build_call (x, 3, size_int (task_reduction_cnt),
    5009          871 :                                  size_int (task_reduction_cntorig),
    5010              :                                  build_fold_addr_expr (tskred_avar));
    5011          871 :           gimple_seq_add_stmt (ilist, g);
    5012              :         }
    5013       157311 :       if (pass == 3 && task_reduction_other_cnt)
    5014              :         {
    5015              :           /* For reduction clauses, build
    5016              :              tskred_base = (void *) tskred_temp[2]
    5017              :                            + omp_get_thread_num () * tskred_temp[1]
    5018              :              or if tskred_temp[1] is known to be constant, that constant
    5019              :              directly.  This is the start of the private reduction copy block
    5020              :              for the current thread.  */
    5021          838 :           tree v = create_tmp_var (integer_type_node);
    5022          838 :           x = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
    5023          838 :           gimple *g = gimple_build_call (x, 0);
    5024          838 :           gimple_call_set_lhs (g, v);
    5025          838 :           gimple_seq_add_stmt (ilist, g);
    5026          838 :           c = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
    5027          838 :           tskred_temp = OMP_CLAUSE_DECL (c);
    5028          838 :           if (is_taskreg_ctx (ctx))
    5029          557 :             tskred_temp = lookup_decl (tskred_temp, ctx);
    5030          838 :           tree v2 = create_tmp_var (sizetype);
    5031          838 :           g = gimple_build_assign (v2, NOP_EXPR, v);
    5032          838 :           gimple_seq_add_stmt (ilist, g);
    5033          838 :           if (ctx->task_reductions[0])
    5034          821 :             v = fold_convert (sizetype, ctx->task_reductions[0]);
    5035              :           else
    5036           17 :             v = task_reduction_read (ilist, tskred_temp, sizetype, 1);
    5037          838 :           tree v3 = create_tmp_var (sizetype);
    5038          838 :           g = gimple_build_assign (v3, MULT_EXPR, v2, v);
    5039          838 :           gimple_seq_add_stmt (ilist, g);
    5040          838 :           v = task_reduction_read (ilist, tskred_temp, ptr_type_node, 2);
    5041          838 :           tskred_base = create_tmp_var (ptr_type_node);
    5042          838 :           g = gimple_build_assign (tskred_base, POINTER_PLUS_EXPR, v, v3);
    5043          838 :           gimple_seq_add_stmt (ilist, g);
    5044              :         }
    5045       157311 :       task_reduction_cnt = 0;
    5046       157311 :       task_reduction_cntorig = 0;
    5047       157311 :       task_reduction_other_cnt = 0;
    5048       761282 :       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    5049              :         {
    5050       603975 :           enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
    5051       603975 :           tree var, new_var;
    5052       603975 :           bool by_ref;
    5053       603975 :           location_t clause_loc = OMP_CLAUSE_LOCATION (c);
    5054       603975 :           bool task_reduction_p = false;
    5055       603975 :           bool task_reduction_needs_orig_p = false;
    5056       603975 :           tree cond = NULL_TREE;
    5057       603975 :           tree allocator, allocate_ptr;
    5058              : 
    5059       603975 :           switch (c_kind)
    5060              :             {
    5061       136008 :             case OMP_CLAUSE_PRIVATE:
    5062       136008 :               if (OMP_CLAUSE_PRIVATE_DEBUG (c))
    5063       435607 :                 continue;
    5064              :               break;
    5065        60040 :             case OMP_CLAUSE_SHARED:
    5066              :               /* Ignore shared directives in teams construct inside
    5067              :                  of target construct.  */
    5068        60040 :               if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
    5069        60040 :                   && !is_host_teams_ctx (ctx))
    5070        23496 :                 continue;
    5071        36544 :               if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
    5072              :                 {
    5073        12080 :                   gcc_assert (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c)
    5074              :                               || is_global_var (OMP_CLAUSE_DECL (c)));
    5075        12080 :                   continue;
    5076              :                 }
    5077              :             case OMP_CLAUSE_FIRSTPRIVATE:
    5078              :             case OMP_CLAUSE_COPYIN:
    5079              :               break;
    5080        15612 :             case OMP_CLAUSE_LINEAR:
    5081        15612 :               if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
    5082        15612 :                   && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
    5083              :                 lastprivate_firstprivate = true;
    5084              :               break;
    5085        37158 :             case OMP_CLAUSE_REDUCTION:
    5086        37158 :             case OMP_CLAUSE_IN_REDUCTION:
    5087        37158 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
    5088        28910 :                   || is_task_ctx (ctx)
    5089        63728 :                   || OMP_CLAUSE_REDUCTION_TASK (c))
    5090              :                 {
    5091        12780 :                   task_reduction_p = true;
    5092        12780 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
    5093              :                     {
    5094         4532 :                       task_reduction_other_cnt++;
    5095         4532 :                       if (pass == 2)
    5096         1133 :                         continue;
    5097              :                     }
    5098              :                   else
    5099         8248 :                     task_reduction_cnt++;
    5100        11647 :                   if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
    5101              :                     {
    5102          696 :                       var = OMP_CLAUSE_DECL (c);
    5103              :                       /* If var is a global variable that isn't privatized
    5104              :                          in outer contexts, we don't need to look up the
    5105              :                          original address, it is always the address of the
    5106              :                          global variable itself.  */
    5107          696 :                       if (!DECL_P (var)
    5108          272 :                           || omp_privatize_by_reference (var)
    5109          923 :                           || !is_global_var
    5110          227 :                                 (maybe_lookup_decl_in_outer_ctx (var, ctx)))
    5111              :                         {
    5112          594 :                           task_reduction_needs_orig_p = true;
    5113          594 :                           if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
    5114          492 :                             task_reduction_cntorig++;
    5115              :                         }
    5116              :                     }
    5117              :                 }
    5118        24378 :               else if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
    5119       357431 :                 reduction_omp_orig_ref = true;
    5120              :               break;
    5121         3352 :             case OMP_CLAUSE__REDUCTEMP_:
    5122         3352 :               if (!is_taskreg_ctx (ctx))
    5123         1124 :                 continue;
    5124              :               /* FALLTHRU */
    5125       111456 :             case OMP_CLAUSE__LOOPTEMP_:
    5126              :               /* Handle _looptemp_/_reductemp_ clauses only on
    5127              :                  parallel/task.  */
    5128       111456 :               if (fd)
    5129        69210 :                 continue;
    5130              :               break;
    5131        43702 :             case OMP_CLAUSE_LASTPRIVATE:
    5132        43702 :               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
    5133              :                 {
    5134         2058 :                   lastprivate_firstprivate = true;
    5135         2058 :                   if (pass != 0 || is_taskloop_ctx (ctx))
    5136         1343 :                     continue;
    5137              :                 }
    5138              :               /* Even without corresponding firstprivate, if
    5139              :                  decl is Fortran allocatable, it needs outer var
    5140              :                  reference.  */
    5141        41644 :               else if (pass == 0
    5142        62430 :                        && lang_hooks.decls.omp_private_outer_ref
    5143        20786 :                                                         (OMP_CLAUSE_DECL (c)))
    5144              :                 lastprivate_firstprivate = true;
    5145              :               break;
    5146          280 :             case OMP_CLAUSE_ALIGNED:
    5147          280 :               if (pass != 1)
    5148          140 :                 continue;
    5149          140 :               var = OMP_CLAUSE_DECL (c);
    5150          140 :               if (TREE_CODE (TREE_TYPE (var)) == POINTER_TYPE
    5151          140 :                   && !is_global_var (var))
    5152              :                 {
    5153           76 :                   new_var = maybe_lookup_decl (var, ctx);
    5154           76 :                   if (new_var == NULL_TREE)
    5155            6 :                     new_var = maybe_lookup_decl_in_outer_ctx (var, ctx);
    5156           76 :                   x = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
    5157           76 :                   tree alarg = omp_clause_aligned_alignment (c);
    5158           76 :                   alarg = fold_convert_loc (clause_loc, size_type_node, alarg);
    5159           76 :                   x = build_call_expr_loc (clause_loc, x, 2, new_var, alarg);
    5160           76 :                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
    5161           76 :                   x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
    5162           76 :                   gimplify_and_add (x, ilist);
    5163              :                 }
    5164           64 :               else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
    5165           64 :                        && is_global_var (var))
    5166              :                 {
    5167           64 :                   tree ptype = build_pointer_type (TREE_TYPE (var)), t, t2;
    5168           64 :                   new_var = lookup_decl (var, ctx);
    5169           64 :                   t = maybe_lookup_decl_in_outer_ctx (var, ctx);
    5170           64 :                   t = build_fold_addr_expr_loc (clause_loc, t);
    5171           64 :                   t2 = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
    5172           64 :                   tree alarg = omp_clause_aligned_alignment (c);
    5173           64 :                   alarg = fold_convert_loc (clause_loc, size_type_node, alarg);
    5174           64 :                   t = build_call_expr_loc (clause_loc, t2, 2, t, alarg);
    5175           64 :                   t = fold_convert_loc (clause_loc, ptype, t);
    5176           64 :                   x = create_tmp_var (ptype);
    5177           64 :                   t = build2 (MODIFY_EXPR, ptype, x, t);
    5178           64 :                   gimplify_and_add (t, ilist);
    5179           64 :                   t = build_simple_mem_ref_loc (clause_loc, x);
    5180           64 :                   SET_DECL_VALUE_EXPR (new_var, t);
    5181           64 :                   DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    5182              :                 }
    5183          140 :               continue;
    5184         1514 :             case OMP_CLAUSE__CONDTEMP_:
    5185         1514 :               if (is_parallel_ctx (ctx)
    5186         1514 :                   || (is_simd && !OMP_CLAUSE__CONDTEMP__ITER (c)))
    5187              :                 break;
    5188         1094 :               continue;
    5189       135862 :             default:
    5190       135862 :               continue;
    5191       137096 :             }
    5192              : 
    5193       357431 :           if (task_reduction_p != (pass >= 2))
    5194        15616 :             continue;
    5195              : 
    5196       341815 :           allocator = NULL_TREE;
    5197       341815 :           allocate_ptr = NULL_TREE;
    5198       341815 :           new_var = var = OMP_CLAUSE_DECL (c);
    5199       341815 :           if ((c_kind == OMP_CLAUSE_REDUCTION
    5200       341815 :                || c_kind == OMP_CLAUSE_IN_REDUCTION)
    5201        29581 :               && TREE_CODE (var) == MEM_REF)
    5202              :             {
    5203         4356 :               var = TREE_OPERAND (var, 0);
    5204         4356 :               if (TREE_CODE (var) == POINTER_PLUS_EXPR)
    5205          773 :                 var = TREE_OPERAND (var, 0);
    5206         4356 :               if (TREE_CODE (var) == INDIRECT_REF
    5207         4168 :                   || TREE_CODE (var) == ADDR_EXPR)
    5208         2506 :                 var = TREE_OPERAND (var, 0);
    5209         4356 :               if (is_variable_sized (var))
    5210              :                 {
    5211          179 :                   gcc_assert (DECL_HAS_VALUE_EXPR_P (var));
    5212          179 :                   var = DECL_VALUE_EXPR (var);
    5213          179 :                   gcc_assert (TREE_CODE (var) == INDIRECT_REF);
    5214          179 :                   var = TREE_OPERAND (var, 0);
    5215          179 :                   gcc_assert (DECL_P (var));
    5216              :                 }
    5217         4356 :               new_var = var;
    5218              :             }
    5219        29581 :           if (c_kind == OMP_CLAUSE_IN_REDUCTION && is_omp_target (ctx->stmt))
    5220              :             {
    5221          844 :               splay_tree_key key = (splay_tree_key) &DECL_CONTEXT (var);
    5222          844 :               new_var = (tree) splay_tree_lookup (ctx->field_map, key)->value;
    5223              :             }
    5224       340971 :           else if (c_kind != OMP_CLAUSE_COPYIN)
    5225       339951 :             new_var = lookup_decl (var, ctx);
    5226              : 
    5227       341815 :           if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
    5228              :             {
    5229        24808 :               if (pass != 0)
    5230        12403 :                 continue;
    5231              :             }
    5232              :           /* C/C++ array section reductions.  */
    5233       317007 :           else if ((c_kind == OMP_CLAUSE_REDUCTION
    5234              :                     || c_kind == OMP_CLAUSE_IN_REDUCTION)
    5235       317007 :                    && var != OMP_CLAUSE_DECL (c))
    5236              :             {
    5237         4356 :               if (pass == 0)
    5238          873 :                 continue;
    5239              : 
    5240         3483 :               tree bias = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
    5241         3483 :               tree orig_var = TREE_OPERAND (OMP_CLAUSE_DECL (c), 0);
    5242              : 
    5243         3483 :               if (TREE_CODE (orig_var) == POINTER_PLUS_EXPR)
    5244              :                 {
    5245          723 :                   tree b = TREE_OPERAND (orig_var, 1);
    5246          723 :                   if (is_omp_target (ctx->stmt))
    5247              :                     b = NULL_TREE;
    5248              :                   else
    5249          723 :                     b = maybe_lookup_decl (b, ctx);
    5250          723 :                   if (b == NULL)
    5251              :                     {
    5252           17 :                       b = TREE_OPERAND (orig_var, 1);
    5253           17 :                       b = maybe_lookup_decl_in_outer_ctx (b, ctx);
    5254              :                     }
    5255          723 :                   if (integer_zerop (bias))
    5256              :                     bias = b;
    5257              :                   else
    5258              :                     {
    5259            0 :                       bias = fold_convert_loc (clause_loc,
    5260            0 :                                                TREE_TYPE (b), bias);
    5261            0 :                       bias = fold_build2_loc (clause_loc, PLUS_EXPR,
    5262            0 :                                               TREE_TYPE (b), b, bias);
    5263              :                     }
    5264          723 :                   orig_var = TREE_OPERAND (orig_var, 0);
    5265              :                 }
    5266         3483 :               if (pass == 2)
    5267              :                 {
    5268         1149 :                   tree out = maybe_lookup_decl_in_outer_ctx (var, ctx);
    5269         1149 :                   if (is_global_var (out)
    5270          241 :                       && TREE_CODE (TREE_TYPE (out)) != POINTER_TYPE
    5271         1336 :                       && (TREE_CODE (TREE_TYPE (out)) != REFERENCE_TYPE
    5272            0 :                           || (TREE_CODE (TREE_TYPE (TREE_TYPE (out)))
    5273              :                               != POINTER_TYPE)))
    5274              :                     x = var;
    5275          962 :                   else if (is_omp_target (ctx->stmt))
    5276              :                     x = out;
    5277              :                   else
    5278              :                     {
    5279          866 :                       bool by_ref = use_pointer_for_field (var, NULL);
    5280          866 :                       x = build_receiver_ref (var, by_ref, ctx);
    5281          866 :                       if (TREE_CODE (TREE_TYPE (var)) == REFERENCE_TYPE
    5282          866 :                           && (TREE_CODE (TREE_TYPE (TREE_TYPE (var)))
    5283              :                               == POINTER_TYPE))
    5284           32 :                         x = build_fold_addr_expr (x);
    5285              :                     }
    5286         1149 :                   if (TREE_CODE (orig_var) == INDIRECT_REF)
    5287           40 :                     x = build_simple_mem_ref (x);
    5288         1109 :                   else if (TREE_CODE (orig_var) == ADDR_EXPR)
    5289              :                     {
    5290          646 :                       if (var == TREE_OPERAND (orig_var, 0))
    5291          583 :                         x = build_fold_addr_expr (x);
    5292              :                     }
    5293         1149 :                   bias = fold_convert (sizetype, bias);
    5294         1149 :                   x = fold_convert (ptr_type_node, x);
    5295         1149 :                   x = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
    5296         1149 :                                        TREE_TYPE (x), x, bias);
    5297         1149 :                   unsigned cnt = task_reduction_cnt - 1;
    5298         1149 :                   if (!task_reduction_needs_orig_p)
    5299         1061 :                     cnt += (task_reduction_cntorig_full
    5300         1061 :                             - task_reduction_cntorig);
    5301              :                   else
    5302           88 :                     cnt = task_reduction_cntorig - 1;
    5303         1149 :                   tree r = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
    5304         1149 :                                    size_int (cnt), NULL_TREE, NULL_TREE);
    5305         1149 :                   gimplify_assign (r, x, ilist);
    5306         1149 :                   continue;
    5307         1149 :                 }
    5308              : 
    5309         2334 :               if (TREE_CODE (orig_var) == INDIRECT_REF
    5310         2240 :                   || TREE_CODE (orig_var) == ADDR_EXPR)
    5311         1362 :                 orig_var = TREE_OPERAND (orig_var, 0);
    5312         2334 :               tree d = OMP_CLAUSE_DECL (c);
    5313         2334 :               tree type = TREE_TYPE (d);
    5314         2334 :               gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
    5315         2334 :               tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
    5316         2334 :               tree sz = v;
    5317         2334 :               const char *name = get_name (orig_var);
    5318         2334 :               if (pass != 3 && !TREE_CONSTANT (v))
    5319              :                 {
    5320           93 :                   tree t;
    5321           93 :                   if (is_omp_target (ctx->stmt))
    5322              :                     t = NULL_TREE;
    5323              :                   else
    5324           93 :                     t = maybe_lookup_decl (v, ctx);
    5325           93 :                   if (t)
    5326           88 :                     v = t;
    5327              :                   else
    5328            5 :                     v = maybe_lookup_decl_in_outer_ctx (v, ctx);
    5329           93 :                   gimplify_expr (&v, ilist, NULL, is_gimple_val, fb_rvalue);
    5330          186 :                   t = fold_build2_loc (clause_loc, PLUS_EXPR,
    5331           93 :                                        TREE_TYPE (v), v,
    5332           93 :                                        build_int_cst (TREE_TYPE (v), 1));
    5333           93 :                   sz = fold_build2_loc (clause_loc, MULT_EXPR,
    5334           93 :                                         TREE_TYPE (v), t,
    5335           93 :                                         TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5336              :                 }
    5337         2334 :               if (pass == 3)
    5338              :                 {
    5339         1461 :                   tree xv = create_tmp_var (ptr_type_node);
    5340         1461 :                   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
    5341              :                     {
    5342         1149 :                       unsigned cnt = task_reduction_cnt - 1;
    5343         1149 :                       if (!task_reduction_needs_orig_p)
    5344         1061 :                         cnt += (task_reduction_cntorig_full
    5345         1061 :                                 - task_reduction_cntorig);
    5346              :                       else
    5347           88 :                         cnt = task_reduction_cntorig - 1;
    5348         1149 :                       x = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
    5349         1149 :                                   size_int (cnt), NULL_TREE, NULL_TREE);
    5350              : 
    5351         1149 :                       gimple *g = gimple_build_assign (xv, x);
    5352         1149 :                       gimple_seq_add_stmt (ilist, g);
    5353              :                     }
    5354              :                   else
    5355              :                     {
    5356          312 :                       unsigned int idx = *ctx->task_reduction_map->get (c);
    5357          312 :                       tree off;
    5358          312 :                       if (ctx->task_reductions[1 + idx])
    5359           81 :                         off = fold_convert (sizetype,
    5360              :                                             ctx->task_reductions[1 + idx]);
    5361              :                       else
    5362          231 :                         off = task_reduction_read (ilist, tskred_temp, sizetype,
    5363          231 :                                                    7 + 3 * idx + 1);
    5364          312 :                       gimple *g = gimple_build_assign (xv, POINTER_PLUS_EXPR,
    5365              :                                                        tskred_base, off);
    5366          312 :                       gimple_seq_add_stmt (ilist, g);
    5367              :                     }
    5368         1461 :                   x = fold_convert (build_pointer_type (boolean_type_node),
    5369              :                                     xv);
    5370         1461 :                   if (TREE_CONSTANT (v))
    5371         1065 :                     x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (x), x,
    5372              :                                      TYPE_SIZE_UNIT (type));
    5373              :                   else
    5374              :                     {
    5375          396 :                       tree t;
    5376          396 :                       if (is_omp_target (ctx->stmt))
    5377              :                         t = NULL_TREE;
    5378              :                       else
    5379          336 :                         t = maybe_lookup_decl (v, ctx);
    5380          336 :                       if (t)
    5381          316 :                         v = t;
    5382              :                       else
    5383           80 :                         v = maybe_lookup_decl_in_outer_ctx (v, ctx);
    5384          396 :                       gimplify_expr (&v, ilist, NULL, is_gimple_val,
    5385              :                                      fb_rvalue);
    5386          792 :                       t = fold_build2_loc (clause_loc, PLUS_EXPR,
    5387          396 :                                            TREE_TYPE (v), v,
    5388          396 :                                            build_int_cst (TREE_TYPE (v), 1));
    5389          396 :                       t = fold_build2_loc (clause_loc, MULT_EXPR,
    5390          396 :                                            TREE_TYPE (v), t,
    5391          396 :                                            TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5392          396 :                       x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (x), x, t);
    5393              :                     }
    5394         1461 :                   cond = create_tmp_var (TREE_TYPE (x));
    5395         1461 :                   gimplify_assign (cond, x, ilist);
    5396         1461 :                   x = xv;
    5397              :                 }
    5398          873 :               else if (lower_private_allocate (var, type, allocator,
    5399              :                                                allocate_ptr, ilist, ctx,
    5400              :                                                true,
    5401          873 :                                                TREE_CONSTANT (v)
    5402          780 :                                                ? TYPE_SIZE_UNIT (type)
    5403              :                                                : sz))
    5404          225 :                 x = allocate_ptr;
    5405          648 :               else if (TREE_CONSTANT (v))
    5406              :                 {
    5407          560 :                   x = create_tmp_var_raw (type, name);
    5408          560 :                   gimple_add_tmp_var (x);
    5409          560 :                   TREE_ADDRESSABLE (x) = 1;
    5410          560 :                   x = build_fold_addr_expr_loc (clause_loc, x);
    5411              :                 }
    5412              :               else
    5413              :                 {
    5414           88 :                   tree atmp
    5415           88 :                     = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
    5416           88 :                   tree al = size_int (TYPE_ALIGN (TREE_TYPE (type)));
    5417           88 :                   x = build_call_expr_loc (clause_loc, atmp, 2, sz, al);
    5418              :                 }
    5419              : 
    5420         2334 :               tree ptype = build_pointer_type (TREE_TYPE (type));
    5421         2334 :               x = fold_convert_loc (clause_loc, ptype, x);
    5422         2334 :               tree y = create_tmp_var (ptype, name);
    5423         2334 :               gimplify_assign (y, x, ilist);
    5424         2334 :               x = y;
    5425         2334 :               tree yb = y;
    5426              : 
    5427         2334 :               if (!integer_zerop (bias))
    5428              :                 {
    5429         1512 :                   bias = fold_convert_loc (clause_loc, pointer_sized_int_node,
    5430              :                                            bias);
    5431         1512 :                   yb = fold_convert_loc (clause_loc, pointer_sized_int_node,
    5432              :                                          x);
    5433         1512 :                   yb = fold_build2_loc (clause_loc, MINUS_EXPR,
    5434              :                                         pointer_sized_int_node, yb, bias);
    5435         1512 :                   x = fold_convert_loc (clause_loc, TREE_TYPE (x), yb);
    5436         1512 :                   yb = create_tmp_var (ptype, name);
    5437         1512 :                   gimplify_assign (yb, x, ilist);
    5438         1512 :                   x = yb;
    5439              :                 }
    5440              : 
    5441         2334 :               d = TREE_OPERAND (d, 0);
    5442         2334 :               if (TREE_CODE (d) == POINTER_PLUS_EXPR)
    5443          420 :                 d = TREE_OPERAND (d, 0);
    5444         2334 :               if (TREE_CODE (d) == ADDR_EXPR)
    5445              :                 {
    5446         1268 :                   if (orig_var != var)
    5447              :                     {
    5448           91 :                       gcc_assert (is_variable_sized (orig_var));
    5449           91 :                       x = fold_convert_loc (clause_loc, TREE_TYPE (new_var),
    5450              :                                             x);
    5451           91 :                       gimplify_assign (new_var, x, ilist);
    5452           91 :                       tree new_orig_var = lookup_decl (orig_var, ctx);
    5453           91 :                       tree t = build_fold_indirect_ref (new_var);
    5454           91 :                       DECL_IGNORED_P (new_var) = 0;
    5455           91 :                       TREE_THIS_NOTRAP (t) = 1;
    5456           91 :                       SET_DECL_VALUE_EXPR (new_orig_var, t);
    5457           91 :                       DECL_HAS_VALUE_EXPR_P (new_orig_var) = 1;
    5458              :                     }
    5459              :                   else
    5460              :                     {
    5461         1177 :                       x = build2 (MEM_REF, TREE_TYPE (new_var), x,
    5462              :                                   build_int_cst (ptype, 0));
    5463         1177 :                       SET_DECL_VALUE_EXPR (new_var, x);
    5464         1177 :                       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    5465              :                     }
    5466              :                 }
    5467              :               else
    5468              :                 {
    5469         1066 :                   gcc_assert (orig_var == var);
    5470         1066 :                   if (TREE_CODE (d) == INDIRECT_REF)
    5471              :                     {
    5472           94 :                       x = create_tmp_var (ptype, name);
    5473           94 :                       TREE_ADDRESSABLE (x) = 1;
    5474           94 :                       gimplify_assign (x, yb, ilist);
    5475           94 :                       x = build_fold_addr_expr_loc (clause_loc, x);
    5476              :                     }
    5477         1066 :                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
    5478         1066 :                   gimplify_assign (new_var, x, ilist);
    5479              :                 }
    5480              :               /* GOMP_taskgroup_reduction_register memsets the whole
    5481              :                  array to zero.  If the initializer is zero, we don't
    5482              :                  need to initialize it again, just mark it as ever
    5483              :                  used unconditionally, i.e. cond = true.  */
    5484         2334 :               if (cond
    5485         1461 :                   && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == NULL_TREE
    5486         3267 :                   && initializer_zerop (omp_reduction_init (c,
    5487          933 :                                                             TREE_TYPE (type))))
    5488              :                 {
    5489          624 :                   gimple *g = gimple_build_assign (build_simple_mem_ref (cond),
    5490              :                                                    boolean_true_node);
    5491          624 :                   gimple_seq_add_stmt (ilist, g);
    5492          624 :                   continue;
    5493          624 :                 }
    5494         1710 :               tree end = create_artificial_label (UNKNOWN_LOCATION);
    5495         1710 :               if (cond)
    5496              :                 {
    5497          837 :                   gimple *g;
    5498          837 :                   if (!is_parallel_ctx (ctx))
    5499              :                     {
    5500          786 :                       tree condv = create_tmp_var (boolean_type_node);
    5501          786 :                       g = gimple_build_assign (condv,
    5502              :                                                build_simple_mem_ref (cond));
    5503          786 :                       gimple_seq_add_stmt (ilist, g);
    5504          786 :                       tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
    5505          786 :                       g = gimple_build_cond (NE_EXPR, condv,
    5506              :                                              boolean_false_node, end, lab1);
    5507          786 :                       gimple_seq_add_stmt (ilist, g);
    5508          786 :                       gimple_seq_add_stmt (ilist, gimple_build_label (lab1));
    5509              :                     }
    5510          837 :                   g = gimple_build_assign (build_simple_mem_ref (cond),
    5511              :                                            boolean_true_node);
    5512          837 :                   gimple_seq_add_stmt (ilist, g);
    5513              :                 }
    5514              : 
    5515         1710 :               tree y1 = create_tmp_var (ptype);
    5516         1710 :               gimplify_assign (y1, y, ilist);
    5517         1710 :               tree i2 = NULL_TREE, y2 = NULL_TREE;
    5518         1710 :               tree body2 = NULL_TREE, end2 = NULL_TREE;
    5519         1710 :               tree y3 = NULL_TREE, y4 = NULL_TREE;
    5520         1710 :               if (task_reduction_needs_orig_p)
    5521              :                 {
    5522          112 :                   y3 = create_tmp_var (ptype);
    5523          112 :                   tree ref;
    5524          112 :                   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
    5525           88 :                     ref = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
    5526           88 :                                   size_int (task_reduction_cnt_full
    5527              :                                             + task_reduction_cntorig - 1),
    5528              :                                   NULL_TREE, NULL_TREE);
    5529              :                   else
    5530              :                     {
    5531           24 :                       unsigned int idx = *ctx->task_reduction_map->get (c);
    5532           24 :                       ref = task_reduction_read (ilist, tskred_temp, ptype,
    5533           24 :                                                  7 + 3 * idx);
    5534              :                     }
    5535          112 :                   gimplify_assign (y3, ref, ilist);
    5536              :                 }
    5537         1598 :               else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) || is_simd)
    5538              :                 {
    5539          668 :                   if (pass != 3)
    5540              :                     {
    5541          252 :                       y2 = create_tmp_var (ptype);
    5542          252 :                       gimplify_assign (y2, y, ilist);
    5543              :                     }
    5544          668 :                   if (is_simd || OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
    5545              :                     {
    5546          188 :                       tree ref = build_outer_var_ref (var, ctx);
    5547              :                       /* For ref build_outer_var_ref already performs this.  */
    5548          188 :                       if (TREE_CODE (d) == INDIRECT_REF)
    5549            0 :                         gcc_assert (omp_privatize_by_reference (var));
    5550          188 :                       else if (TREE_CODE (d) == ADDR_EXPR)
    5551           96 :                         ref = build_fold_addr_expr (ref);
    5552           92 :                       else if (omp_privatize_by_reference (var))
    5553            8 :                         ref = build_fold_addr_expr (ref);
    5554          188 :                       ref = fold_convert_loc (clause_loc, ptype, ref);
    5555          188 :                       if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
    5556          188 :                           && OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
    5557              :                         {
    5558            8 :                           y3 = create_tmp_var (ptype);
    5559            8 :                           gimplify_assign (y3, unshare_expr (ref), ilist);
    5560              :                         }
    5561          188 :                       if (is_simd)
    5562              :                         {
    5563          180 :                           y4 = create_tmp_var (ptype);
    5564          180 :                           gimplify_assign (y4, ref, dlist);
    5565              :                         }
    5566              :                     }
    5567              :                 }
    5568         1710 :               tree i = create_tmp_var (TREE_TYPE (v));
    5569         1710 :               gimplify_assign (i, build_int_cst (TREE_TYPE (v), 0), ilist);
    5570         1710 :               tree body = create_artificial_label (UNKNOWN_LOCATION);
    5571         1710 :               gimple_seq_add_stmt (ilist, gimple_build_label (body));
    5572         1710 :               if (y2)
    5573              :                 {
    5574          252 :                   i2 = create_tmp_var (TREE_TYPE (v));
    5575          252 :                   gimplify_assign (i2, build_int_cst (TREE_TYPE (v), 0), dlist);
    5576          252 :                   body2 = create_artificial_label (UNKNOWN_LOCATION);
    5577          252 :                   end2 = create_artificial_label (UNKNOWN_LOCATION);
    5578          252 :                   gimple_seq_add_stmt (dlist, gimple_build_label (body2));
    5579              :                 }
    5580         1710 :               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    5581              :                 {
    5582          600 :                   tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
    5583          600 :                   tree decl_placeholder
    5584          600 :                     = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c);
    5585          600 :                   SET_DECL_VALUE_EXPR (decl_placeholder,
    5586              :                                        build_simple_mem_ref (y1));
    5587          600 :                   DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 1;
    5588          600 :                   SET_DECL_VALUE_EXPR (placeholder,
    5589              :                                        y3 ? build_simple_mem_ref (y3)
    5590              :                                        : error_mark_node);
    5591          600 :                   DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
    5592          600 :                   x = lang_hooks.decls.omp_clause_default_ctor
    5593          720 :                                 (c, build_simple_mem_ref (y1),
    5594          120 :                                  y3 ? build_simple_mem_ref (y3) : NULL_TREE);
    5595          600 :                   if (x)
    5596          152 :                     gimplify_and_add (x, ilist);
    5597          600 :                   if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
    5598              :                     {
    5599          576 :                       gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
    5600          576 :                       lower_omp (&tseq, ctx);
    5601          576 :                       gimple_seq_add_seq (ilist, tseq);
    5602              :                     }
    5603          600 :                   OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
    5604          600 :                   if (is_simd)
    5605              :                     {
    5606            0 :                       SET_DECL_VALUE_EXPR (decl_placeholder,
    5607              :                                            build_simple_mem_ref (y2));
    5608            0 :                       SET_DECL_VALUE_EXPR (placeholder,
    5609              :                                            build_simple_mem_ref (y4));
    5610            0 :                       gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
    5611            0 :                       lower_omp (&tseq, ctx);
    5612            0 :                       gimple_seq_add_seq (dlist, tseq);
    5613            0 :                       OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    5614              :                     }
    5615          600 :                   DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
    5616          600 :                   DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 0;
    5617          600 :                   if (y2)
    5618              :                     {
    5619           72 :                       x = lang_hooks.decls.omp_clause_dtor
    5620           72 :                                                 (c, build_simple_mem_ref (y2));
    5621           72 :                       if (x)
    5622           40 :                         gimplify_and_add (x, dlist);
    5623              :                     }
    5624              :                 }
    5625              :               else
    5626              :                 {
    5627         1110 :                   x = omp_reduction_init (c, TREE_TYPE (type));
    5628         1110 :                   enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
    5629              : 
    5630              :                   /* reduction(-:var) sums up the partial results, so it
    5631              :                      acts identically to reduction(+:var).  */
    5632         1110 :                   if (code == MINUS_EXPR)
    5633            0 :                     code = PLUS_EXPR;
    5634              : 
    5635         1110 :                   gimplify_assign (build_simple_mem_ref (y1), x, ilist);
    5636         1110 :                   if (is_simd)
    5637              :                     {
    5638          180 :                       x = build2 (code, TREE_TYPE (type),
    5639              :                                   build_simple_mem_ref (y4),
    5640              :                                   build_simple_mem_ref (y2));
    5641          180 :                       gimplify_assign (build_simple_mem_ref (y4), x, dlist);
    5642              :                     }
    5643              :                 }
    5644         1710 :               gimple *g
    5645         1710 :                 = gimple_build_assign (y1, POINTER_PLUS_EXPR, y1,
    5646         1710 :                                        TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5647         1710 :               gimple_seq_add_stmt (ilist, g);
    5648         1710 :               if (y3)
    5649              :                 {
    5650          120 :                   g = gimple_build_assign (y3, POINTER_PLUS_EXPR, y3,
    5651          120 :                                            TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5652          120 :                   gimple_seq_add_stmt (ilist, g);
    5653              :                 }
    5654         1710 :               g = gimple_build_assign (i, PLUS_EXPR, i,
    5655         1710 :                                        build_int_cst (TREE_TYPE (i), 1));
    5656         1710 :               gimple_seq_add_stmt (ilist, g);
    5657         1710 :               g = gimple_build_cond (LE_EXPR, i, v, body, end);
    5658         1710 :               gimple_seq_add_stmt (ilist, g);
    5659         1710 :               gimple_seq_add_stmt (ilist, gimple_build_label (end));
    5660         1710 :               if (y2)
    5661              :                 {
    5662          252 :                   g = gimple_build_assign (y2, POINTER_PLUS_EXPR, y2,
    5663          252 :                                            TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5664          252 :                   gimple_seq_add_stmt (dlist, g);
    5665          252 :                   if (y4)
    5666              :                     {
    5667          180 :                       g = gimple_build_assign
    5668          180 :                                         (y4, POINTER_PLUS_EXPR, y4,
    5669          180 :                                          TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5670          180 :                       gimple_seq_add_stmt (dlist, g);
    5671              :                     }
    5672          252 :                   g = gimple_build_assign (i2, PLUS_EXPR, i2,
    5673          252 :                                            build_int_cst (TREE_TYPE (i2), 1));
    5674          252 :                   gimple_seq_add_stmt (dlist, g);
    5675          252 :                   g = gimple_build_cond (LE_EXPR, i2, v, body2, end2);
    5676          252 :                   gimple_seq_add_stmt (dlist, g);
    5677          252 :                   gimple_seq_add_stmt (dlist, gimple_build_label (end2));
    5678              :                 }
    5679         1710 :               if (allocator)
    5680              :                 {
    5681          225 :                   tree f = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
    5682          225 :                   g = gimple_build_call (f, 2, allocate_ptr, allocator);
    5683          225 :                   gimple_seq_add_stmt (dlist, g);
    5684              :                 }
    5685         1710 :               continue;
    5686         1710 :             }
    5687       312651 :           else if (pass == 2)
    5688              :             {
    5689          913 :               tree out = maybe_lookup_decl_in_outer_ctx (var, ctx);
    5690          913 :               if (is_global_var (out))
    5691              :                 x = var;
    5692          361 :               else if (is_omp_target (ctx->stmt))
    5693              :                 x = out;
    5694              :               else
    5695              :                 {
    5696          301 :                   bool by_ref = use_pointer_for_field (var, ctx);
    5697          301 :                   x = build_receiver_ref (var, by_ref, ctx);
    5698              :                 }
    5699          913 :               if (!omp_privatize_by_reference (var))
    5700          823 :                 x = build_fold_addr_expr (x);
    5701          913 :               x = fold_convert (ptr_type_node, x);
    5702          913 :               unsigned cnt = task_reduction_cnt - 1;
    5703          913 :               if (!task_reduction_needs_orig_p)
    5704          878 :                 cnt += task_reduction_cntorig_full - task_reduction_cntorig;
    5705              :               else
    5706           35 :                 cnt = task_reduction_cntorig - 1;
    5707          913 :               tree r = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
    5708          913 :                                size_int (cnt), NULL_TREE, NULL_TREE);
    5709          913 :               gimplify_assign (r, x, ilist);
    5710          913 :               continue;
    5711          913 :             }
    5712       311738 :           else if (pass == 3)
    5713              :             {
    5714         1734 :               tree type = TREE_TYPE (new_var);
    5715         1734 :               if (!omp_privatize_by_reference (var))
    5716         1628 :                 type = build_pointer_type (type);
    5717         1734 :               if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
    5718              :                 {
    5719          913 :                   unsigned cnt = task_reduction_cnt - 1;
    5720          913 :                   if (!task_reduction_needs_orig_p)
    5721          878 :                     cnt += (task_reduction_cntorig_full
    5722          878 :                             - task_reduction_cntorig);
    5723              :                   else
    5724           35 :                     cnt = task_reduction_cntorig - 1;
    5725          913 :                   x = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
    5726          913 :                               size_int (cnt), NULL_TREE, NULL_TREE);
    5727              :                 }
    5728              :               else
    5729              :                 {
    5730          821 :                   unsigned int idx = *ctx->task_reduction_map->get (c);
    5731          821 :                   tree off;
    5732          821 :                   if (ctx->task_reductions[1 + idx])
    5733          821 :                     off = fold_convert (sizetype,
    5734              :                                         ctx->task_reductions[1 + idx]);
    5735              :                   else
    5736            0 :                     off = task_reduction_read (ilist, tskred_temp, sizetype,
    5737            0 :                                                7 + 3 * idx + 1);
    5738          821 :                   x = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
    5739              :                                    tskred_base, off);
    5740              :                 }
    5741         1734 :               x = fold_convert (type, x);
    5742         1734 :               tree t;
    5743         1734 :               if (omp_privatize_by_reference (var))
    5744              :                 {
    5745          106 :                   gimplify_assign (new_var, x, ilist);
    5746          106 :                   t = new_var;
    5747          106 :                   new_var = build_simple_mem_ref (new_var);
    5748              :                 }
    5749              :               else
    5750              :                 {
    5751         1628 :                   t = create_tmp_var (type);
    5752         1628 :                   gimplify_assign (t, x, ilist);
    5753         1628 :                   SET_DECL_VALUE_EXPR (new_var, build_simple_mem_ref (t));
    5754         1628 :                   DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    5755              :                 }
    5756         1734 :               t = fold_convert (build_pointer_type (boolean_type_node), t);
    5757         1734 :               t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t,
    5758              :                                TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5759         1734 :               cond = create_tmp_var (TREE_TYPE (t));
    5760         1734 :               gimplify_assign (cond, t, ilist);
    5761              :             }
    5762       310004 :           else if (is_variable_sized (var))
    5763              :             {
    5764              :               /* For variable sized types, we need to allocate the
    5765              :                  actual storage here.  Call alloca and store the
    5766              :                  result in the pointer decl that we created elsewhere.  */
    5767          262 :               if (pass == 0)
    5768          134 :                 continue;
    5769              : 
    5770          128 :               if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
    5771              :                 {
    5772          114 :                   tree tmp;
    5773              : 
    5774          114 :                   ptr = DECL_VALUE_EXPR (new_var);
    5775          114 :                   gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
    5776          114 :                   ptr = TREE_OPERAND (ptr, 0);
    5777          114 :                   gcc_assert (DECL_P (ptr));
    5778          114 :                   x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
    5779              : 
    5780          114 :                   if (lower_private_allocate (var, new_var, allocator,
    5781              :                                               allocate_ptr, ilist, ctx,
    5782              :                                               false, x))
    5783            8 :                     tmp = allocate_ptr;
    5784              :                   else
    5785              :                     {
    5786              :                       /* void *tmp = __builtin_alloca */
    5787          106 :                       tree atmp
    5788          106 :                         = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
    5789          106 :                       gcall *stmt
    5790          106 :                         = gimple_build_call (atmp, 2, x,
    5791          106 :                                              size_int (DECL_ALIGN (var)));
    5792          106 :                       cfun->calls_alloca = 1;
    5793          106 :                       tmp = create_tmp_var_raw (ptr_type_node);
    5794          106 :                       gimple_add_tmp_var (tmp);
    5795          106 :                       gimple_call_set_lhs (stmt, tmp);
    5796              : 
    5797          106 :                       gimple_seq_add_stmt (ilist, stmt);
    5798              :                     }
    5799              : 
    5800          114 :                   x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
    5801          114 :                   gimplify_assign (ptr, x, ilist);
    5802              :                 }
    5803              :             }
    5804       309742 :           else if (omp_privatize_by_reference (var)
    5805       309742 :                    && (c_kind != OMP_CLAUSE_FIRSTPRIVATE
    5806         1992 :                        || !OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c)))
    5807              :             {
    5808              :               /* For references that are being privatized for Fortran,
    5809              :                  allocate new backing storage for the new pointer
    5810              :                  variable.  This allows us to avoid changing all the
    5811              :                  code that expects a pointer to something that expects
    5812              :                  a direct variable.  */
    5813         4871 :               if (pass == 0)
    5814         2538 :                 continue;
    5815              : 
    5816         2333 :               x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
    5817         2333 :               if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
    5818              :                 {
    5819          146 :                   x = build_receiver_ref (var, false, ctx);
    5820          146 :                   if (ctx->allocate_map)
    5821           16 :                     if (tree *allocatep = ctx->allocate_map->get (var))
    5822              :                       {
    5823           16 :                         allocator = *allocatep;
    5824           16 :                         if (TREE_CODE (allocator) == TREE_LIST)
    5825            0 :                           allocator = TREE_PURPOSE (allocator);
    5826           16 :                         if (TREE_CODE (allocator) != INTEGER_CST)
    5827            8 :                           allocator = build_outer_var_ref (allocator, ctx);
    5828           16 :                         allocator = fold_convert (pointer_sized_int_node,
    5829              :                                                   allocator);
    5830           16 :                         allocate_ptr = unshare_expr (x);
    5831              :                       }
    5832          146 :                   if (allocator == NULL_TREE)
    5833          130 :                     x = build_fold_addr_expr_loc (clause_loc, x);
    5834              :                 }
    5835         2187 :               else if (lower_private_allocate (var, new_var, allocator,
    5836              :                                                allocate_ptr,
    5837              :                                                ilist, ctx, true, x))
    5838           86 :                 x = allocate_ptr;
    5839         2101 :               else if (TREE_CONSTANT (x))
    5840              :                 {
    5841              :                   /* For reduction in SIMD loop, defer adding the
    5842              :                      initialization of the reference, because if we decide
    5843              :                      to use SIMD array for it, the initilization could cause
    5844              :                      expansion ICE.  Ditto for other privatization clauses.  */
    5845         1404 :                   if (is_simd)
    5846              :                     x = NULL_TREE;
    5847              :                   else
    5848              :                     {
    5849         1077 :                       x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
    5850              :                                               get_name (var));
    5851         1077 :                       gimple_add_tmp_var (x);
    5852         1077 :                       TREE_ADDRESSABLE (x) = 1;
    5853         1077 :                       x = build_fold_addr_expr_loc (clause_loc, x);
    5854              :                     }
    5855              :                 }
    5856              :               else
    5857              :                 {
    5858          697 :                   tree atmp
    5859          697 :                     = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
    5860          697 :                   tree rtype = TREE_TYPE (TREE_TYPE (new_var));
    5861          697 :                   tree al = size_int (TYPE_ALIGN (rtype));
    5862          697 :                   x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
    5863              :                 }
    5864              : 
    5865         2006 :               if (x)
    5866              :                 {
    5867         2006 :                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
    5868         2006 :                   gimplify_assign (new_var, x, ilist);
    5869              :                 }
    5870              : 
    5871         2333 :               new_var = build_simple_mem_ref_loc (clause_loc, new_var);
    5872              :             }
    5873       304871 :           else if ((c_kind == OMP_CLAUSE_REDUCTION
    5874              :                     || c_kind == OMP_CLAUSE_IN_REDUCTION)
    5875       304871 :                    && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    5876              :             {
    5877         1952 :               if (pass == 0)
    5878          976 :                 continue;
    5879              :             }
    5880       302919 :           else if (pass != 0)
    5881       151205 :             continue;
    5882              : 
    5883       169290 :           switch (OMP_CLAUSE_CODE (c))
    5884              :             {
    5885        11895 :             case OMP_CLAUSE_SHARED:
    5886              :               /* Ignore shared directives in teams construct inside
    5887              :                  target construct.  */
    5888        11895 :               if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
    5889        11895 :                   && !is_host_teams_ctx (ctx))
    5890            0 :                 continue;
    5891              :               /* Shared global vars are just accessed directly.  */
    5892        11895 :               if (is_global_var (new_var))
    5893              :                 break;
    5894              :               /* For taskloop firstprivate/lastprivate, represented
    5895              :                  as firstprivate and shared clause on the task, new_var
    5896              :                  is the firstprivate var.  */
    5897        11741 :               if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
    5898              :                 break;
    5899              :               /* Set up the DECL_VALUE_EXPR for shared variables now.  This
    5900              :                  needs to be delayed until after fixup_child_record_type so
    5901              :                  that we get the correct type during the dereference.  */
    5902        11429 :               by_ref = use_pointer_for_field (var, ctx);
    5903        11429 :               x = build_receiver_ref (var, by_ref, ctx);
    5904        11429 :               SET_DECL_VALUE_EXPR (new_var, x);
    5905        11429 :               DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    5906              : 
    5907              :               /* ??? If VAR is not passed by reference, and the variable
    5908              :                  hasn't been initialized yet, then we'll get a warning for
    5909              :                  the store into the omp_data_s structure.  Ideally, we'd be
    5910              :                  able to notice this and not store anything at all, but
    5911              :                  we're generating code too early.  Suppress the warning.  */
    5912        11429 :               if (!by_ref)
    5913         5203 :                 suppress_warning (var, OPT_Wuninitialized);
    5914              :               break;
    5915              : 
    5916          210 :             case OMP_CLAUSE__CONDTEMP_:
    5917          210 :               if (is_parallel_ctx (ctx))
    5918              :                 {
    5919          103 :                   x = build_receiver_ref (var, false, ctx);
    5920          103 :                   SET_DECL_VALUE_EXPR (new_var, x);
    5921          103 :                   DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    5922              :                 }
    5923          107 :               else if (is_simd && !OMP_CLAUSE__CONDTEMP__ITER (c))
    5924              :                 {
    5925          107 :                   x = build_zero_cst (TREE_TYPE (var));
    5926          107 :                   goto do_private;
    5927              :                 }
    5928              :               break;
    5929              : 
    5930        21290 :             case OMP_CLAUSE_LASTPRIVATE:
    5931        21290 :               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
    5932              :                 break;
    5933              :               /* FALLTHRU */
    5934              : 
    5935        87386 :             case OMP_CLAUSE_PRIVATE:
    5936        87386 :               if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
    5937        20786 :                 x = build_outer_var_ref (var, ctx);
    5938        66600 :               else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
    5939              :                 {
    5940          163 :                   if (is_task_ctx (ctx))
    5941           12 :                     x = build_receiver_ref (var, false, ctx);
    5942              :                   else
    5943          151 :                     x = build_outer_var_ref (var, ctx, OMP_CLAUSE_PRIVATE);
    5944              :                 }
    5945              :               else
    5946              :                 x = NULL;
    5947        94030 :             do_private:
    5948        94030 :               tree nx;
    5949        94030 :               bool copy_ctor;
    5950        94030 :               copy_ctor = false;
    5951        94030 :               lower_private_allocate (var, new_var, allocator, allocate_ptr,
    5952              :                                       ilist, ctx, false, NULL_TREE);
    5953        94030 :               nx = unshare_expr (new_var);
    5954        94030 :               if (is_simd
    5955        24199 :                   && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    5956       101416 :                   && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
    5957           22 :                 copy_ctor = true;
    5958        94030 :               if (copy_ctor)
    5959           22 :                 nx = lang_hooks.decls.omp_clause_copy_ctor (c, nx, x);
    5960              :               else
    5961        94008 :                 nx = lang_hooks.decls.omp_clause_default_ctor (c, nx, x);
    5962        94030 :               if (is_simd)
    5963              :                 {
    5964        24199 :                   tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
    5965        23517 :                   if ((TREE_ADDRESSABLE (new_var) || nx || y
    5966        23501 :                        || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    5967         7010 :                            && (gimple_omp_for_collapse (ctx->stmt) != 1
    5968         1375 :                                || (gimple_omp_for_index (ctx->stmt, 0)
    5969              :                                    != new_var)))
    5970        16793 :                        || OMP_CLAUSE_CODE (c) == OMP_CLAUSE__CONDTEMP_
    5971        16686 :                        || omp_privatize_by_reference (var))
    5972        31064 :                       && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
    5973              :                                                        ivar, lvar))
    5974              :                     {
    5975         5996 :                       if (omp_privatize_by_reference (var))
    5976              :                         {
    5977           52 :                           gcc_assert (TREE_CODE (new_var) == MEM_REF);
    5978           52 :                           tree new_vard = TREE_OPERAND (new_var, 0);
    5979           52 :                           gcc_assert (DECL_P (new_vard));
    5980           52 :                           SET_DECL_VALUE_EXPR (new_vard,
    5981              :                                                build_fold_addr_expr (lvar));
    5982           52 :                           DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
    5983              :                         }
    5984              : 
    5985         5996 :                       if (nx)
    5986              :                         {
    5987           30 :                           tree iv = unshare_expr (ivar);
    5988           30 :                           if (copy_ctor)
    5989           22 :                             x = lang_hooks.decls.omp_clause_copy_ctor (c, iv,
    5990              :                                                                        x);
    5991              :                           else
    5992            8 :                             x = lang_hooks.decls.omp_clause_default_ctor (c,
    5993              :                                                                           iv,
    5994              :                                                                           x);
    5995              :                         }
    5996         5966 :                       else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__CONDTEMP_)
    5997              :                         {
    5998           37 :                           x = build2 (MODIFY_EXPR, TREE_TYPE (ivar),
    5999              :                                       unshare_expr (ivar), x);
    6000           37 :                           nx = x;
    6001              :                         }
    6002         5996 :                       if (nx && x)
    6003           67 :                         gimplify_and_add (x, &llist[0]);
    6004         5996 :                       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    6005         5996 :                           && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
    6006              :                         {
    6007           37 :                           tree v = new_var;
    6008           37 :                           if (!DECL_P (v))
    6009              :                             {
    6010            4 :                               gcc_assert (TREE_CODE (v) == MEM_REF);
    6011            4 :                               v = TREE_OPERAND (v, 0);
    6012            4 :                               gcc_assert (DECL_P (v));
    6013              :                             }
    6014           37 :                           v = *ctx->lastprivate_conditional_map->get (v);
    6015           37 :                           tree t = create_tmp_var (TREE_TYPE (v));
    6016           37 :                           tree z = build_zero_cst (TREE_TYPE (v));
    6017           37 :                           tree orig_v
    6018           37 :                             = build_outer_var_ref (var, ctx,
    6019              :                                                    OMP_CLAUSE_LASTPRIVATE);
    6020           37 :                           gimple_seq_add_stmt (dlist,
    6021           37 :                                                gimple_build_assign (t, z));
    6022           37 :                           gcc_assert (DECL_HAS_VALUE_EXPR_P (v));
    6023           37 :                           tree civar = DECL_VALUE_EXPR (v);
    6024           37 :                           gcc_assert (TREE_CODE (civar) == ARRAY_REF);
    6025           37 :                           civar = unshare_expr (civar);
    6026           37 :                           TREE_OPERAND (civar, 1) = sctx.idx;
    6027           37 :                           x = build2 (MODIFY_EXPR, TREE_TYPE (t), t,
    6028              :                                       unshare_expr (civar));
    6029           74 :                           x = build2 (COMPOUND_EXPR, TREE_TYPE (orig_v), x,
    6030           37 :                                       build2 (MODIFY_EXPR, TREE_TYPE (orig_v),
    6031              :                                               orig_v, unshare_expr (ivar)));
    6032           37 :                           tree cond = build2 (LT_EXPR, boolean_type_node, t,
    6033              :                                               civar);
    6034           37 :                           x = build3 (COND_EXPR, void_type_node, cond, x,
    6035              :                                       void_node);
    6036           37 :                           gimple_seq tseq = NULL;
    6037           37 :                           gimplify_and_add (x, &tseq);
    6038           37 :                           if (ctx->outer)
    6039           27 :                             lower_omp (&tseq, ctx->outer);
    6040           37 :                           gimple_seq_add_seq (&llist[1], tseq);
    6041              :                         }
    6042         5996 :                       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    6043         5996 :                           && ctx->for_simd_scan_phase)
    6044              :                         {
    6045            9 :                           x = unshare_expr (ivar);
    6046            9 :                           tree orig_v
    6047            9 :                             = build_outer_var_ref (var, ctx,
    6048              :                                                    OMP_CLAUSE_LASTPRIVATE);
    6049            9 :                           x = lang_hooks.decls.omp_clause_assign_op (c, x,
    6050              :                                                                      orig_v);
    6051            9 :                           gimplify_and_add (x, &llist[0]);
    6052              :                         }
    6053         5996 :                       if (y)
    6054              :                         {
    6055           30 :                           y = lang_hooks.decls.omp_clause_dtor (c, ivar);
    6056           30 :                           if (y)
    6057           30 :                             gimplify_and_add (y, &llist[1]);
    6058              :                         }
    6059              :                       break;
    6060              :                     }
    6061        18203 :                   if (omp_privatize_by_reference (var))
    6062              :                     {
    6063           28 :                       gcc_assert (TREE_CODE (new_var) == MEM_REF);
    6064           28 :                       tree new_vard = TREE_OPERAND (new_var, 0);
    6065           28 :                       gcc_assert (DECL_P (new_vard));
    6066           28 :                       tree type = TREE_TYPE (TREE_TYPE (new_vard));
    6067           28 :                       x = TYPE_SIZE_UNIT (type);
    6068           28 :                       if (TREE_CONSTANT (x))
    6069              :                         {
    6070           28 :                           x = create_tmp_var_raw (type, get_name (var));
    6071           28 :                           gimple_add_tmp_var (x);
    6072           28 :                           TREE_ADDRESSABLE (x) = 1;
    6073           28 :                           x = build_fold_addr_expr_loc (clause_loc, x);
    6074           28 :                           x = fold_convert_loc (clause_loc,
    6075           28 :                                                 TREE_TYPE (new_vard), x);
    6076           28 :                           gimplify_assign (new_vard, x, ilist);
    6077              :                         }
    6078              :                     }
    6079              :                 }
    6080        88034 :               if (nx)
    6081          486 :                 gimplify_and_add (nx, ilist);
    6082        88034 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    6083        15148 :                   && is_simd
    6084        89782 :                   && ctx->for_simd_scan_phase)
    6085              :                 {
    6086            5 :                   tree orig_v = build_outer_var_ref (var, ctx,
    6087              :                                                      OMP_CLAUSE_LASTPRIVATE);
    6088            5 :                   x = lang_hooks.decls.omp_clause_assign_op (c, new_var,
    6089              :                                                              orig_v);
    6090            5 :                   gimplify_and_add (x, ilist);
    6091              :                 }
    6092              :               /* FALLTHRU */
    6093              : 
    6094       118787 :             do_dtor:
    6095       118787 :               x = lang_hooks.decls.omp_clause_dtor (c, new_var);
    6096       118787 :               if (x)
    6097         1126 :                 gimplify_and_add (x, dlist);
    6098       118787 :               if (allocator)
    6099              :                 {
    6100          847 :                   if (!is_gimple_val (allocator))
    6101              :                     {
    6102           22 :                       tree avar = create_tmp_var (TREE_TYPE (allocator));
    6103           22 :                       gimplify_assign (avar, allocator, dlist);
    6104           22 :                       allocator = avar;
    6105              :                     }
    6106          847 :                   if (!is_gimple_val (allocate_ptr))
    6107              :                     {
    6108           50 :                       tree apvar = create_tmp_var (TREE_TYPE (allocate_ptr));
    6109           50 :                       gimplify_assign (apvar, allocate_ptr, dlist);
    6110           50 :                       allocate_ptr = apvar;
    6111              :                     }
    6112          847 :                   tree f = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
    6113          847 :                   gimple *g
    6114          847 :                     = gimple_build_call (f, 2, allocate_ptr, allocator);
    6115          847 :                   gimple_seq_add_stmt (dlist, g);
    6116              :                 }
    6117              :               break;
    6118              : 
    6119         7806 :             case OMP_CLAUSE_LINEAR:
    6120         7806 :               if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
    6121         1269 :                 goto do_firstprivate;
    6122         6537 :               if (OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
    6123              :                 x = NULL;
    6124              :               else
    6125         3598 :                 x = build_outer_var_ref (var, ctx);
    6126         6537 :               goto do_private;
    6127              : 
    6128        28604 :             case OMP_CLAUSE_FIRSTPRIVATE:
    6129        28604 :               if (is_task_ctx (ctx))
    6130              :                 {
    6131         4628 :                   if ((omp_privatize_by_reference (var)
    6132          146 :                        && !OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c))
    6133         4628 :                       || is_variable_sized (var))
    6134          160 :                     goto do_dtor;
    6135         4468 :                   else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
    6136              :                                                                           ctx))
    6137         4468 :                            || use_pointer_for_field (var, NULL))
    6138              :                     {
    6139          421 :                       x = build_receiver_ref (var, false, ctx);
    6140          421 :                       if (ctx->allocate_map)
    6141           34 :                         if (tree *allocatep = ctx->allocate_map->get (var))
    6142              :                           {
    6143           34 :                             allocator = *allocatep;
    6144           34 :                             if (TREE_CODE (allocator) == TREE_LIST)
    6145            4 :                               allocator = TREE_PURPOSE (allocator);
    6146           34 :                             if (TREE_CODE (allocator) != INTEGER_CST)
    6147           14 :                               allocator = build_outer_var_ref (allocator, ctx);
    6148           34 :                             allocator = fold_convert (pointer_sized_int_node,
    6149              :                                                       allocator);
    6150           34 :                             allocate_ptr = unshare_expr (x);
    6151           34 :                             x = build_simple_mem_ref (x);
    6152           34 :                             TREE_THIS_NOTRAP (x) = 1;
    6153              :                           }
    6154          421 :                       SET_DECL_VALUE_EXPR (new_var, x);
    6155          421 :                       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    6156          421 :                       goto do_dtor;
    6157              :                     }
    6158              :                 }
    6159        28023 :               if (OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c)
    6160        28023 :                   && omp_privatize_by_reference (var))
    6161              :                 {
    6162            0 :                   x = build_outer_var_ref (var, ctx);
    6163            0 :                   gcc_assert (TREE_CODE (x) == MEM_REF
    6164              :                               && integer_zerop (TREE_OPERAND (x, 1)));
    6165            0 :                   x = TREE_OPERAND (x, 0);
    6166            0 :                   x = lang_hooks.decls.omp_clause_copy_ctor
    6167            0 :                                                 (c, unshare_expr (new_var), x);
    6168            0 :                   gimplify_and_add (x, ilist);
    6169            0 :                   goto do_dtor;
    6170              :                 }
    6171        29292 :             do_firstprivate:
    6172        29292 :               lower_private_allocate (var, new_var, allocator, allocate_ptr,
    6173              :                                       ilist, ctx, false, NULL_TREE);
    6174        29292 :               x = build_outer_var_ref (var, ctx);
    6175        29292 :               if (is_simd)
    6176              :                 {
    6177         1063 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
    6178         1063 :                       && gimple_omp_for_combined_into_p (ctx->stmt))
    6179              :                     {
    6180          668 :                       tree t = OMP_CLAUSE_LINEAR_STEP (c);
    6181          668 :                       if (DECL_P (t))
    6182          114 :                         t = build_outer_var_ref (t, ctx);
    6183          668 :                       tree stept = TREE_TYPE (t);
    6184          668 :                       tree ct = omp_find_clause (clauses,
    6185              :                                                  OMP_CLAUSE__LOOPTEMP_);
    6186          668 :                       gcc_assert (ct);
    6187          668 :                       tree l = OMP_CLAUSE_DECL (ct);
    6188          668 :                       tree n1 = fd->loop.n1;
    6189          668 :                       tree step = fd->loop.step;
    6190          668 :                       tree itype = TREE_TYPE (l);
    6191          668 :                       if (POINTER_TYPE_P (itype))
    6192            0 :                         itype = signed_type_for (itype);
    6193          668 :                       l = fold_build2 (MINUS_EXPR, itype, l, n1);
    6194          668 :                       if (TYPE_UNSIGNED (itype)
    6195          668 :                           && fd->loop.cond_code == GT_EXPR)
    6196            0 :                         l = fold_build2 (TRUNC_DIV_EXPR, itype,
    6197              :                                          fold_build1 (NEGATE_EXPR, itype, l),
    6198              :                                          fold_build1 (NEGATE_EXPR,
    6199              :                                                       itype, step));
    6200              :                       else
    6201          668 :                         l = fold_build2 (TRUNC_DIV_EXPR, itype, l, step);
    6202          668 :                       t = fold_build2 (MULT_EXPR, stept,
    6203              :                                        fold_convert (stept, l), t);
    6204              : 
    6205          668 :                       if (OMP_CLAUSE_LINEAR_ARRAY (c))
    6206              :                         {
    6207          108 :                           if (omp_privatize_by_reference (var))
    6208              :                             {
    6209           72 :                               gcc_assert (TREE_CODE (new_var) == MEM_REF);
    6210           72 :                               tree new_vard = TREE_OPERAND (new_var, 0);
    6211           72 :                               gcc_assert (DECL_P (new_vard));
    6212           72 :                               tree type = TREE_TYPE (TREE_TYPE (new_vard));
    6213           72 :                               nx = TYPE_SIZE_UNIT (type);
    6214           72 :                               if (TREE_CONSTANT (nx))
    6215              :                                 {
    6216           24 :                                   nx = create_tmp_var_raw (type,
    6217              :                                                            get_name (var));
    6218           24 :                                   gimple_add_tmp_var (nx);
    6219           24 :                                   TREE_ADDRESSABLE (nx) = 1;
    6220           24 :                                   nx = build_fold_addr_expr_loc (clause_loc,
    6221              :                                                                  nx);
    6222           24 :                                   nx = fold_convert_loc (clause_loc,
    6223           24 :                                                          TREE_TYPE (new_vard),
    6224              :                                                          nx);
    6225           24 :                                   gimplify_assign (new_vard, nx, ilist);
    6226              :                                 }
    6227              :                             }
    6228              : 
    6229          108 :                           x = lang_hooks.decls.omp_clause_linear_ctor
    6230          108 :                                                         (c, new_var, x, t);
    6231          108 :                           gimplify_and_add (x, ilist);
    6232          108 :                           goto do_dtor;
    6233              :                         }
    6234              : 
    6235          560 :                       if (POINTER_TYPE_P (TREE_TYPE (x)))
    6236           11 :                         x = fold_build_pointer_plus (x, t);
    6237              :                       else
    6238          549 :                         x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x,
    6239              :                                          fold_convert (TREE_TYPE (x), t));
    6240              :                     }
    6241              : 
    6242          955 :                   if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
    6243          934 :                        || TREE_ADDRESSABLE (new_var)
    6244          799 :                        || omp_privatize_by_reference (var))
    6245         1217 :                       && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
    6246              :                                                        ivar, lvar))
    6247              :                     {
    6248          152 :                       if (omp_privatize_by_reference (var))
    6249              :                         {
    6250           22 :                           gcc_assert (TREE_CODE (new_var) == MEM_REF);
    6251           22 :                           tree new_vard = TREE_OPERAND (new_var, 0);
    6252           22 :                           gcc_assert (DECL_P (new_vard));
    6253           22 :                           SET_DECL_VALUE_EXPR (new_vard,
    6254              :                                                build_fold_addr_expr (lvar));
    6255           22 :                           DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
    6256              :                         }
    6257          152 :                       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
    6258              :                         {
    6259          131 :                           tree iv = create_tmp_var (TREE_TYPE (new_var));
    6260          131 :                           x = lang_hooks.decls.omp_clause_copy_ctor (c, iv, x);
    6261          131 :                           gimplify_and_add (x, ilist);
    6262          131 :                           gimple_stmt_iterator gsi
    6263          131 :                             = gsi_start (*gimple_omp_body_ptr (ctx->stmt));
    6264          131 :                           gassign *g
    6265          131 :                             = gimple_build_assign (unshare_expr (lvar), iv);
    6266          131 :                           gsi_insert_before_without_update (&gsi, g,
    6267              :                                                             GSI_SAME_STMT);
    6268          131 :                           tree t = OMP_CLAUSE_LINEAR_STEP (c);
    6269          131 :                           enum tree_code code = PLUS_EXPR;
    6270          131 :                           if (POINTER_TYPE_P (TREE_TYPE (new_var)))
    6271              :                             code = POINTER_PLUS_EXPR;
    6272          131 :                           g = gimple_build_assign (iv, code, iv, t);
    6273          131 :                           gsi_insert_before_without_update (&gsi, g,
    6274              :                                                             GSI_SAME_STMT);
    6275          131 :                           break;
    6276              :                         }
    6277           21 :                       x = lang_hooks.decls.omp_clause_copy_ctor
    6278           21 :                                                 (c, unshare_expr (ivar), x);
    6279           21 :                       gimplify_and_add (x, &llist[0]);
    6280           21 :                       x = lang_hooks.decls.omp_clause_dtor (c, ivar);
    6281           21 :                       if (x)
    6282           21 :                         gimplify_and_add (x, &llist[1]);
    6283              :                       break;
    6284              :                     }
    6285          803 :                   if (omp_privatize_by_reference (var))
    6286              :                     {
    6287          105 :                       gcc_assert (TREE_CODE (new_var) == MEM_REF);
    6288          105 :                       tree new_vard = TREE_OPERAND (new_var, 0);
    6289          105 :                       gcc_assert (DECL_P (new_vard));
    6290          105 :                       tree type = TREE_TYPE (TREE_TYPE (new_vard));
    6291          105 :                       nx = TYPE_SIZE_UNIT (type);
    6292          105 :                       if (TREE_CONSTANT (nx))
    6293              :                         {
    6294           57 :                           nx = create_tmp_var_raw (type, get_name (var));
    6295           57 :                           gimple_add_tmp_var (nx);
    6296           57 :                           TREE_ADDRESSABLE (nx) = 1;
    6297           57 :                           nx = build_fold_addr_expr_loc (clause_loc, nx);
    6298           57 :                           nx = fold_convert_loc (clause_loc,
    6299           57 :                                                  TREE_TYPE (new_vard), nx);
    6300           57 :                           gimplify_assign (new_vard, nx, ilist);
    6301              :                         }
    6302              :                     }
    6303              :                 }
    6304        29032 :               x = lang_hooks.decls.omp_clause_copy_ctor
    6305        29032 :                                                 (c, unshare_expr (new_var), x);
    6306        29028 :               gimplify_and_add (x, ilist);
    6307        29028 :               goto do_dtor;
    6308              : 
    6309        19352 :             case OMP_CLAUSE__LOOPTEMP_:
    6310        19352 :             case OMP_CLAUSE__REDUCTEMP_:
    6311        19352 :               gcc_assert (is_taskreg_ctx (ctx));
    6312        19352 :               x = build_outer_var_ref (var, ctx);
    6313        19352 :               x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
    6314        19352 :               gimplify_and_add (x, ilist);
    6315        19352 :               break;
    6316              : 
    6317          510 :             case OMP_CLAUSE_COPYIN:
    6318          510 :               by_ref = use_pointer_for_field (var, NULL);
    6319          510 :               x = build_receiver_ref (var, by_ref, ctx);
    6320          510 :               x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
    6321          510 :               append_to_statement_list (x, &copyin_seq);
    6322          510 :               copyin_by_ref |= by_ref;
    6323          510 :               break;
    6324              : 
    6325        13023 :             case OMP_CLAUSE_REDUCTION:
    6326        13023 :             case OMP_CLAUSE_IN_REDUCTION:
    6327              :               /* OpenACC reductions are initialized using the
    6328              :                  GOACC_REDUCTION internal function.  */
    6329        13023 :               if (is_gimple_omp_oacc (ctx->stmt))
    6330              :                 break;
    6331         9041 :               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    6332              :                 {
    6333         1444 :                   tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
    6334         1444 :                   gimple *tseq;
    6335         1444 :                   tree ptype = TREE_TYPE (placeholder);
    6336         1444 :                   if (cond)
    6337              :                     {
    6338          295 :                       x = error_mark_node;
    6339          295 :                       if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c)
    6340          295 :                           && !task_reduction_needs_orig_p)
    6341           28 :                         x = var;
    6342          267 :                       else if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
    6343              :                         {
    6344           45 :                           tree pptype = build_pointer_type (ptype);
    6345           45 :                           if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
    6346           35 :                             x = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
    6347           35 :                                         size_int (task_reduction_cnt_full
    6348              :                                                   + task_reduction_cntorig - 1),
    6349              :                                         NULL_TREE, NULL_TREE);
    6350              :                           else
    6351              :                             {
    6352           10 :                               unsigned int idx
    6353           10 :                                 = *ctx->task_reduction_map->get (c);
    6354           10 :                               x = task_reduction_read (ilist, tskred_temp,
    6355           10 :                                                        pptype, 7 + 3 * idx);
    6356              :                             }
    6357           45 :                           x = fold_convert (pptype, x);
    6358           45 :                           x = build_simple_mem_ref (x);
    6359              :                         }
    6360              :                     }
    6361              :                   else
    6362              :                     {
    6363         1149 :                       lower_private_allocate (var, new_var, allocator,
    6364              :                                               allocate_ptr, ilist, ctx, false,
    6365              :                                               NULL_TREE);
    6366         1149 :                       x = build_outer_var_ref (var, ctx);
    6367              : 
    6368         1149 :                       if (omp_privatize_by_reference (var)
    6369         1149 :                           && !useless_type_conversion_p (ptype, TREE_TYPE (x)))
    6370           49 :                         x = build_fold_addr_expr_loc (clause_loc, x);
    6371              :                     }
    6372         1444 :                   SET_DECL_VALUE_EXPR (placeholder, x);
    6373         1444 :                   DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
    6374         1444 :                   tree new_vard = new_var;
    6375         1444 :                   if (omp_privatize_by_reference (var))
    6376              :                     {
    6377          203 :                       gcc_assert (TREE_CODE (new_var) == MEM_REF);
    6378          203 :                       new_vard = TREE_OPERAND (new_var, 0);
    6379          203 :                       gcc_assert (DECL_P (new_vard));
    6380              :                     }
    6381         1444 :                   tree rvar = NULL_TREE, *rvarp = NULL, rvar2 = NULL_TREE;
    6382         1444 :                   if (is_simd
    6383          311 :                       && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    6384         1755 :                       && OMP_CLAUSE_REDUCTION_INSCAN (c))
    6385              :                     rvarp = &rvar;
    6386         1444 :                   if (is_simd
    6387         1444 :                       && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
    6388              :                                                        ivar, lvar, rvarp,
    6389              :                                                        &rvar2))
    6390              :                     {
    6391          174 :                       if (new_vard == new_var)
    6392              :                         {
    6393          128 :                           gcc_assert (DECL_VALUE_EXPR (new_var) == lvar);
    6394          128 :                           SET_DECL_VALUE_EXPR (new_var, ivar);
    6395              :                         }
    6396              :                       else
    6397              :                         {
    6398           46 :                           SET_DECL_VALUE_EXPR (new_vard,
    6399              :                                                build_fold_addr_expr (ivar));
    6400           46 :                           DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
    6401              :                         }
    6402          174 :                       x = lang_hooks.decls.omp_clause_default_ctor
    6403          174 :                                 (c, unshare_expr (ivar),
    6404              :                                  build_outer_var_ref (var, ctx));
    6405          174 :                       if (rvarp && ctx->for_simd_scan_phase)
    6406              :                         {
    6407           16 :                           if (x)
    6408            8 :                             gimplify_and_add (x, &llist[0]);
    6409           16 :                           x = lang_hooks.decls.omp_clause_dtor (c, ivar);
    6410           16 :                           if (x)
    6411            8 :                             gimplify_and_add (x, &llist[1]);
    6412          469 :                           break;
    6413              :                         }
    6414           78 :                       else if (rvarp)
    6415              :                         {
    6416           78 :                           if (x)
    6417              :                             {
    6418           38 :                               gimplify_and_add (x, &llist[0]);
    6419              : 
    6420           38 :                               tree ivar2 = unshare_expr (lvar);
    6421           38 :                               TREE_OPERAND (ivar2, 1) = sctx.idx;
    6422           38 :                               x = lang_hooks.decls.omp_clause_default_ctor
    6423           38 :                                     (c, ivar2, build_outer_var_ref (var, ctx));
    6424           38 :                               gimplify_and_add (x, &llist[0]);
    6425              : 
    6426           38 :                               if (rvar2)
    6427              :                                 {
    6428           16 :                                   x = lang_hooks.decls.omp_clause_default_ctor
    6429           16 :                                         (c, unshare_expr (rvar2),
    6430              :                                          build_outer_var_ref (var, ctx));
    6431           16 :                                   gimplify_and_add (x, &llist[0]);
    6432              :                                 }
    6433              : 
    6434              :                               /* For types that need construction, add another
    6435              :                                  private var which will be default constructed
    6436              :                                  and optionally initialized with
    6437              :                                  OMP_CLAUSE_REDUCTION_GIMPLE_INIT, as in the
    6438              :                                  loop we want to assign this value instead of
    6439              :                                  constructing and destructing it in each
    6440              :                                  iteration.  */
    6441           38 :                               tree nv = create_tmp_var_raw (TREE_TYPE (ivar));
    6442           38 :                               gimple_add_tmp_var (nv);
    6443           60 :                               ctx->cb.decl_map->put (TREE_OPERAND (rvar2
    6444              :                                                                    ? rvar2
    6445              :                                                                    : ivar, 0),
    6446              :                                                      nv);
    6447           38 :                               x = lang_hooks.decls.omp_clause_default_ctor
    6448           38 :                                     (c, nv, build_outer_var_ref (var, ctx));
    6449           38 :                               gimplify_and_add (x, ilist);
    6450              : 
    6451           38 :                               if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
    6452              :                                 {
    6453           19 :                                   tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
    6454           19 :                                   x = DECL_VALUE_EXPR (new_vard);
    6455           19 :                                   tree vexpr = nv;
    6456           19 :                                   if (new_vard != new_var)
    6457           11 :                                     vexpr = build_fold_addr_expr (nv);
    6458           19 :                                   SET_DECL_VALUE_EXPR (new_vard, vexpr);
    6459           19 :                                   lower_omp (&tseq, ctx);
    6460           19 :                                   SET_DECL_VALUE_EXPR (new_vard, x);
    6461           19 :                                   gimple_seq_add_seq (ilist, tseq);
    6462           19 :                                   OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
    6463              :                                 }
    6464              : 
    6465           38 :                               x = lang_hooks.decls.omp_clause_dtor (c, nv);
    6466           38 :                               if (x)
    6467           38 :                                 gimplify_and_add (x, dlist);
    6468              :                             }
    6469              : 
    6470           78 :                           tree ref = build_outer_var_ref (var, ctx);
    6471           78 :                           x = unshare_expr (ivar);
    6472           78 :                           x = lang_hooks.decls.omp_clause_assign_op (c, x,
    6473              :                                                                      ref);
    6474           78 :                           gimplify_and_add (x, &llist[0]);
    6475              : 
    6476           78 :                           ref = build_outer_var_ref (var, ctx);
    6477           78 :                           x = lang_hooks.decls.omp_clause_assign_op (c, ref,
    6478              :                                                                      rvar);
    6479           78 :                           gimplify_and_add (x, &llist[3]);
    6480              : 
    6481           78 :                           DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
    6482           78 :                           if (new_vard == new_var)
    6483           48 :                             SET_DECL_VALUE_EXPR (new_var, lvar);
    6484              :                           else
    6485           30 :                             SET_DECL_VALUE_EXPR (new_vard,
    6486              :                                                  build_fold_addr_expr (lvar));
    6487              : 
    6488           78 :                           x = lang_hooks.decls.omp_clause_dtor (c, ivar);
    6489           78 :                           if (x)
    6490           38 :                             gimplify_and_add (x, &llist[1]);
    6491              : 
    6492           78 :                           tree ivar2 = unshare_expr (lvar);
    6493           78 :                           TREE_OPERAND (ivar2, 1) = sctx.idx;
    6494           78 :                           x = lang_hooks.decls.omp_clause_dtor (c, ivar2);
    6495           78 :                           if (x)
    6496           38 :                             gimplify_and_add (x, &llist[1]);
    6497              : 
    6498           78 :                           if (rvar2)
    6499              :                             {
    6500           36 :                               x = lang_hooks.decls.omp_clause_dtor (c, rvar2);
    6501           36 :                               if (x)
    6502           16 :                                 gimplify_and_add (x, &llist[1]);
    6503              :                             }
    6504              :                           break;
    6505              :                         }
    6506           80 :                       if (x)
    6507           34 :                         gimplify_and_add (x, &llist[0]);
    6508           80 :                       if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
    6509              :                         {
    6510           76 :                           tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
    6511           76 :                           lower_omp (&tseq, ctx);
    6512           76 :                           gimple_seq_add_seq (&llist[0], tseq);
    6513              :                         }
    6514           80 :                       OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
    6515           80 :                       tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
    6516           80 :                       lower_omp (&tseq, ctx);
    6517           80 :                       gimple_seq_add_seq (&llist[1], tseq);
    6518           80 :                       OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    6519           80 :                       DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
    6520           80 :                       if (new_vard == new_var)
    6521           70 :                         SET_DECL_VALUE_EXPR (new_var, lvar);
    6522              :                       else
    6523           10 :                         SET_DECL_VALUE_EXPR (new_vard,
    6524              :                                              build_fold_addr_expr (lvar));
    6525           80 :                       x = lang_hooks.decls.omp_clause_dtor (c, ivar);
    6526           80 :                       if (x)
    6527           38 :                         gimplify_and_add (x, &llist[1]);
    6528              :                       break;
    6529              :                     }
    6530              :                   /* If this is a reference to constant size reduction var
    6531              :                      with placeholder, we haven't emitted the initializer
    6532              :                      for it because it is undesirable if SIMD arrays are used.
    6533              :                      But if they aren't used, we need to emit the deferred
    6534              :                      initialization now.  */
    6535         1270 :                   else if (omp_privatize_by_reference (var) && is_simd)
    6536           46 :                     handle_simd_reference (clause_loc, new_vard, ilist);
    6537              : 
    6538         1270 :                   tree lab2 = NULL_TREE;
    6539         1270 :                   if (cond)
    6540              :                     {
    6541          295 :                       gimple *g;
    6542          295 :                       if (!is_parallel_ctx (ctx))
    6543              :                         {
    6544          278 :                           tree condv = create_tmp_var (boolean_type_node);
    6545          278 :                           tree m = build_simple_mem_ref (cond);
    6546          278 :                           g = gimple_build_assign (condv, m);
    6547          278 :                           gimple_seq_add_stmt (ilist, g);
    6548          278 :                           tree lab1
    6549          278 :                             = create_artificial_label (UNKNOWN_LOCATION);
    6550          278 :                           lab2 = create_artificial_label (UNKNOWN_LOCATION);
    6551          278 :                           g = gimple_build_cond (NE_EXPR, condv,
    6552              :                                                  boolean_false_node,
    6553              :                                                  lab2, lab1);
    6554          278 :                           gimple_seq_add_stmt (ilist, g);
    6555          278 :                           gimple_seq_add_stmt (ilist,
    6556          278 :                                                gimple_build_label (lab1));
    6557              :                         }
    6558          295 :                       g = gimple_build_assign (build_simple_mem_ref (cond),
    6559              :                                                boolean_true_node);
    6560          295 :                       gimple_seq_add_stmt (ilist, g);
    6561              :                     }
    6562          295 :                   x = lang_hooks.decls.omp_clause_default_ctor
    6563         1270 :                                 (c, unshare_expr (new_var),
    6564              :                                  cond ? NULL_TREE
    6565          975 :                                  : build_outer_var_ref (var, ctx));
    6566         1270 :                   if (x)
    6567          286 :                     gimplify_and_add (x, ilist);
    6568              : 
    6569         1270 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    6570         1270 :                       && OMP_CLAUSE_REDUCTION_INSCAN (c))
    6571              :                     {
    6572          158 :                       if (ctx->for_simd_scan_phase)
    6573          975 :                         goto do_dtor;
    6574          142 :                       if (x || (!is_simd
    6575           32 :                                 && OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c)))
    6576              :                         {
    6577           70 :                           tree nv = create_tmp_var_raw (TREE_TYPE (new_var));
    6578           70 :                           gimple_add_tmp_var (nv);
    6579           70 :                           ctx->cb.decl_map->put (new_vard, nv);
    6580           70 :                           x = lang_hooks.decls.omp_clause_default_ctor
    6581           70 :                                 (c, nv, build_outer_var_ref (var, ctx));
    6582           70 :                           if (x)
    6583           70 :                             gimplify_and_add (x, ilist);
    6584           70 :                           if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
    6585              :                             {
    6586           35 :                               tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
    6587           35 :                               tree vexpr = nv;
    6588           35 :                               if (new_vard != new_var)
    6589           19 :                                 vexpr = build_fold_addr_expr (nv);
    6590           35 :                               SET_DECL_VALUE_EXPR (new_vard, vexpr);
    6591           35 :                               DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
    6592           35 :                               lower_omp (&tseq, ctx);
    6593           35 :                               SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
    6594           35 :                               DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
    6595           35 :                               gimple_seq_add_seq (ilist, tseq);
    6596              :                             }
    6597           70 :                           OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
    6598           70 :                           if (is_simd && ctx->scan_exclusive)
    6599              :                             {
    6600           16 :                               tree nv2
    6601           16 :                                 = create_tmp_var_raw (TREE_TYPE (new_var));
    6602           16 :                               gimple_add_tmp_var (nv2);
    6603           16 :                               ctx->cb.decl_map->put (nv, nv2);
    6604           16 :                               x = lang_hooks.decls.omp_clause_default_ctor
    6605           16 :                                     (c, nv2, build_outer_var_ref (var, ctx));
    6606           16 :                               gimplify_and_add (x, ilist);
    6607           16 :                               x = lang_hooks.decls.omp_clause_dtor (c, nv2);
    6608           16 :                               if (x)
    6609           16 :                                 gimplify_and_add (x, dlist);
    6610              :                             }
    6611           70 :                           x = lang_hooks.decls.omp_clause_dtor (c, nv);
    6612           70 :                           if (x)
    6613           70 :                             gimplify_and_add (x, dlist);
    6614              :                         }
    6615           72 :                       else if (is_simd
    6616           40 :                                && ctx->scan_exclusive
    6617           92 :                                && TREE_ADDRESSABLE (TREE_TYPE (new_var)))
    6618              :                         {
    6619            0 :                           tree nv2 = create_tmp_var_raw (TREE_TYPE (new_var));
    6620            0 :                           gimple_add_tmp_var (nv2);
    6621            0 :                           ctx->cb.decl_map->put (new_vard, nv2);
    6622            0 :                           x = lang_hooks.decls.omp_clause_dtor (c, nv2);
    6623            0 :                           if (x)
    6624            0 :                             gimplify_and_add (x, dlist);
    6625              :                         }
    6626          142 :                       DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
    6627          142 :                       goto do_dtor;
    6628              :                     }
    6629              : 
    6630         1112 :                   if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
    6631              :                     {
    6632         1064 :                       tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
    6633         1064 :                       if (c_kind == OMP_CLAUSE_IN_REDUCTION
    6634         1064 :                           && is_omp_target (ctx->stmt))
    6635              :                         {
    6636           12 :                           tree d = maybe_lookup_decl_in_outer_ctx (var, ctx);
    6637           12 :                           tree oldv = NULL_TREE;
    6638           12 :                           gcc_assert (d);
    6639           12 :                           if (DECL_HAS_VALUE_EXPR_P (d))
    6640            6 :                             oldv = DECL_VALUE_EXPR (d);
    6641           12 :                           SET_DECL_VALUE_EXPR (d, new_vard);
    6642           12 :                           DECL_HAS_VALUE_EXPR_P (d) = 1;
    6643           12 :                           lower_omp (&tseq, ctx);
    6644           12 :                           if (oldv)
    6645            6 :                             SET_DECL_VALUE_EXPR (d, oldv);
    6646              :                           else
    6647              :                             {
    6648            6 :                               SET_DECL_VALUE_EXPR (d, NULL_TREE);
    6649            6 :                               DECL_HAS_VALUE_EXPR_P (d) = 0;
    6650              :                             }
    6651              :                         }
    6652              :                       else
    6653         1052 :                         lower_omp (&tseq, ctx);
    6654         1064 :                       gimple_seq_add_seq (ilist, tseq);
    6655              :                     }
    6656         1112 :                   OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
    6657         1112 :                   if (is_simd)
    6658              :                     {
    6659           43 :                       tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
    6660           43 :                       lower_omp (&tseq, ctx);
    6661           43 :                       gimple_seq_add_seq (dlist, tseq);
    6662           43 :                       OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    6663              :                     }
    6664         1112 :                   DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
    6665         1112 :                   if (cond)
    6666              :                     {
    6667          295 :                       if (lab2)
    6668          278 :                         gimple_seq_add_stmt (ilist, gimple_build_label (lab2));
    6669              :                       break;
    6670              :                     }
    6671          817 :                   goto do_dtor;
    6672              :                 }
    6673              :               else
    6674              :                 {
    6675         7597 :                   x = omp_reduction_init (c, TREE_TYPE (new_var));
    6676         7597 :                   gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
    6677         7597 :                   enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
    6678              : 
    6679         7597 :                   if (cond)
    6680              :                     {
    6681         1439 :                       gimple *g;
    6682         1439 :                       tree lab2 = NULL_TREE;
    6683              :                       /* GOMP_taskgroup_reduction_register memsets the whole
    6684              :                          array to zero.  If the initializer is zero, we don't
    6685              :                          need to initialize it again, just mark it as ever
    6686              :                          used unconditionally, i.e. cond = true.  */
    6687         1439 :                       if (initializer_zerop (x))
    6688              :                         {
    6689         1258 :                           g = gimple_build_assign (build_simple_mem_ref (cond),
    6690              :                                                    boolean_true_node);
    6691         1258 :                           gimple_seq_add_stmt (ilist, g);
    6692         3223 :                           break;
    6693              :                         }
    6694              : 
    6695              :                       /* Otherwise, emit
    6696              :                          if (!cond) { cond = true; new_var = x; }  */
    6697          181 :                       if (!is_parallel_ctx (ctx))
    6698              :                         {
    6699          177 :                           tree condv = create_tmp_var (boolean_type_node);
    6700          177 :                           tree m = build_simple_mem_ref (cond);
    6701          177 :                           g = gimple_build_assign (condv, m);
    6702          177 :                           gimple_seq_add_stmt (ilist, g);
    6703          177 :                           tree lab1
    6704          177 :                             = create_artificial_label (UNKNOWN_LOCATION);
    6705          177 :                           lab2 = create_artificial_label (UNKNOWN_LOCATION);
    6706          177 :                           g = gimple_build_cond (NE_EXPR, condv,
    6707              :                                                  boolean_false_node,
    6708              :                                                  lab2, lab1);
    6709          177 :                           gimple_seq_add_stmt (ilist, g);
    6710          177 :                           gimple_seq_add_stmt (ilist,
    6711          177 :                                                gimple_build_label (lab1));
    6712              :                         }
    6713          181 :                       g = gimple_build_assign (build_simple_mem_ref (cond),
    6714              :                                                boolean_true_node);
    6715          181 :                       gimple_seq_add_stmt (ilist, g);
    6716          181 :                       gimplify_assign (new_var, x, ilist);
    6717          181 :                       if (lab2)
    6718          177 :                         gimple_seq_add_stmt (ilist, gimple_build_label (lab2));
    6719              :                       break;
    6720              :                     }
    6721              : 
    6722              :                   /* reduction(-:var) sums up the partial results, so it
    6723              :                      acts identically to reduction(+:var).  */
    6724         6158 :                   if (code == MINUS_EXPR)
    6725           33 :                     code = PLUS_EXPR;
    6726              : 
    6727         6158 :                   bool is_truth_op
    6728         6158 :                     = (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR);
    6729         6158 :                   tree new_vard = new_var;
    6730         6158 :                   if (is_simd && omp_privatize_by_reference (var))
    6731              :                     {
    6732           52 :                       gcc_assert (TREE_CODE (new_var) == MEM_REF);
    6733           52 :                       new_vard = TREE_OPERAND (new_var, 0);
    6734           52 :                       gcc_assert (DECL_P (new_vard));
    6735              :                     }
    6736         6158 :                   tree rvar = NULL_TREE, *rvarp = NULL, rvar2 = NULL_TREE;
    6737         6158 :                   if (is_simd
    6738         2087 :                       && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    6739         8245 :                       && OMP_CLAUSE_REDUCTION_INSCAN (c))
    6740              :                     rvarp = &rvar;
    6741         6158 :                   if (is_simd
    6742         6158 :                       && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
    6743              :                                                        ivar, lvar, rvarp,
    6744              :                                                        &rvar2))
    6745              :                     {
    6746          867 :                       if (new_vard != new_var)
    6747              :                         {
    6748           34 :                           SET_DECL_VALUE_EXPR (new_vard,
    6749              :                                                build_fold_addr_expr (lvar));
    6750           34 :                           DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
    6751              :                         }
    6752              : 
    6753          867 :                       tree ref = build_outer_var_ref (var, ctx);
    6754              : 
    6755          867 :                       if (rvarp)
    6756              :                         {
    6757          193 :                           if (ctx->for_simd_scan_phase)
    6758              :                             break;
    6759          154 :                           gimplify_assign (ivar, ref, &llist[0]);
    6760          154 :                           ref = build_outer_var_ref (var, ctx);
    6761          154 :                           gimplify_assign (ref, rvar, &llist[3]);
    6762          154 :                           break;
    6763              :                         }
    6764              : 
    6765          674 :                       gimplify_assign (unshare_expr (ivar), x, &llist[0]);
    6766              : 
    6767          674 :                       if (sctx.is_simt)
    6768              :                         {
    6769            0 :                           if (!simt_lane)
    6770            0 :                             simt_lane = create_tmp_var (unsigned_type_node);
    6771            0 :                           x = build_call_expr_internal_loc
    6772            0 :                             (UNKNOWN_LOCATION, IFN_GOMP_SIMT_XCHG_BFLY,
    6773            0 :                              TREE_TYPE (ivar), 2, ivar, simt_lane);
    6774              :                           /* Make sure x is evaluated unconditionally.  */
    6775            0 :                           tree bfly_var = create_tmp_var (TREE_TYPE (ivar));
    6776            0 :                           gimplify_assign (bfly_var, x, &llist[2]);
    6777            0 :                           x = build2 (code, TREE_TYPE (ivar), ivar, bfly_var);
    6778            0 :                           gimplify_assign (ivar, x, &llist[2]);
    6779              :                         }
    6780          674 :                       tree ivar2 = ivar;
    6781          674 :                       tree ref2 = ref;
    6782          674 :                       if (is_truth_op)
    6783              :                         {
    6784           99 :                           tree zero = build_zero_cst (TREE_TYPE (ivar));
    6785           99 :                           ivar2 = fold_build2_loc (clause_loc, NE_EXPR,
    6786              :                                                    boolean_type_node, ivar,
    6787              :                                                    zero);
    6788           99 :                           ref2 = fold_build2_loc (clause_loc, NE_EXPR,
    6789              :                                                   boolean_type_node, ref,
    6790              :                                                   zero);
    6791              :                         }
    6792          674 :                       x = build2 (code, TREE_TYPE (ref), ref2, ivar2);
    6793          674 :                       if (is_truth_op)
    6794           99 :                         x = fold_convert (TREE_TYPE (ref), x);
    6795          674 :                       ref = build_outer_var_ref (var, ctx);
    6796          674 :                       gimplify_assign (ref, x, &llist[1]);
    6797              : 
    6798              :                     }
    6799              :                   else
    6800              :                     {
    6801         5291 :                       lower_private_allocate (var, new_var, allocator,
    6802              :                                               allocate_ptr, ilist, ctx,
    6803              :                                               false, NULL_TREE);
    6804         5291 :                       if (omp_privatize_by_reference (var) && is_simd)
    6805           18 :                         handle_simd_reference (clause_loc, new_vard, ilist);
    6806         5291 :                       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    6807         5291 :                           && OMP_CLAUSE_REDUCTION_INSCAN (c))
    6808              :                         break;
    6809         4958 :                       gimplify_assign (new_var, x, ilist);
    6810         4958 :                       if (is_simd)
    6811              :                         {
    6812         1028 :                           tree ref = build_outer_var_ref (var, ctx);
    6813         1028 :                           tree new_var2 = new_var;
    6814         1028 :                           tree ref2 = ref;
    6815         1028 :                           if (is_truth_op)
    6816              :                             {
    6817           24 :                               tree zero = build_zero_cst (TREE_TYPE (new_var));
    6818           24 :                               new_var2
    6819           24 :                                 = fold_build2_loc (clause_loc, NE_EXPR,
    6820              :                                                    boolean_type_node, new_var,
    6821              :                                                    zero);
    6822           24 :                               ref2 = fold_build2_loc (clause_loc, NE_EXPR,
    6823              :                                                       boolean_type_node, ref,
    6824              :                                                       zero);
    6825              :                             }
    6826         1028 :                           x = build2 (code, TREE_TYPE (ref2), ref2, new_var2);
    6827         1028 :                           if (is_truth_op)
    6828           24 :                             x = fold_convert (TREE_TYPE (new_var), x);
    6829         1028 :                           ref = build_outer_var_ref (var, ctx);
    6830         1028 :                           gimplify_assign (ref, x, dlist);
    6831              :                         }
    6832         4958 :                       if (allocator)
    6833           61 :                         goto do_dtor;
    6834              :                     }
    6835              :                 }
    6836         5571 :               break;
    6837              : 
    6838            0 :             default:
    6839            0 :               gcc_unreachable ();
    6840              :             }
    6841              :         }
    6842              :     }
    6843        77122 :   if (tskred_avar)
    6844              :     {
    6845          871 :       tree clobber = build_clobber (TREE_TYPE (tskred_avar));
    6846          871 :       gimple_seq_add_stmt (ilist, gimple_build_assign (tskred_avar, clobber));
    6847              :     }
    6848              : 
    6849        77122 :   if (known_eq (sctx.max_vf, 1U))
    6850              :     {
    6851         1772 :       sctx.is_simt = false;
    6852         1772 :       if (ctx->lastprivate_conditional_map)
    6853              :         {
    6854           52 :           if (gimple_omp_for_combined_into_p (ctx->stmt))
    6855              :             {
    6856              :               /* Signal to lower_omp_1 that it should use parent context.  */
    6857           43 :               ctx->combined_into_simd_safelen1 = true;
    6858          370 :               for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    6859          327 :                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    6860          327 :                     && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
    6861              :                   {
    6862           57 :                     tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
    6863           57 :                     omp_context *outer = ctx->outer;
    6864           57 :                     if (gimple_code (outer->stmt) == GIMPLE_OMP_SCAN)
    6865            6 :                       outer = outer->outer;
    6866           57 :                     tree *v = ctx->lastprivate_conditional_map->get (o);
    6867           57 :                     tree po = lookup_decl (OMP_CLAUSE_DECL (c), outer);
    6868           57 :                     tree *pv = outer->lastprivate_conditional_map->get (po);
    6869           57 :                     *v = *pv;
    6870              :                   }
    6871              :             }
    6872              :           else
    6873              :             {
    6874              :               /* When not vectorized, treat lastprivate(conditional:) like
    6875              :                  normal lastprivate, as there will be just one simd lane
    6876              :                  writing the privatized variable.  */
    6877            9 :               delete ctx->lastprivate_conditional_map;
    6878            9 :               ctx->lastprivate_conditional_map = NULL;
    6879              :             }
    6880              :         }
    6881              :     }
    6882              : 
    6883        77122 :   if (nonconst_simd_if)
    6884              :     {
    6885          625 :       if (sctx.lane == NULL_TREE)
    6886              :         {
    6887          570 :           sctx.idx = create_tmp_var (unsigned_type_node);
    6888          570 :           sctx.lane = create_tmp_var (unsigned_type_node);
    6889              :         }
    6890              :       /* FIXME: For now.  */
    6891          625 :       sctx.is_simt = false;
    6892              :     }
    6893              : 
    6894        77122 :   if (sctx.lane || sctx.is_simt)
    6895              :     {
    6896         4010 :       uid = create_tmp_var (ptr_type_node, "simduid");
    6897              :       /* Don't want uninit warnings on simduid, it is always uninitialized,
    6898              :          but we use it not for the value, but for the DECL_UID only.  */
    6899         4010 :       suppress_warning (uid, OPT_Wuninitialized);
    6900         4010 :       c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_);
    6901         4010 :       OMP_CLAUSE__SIMDUID__DECL (c) = uid;
    6902         4010 :       OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
    6903         4010 :       gimple_omp_for_set_clauses (ctx->stmt, c);
    6904              :     }
    6905              :   /* Emit calls denoting privatized variables and initializing a pointer to
    6906              :      structure that holds private variables as fields after ompdevlow pass.  */
    6907        77122 :   if (sctx.is_simt)
    6908              :     {
    6909            0 :       sctx.simt_eargs[0] = uid;
    6910            0 :       gimple *g
    6911            0 :         = gimple_build_call_internal_vec (IFN_GOMP_SIMT_ENTER, sctx.simt_eargs);
    6912            0 :       gimple_call_set_lhs (g, uid);
    6913            0 :       gimple_seq_add_stmt (ilist, g);
    6914            0 :       sctx.simt_eargs.release ();
    6915              : 
    6916            0 :       simtrec = create_tmp_var (ptr_type_node, ".omp_simt");
    6917            0 :       g = gimple_build_call_internal (IFN_GOMP_SIMT_ENTER_ALLOC, 1, uid);
    6918            0 :       gimple_call_set_lhs (g, simtrec);
    6919            0 :       gimple_seq_add_stmt (ilist, g);
    6920              :     }
    6921        77122 :   if (sctx.lane)
    6922              :     {
    6923         7395 :       gimple *g = gimple_build_call_internal (IFN_GOMP_SIMD_LANE,
    6924              :                                               2 + (nonconst_simd_if != NULL),
    6925              :                                               uid, integer_zero_node,
    6926              :                                               nonconst_simd_if);
    6927         4010 :       gimple_call_set_lhs (g, sctx.lane);
    6928         4010 :       gimple_stmt_iterator gsi = gsi_start (*gimple_omp_body_ptr (ctx->stmt));
    6929         4010 :       gsi_insert_before_without_update (&gsi, g, GSI_SAME_STMT);
    6930         4010 :       g = gimple_build_assign (sctx.lane, INTEGER_CST,
    6931              :                                build_int_cst (unsigned_type_node, 0));
    6932         4010 :       gimple_seq_add_stmt (ilist, g);
    6933         4010 :       if (sctx.lastlane)
    6934              :         {
    6935          184 :           g = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE,
    6936              :                                           2, uid, sctx.lane);
    6937          184 :           gimple_call_set_lhs (g, sctx.lastlane);
    6938          184 :           gimple_seq_add_stmt (dlist, g);
    6939          184 :           gimple_seq_add_seq (dlist, llist[3]);
    6940              :         }
    6941              :       /* Emit reductions across SIMT lanes in log_2(simt_vf) steps.  */
    6942         4010 :       if (llist[2])
    6943              :         {
    6944            0 :           tree simt_vf = create_tmp_var (unsigned_type_node);
    6945            0 :           g = gimple_build_call_internal (IFN_GOMP_SIMT_VF, 0);
    6946            0 :           gimple_call_set_lhs (g, simt_vf);
    6947            0 :           gimple_seq_add_stmt (dlist, g);
    6948              : 
    6949            0 :           tree t = build_int_cst (unsigned_type_node, 1);
    6950            0 :           g = gimple_build_assign (simt_lane, INTEGER_CST, t);
    6951            0 :           gimple_seq_add_stmt (dlist, g);
    6952              : 
    6953            0 :           t = build_int_cst (unsigned_type_node, 0);
    6954            0 :           g = gimple_build_assign (sctx.idx, INTEGER_CST, t);
    6955            0 :           gimple_seq_add_stmt (dlist, g);
    6956              : 
    6957            0 :           tree body = create_artificial_label (UNKNOWN_LOCATION);
    6958            0 :           tree header = create_artificial_label (UNKNOWN_LOCATION);
    6959            0 :           tree end = create_artificial_label (UNKNOWN_LOCATION);
    6960            0 :           gimple_seq_add_stmt (dlist, gimple_build_goto (header));
    6961            0 :           gimple_seq_add_stmt (dlist, gimple_build_label (body));
    6962              : 
    6963            0 :           gimple_seq_add_seq (dlist, llist[2]);
    6964              : 
    6965            0 :           g = gimple_build_assign (simt_lane, LSHIFT_EXPR, simt_lane, integer_one_node);
    6966            0 :           gimple_seq_add_stmt (dlist, g);
    6967              : 
    6968            0 :           gimple_seq_add_stmt (dlist, gimple_build_label (header));
    6969            0 :           g = gimple_build_cond (LT_EXPR, simt_lane, simt_vf, body, end);
    6970            0 :           gimple_seq_add_stmt (dlist, g);
    6971              : 
    6972            0 :           gimple_seq_add_stmt (dlist, gimple_build_label (end));
    6973              :         }
    6974        12030 :       for (int i = 0; i < 2; i++)
    6975         8020 :         if (llist[i])
    6976              :           {
    6977         1716 :             tree vf = create_tmp_var (unsigned_type_node);
    6978         1716 :             g = gimple_build_call_internal (IFN_GOMP_SIMD_VF, 1, uid);
    6979         1716 :             gimple_call_set_lhs (g, vf);
    6980         1716 :             gimple_seq *seq = i == 0 ? ilist : dlist;
    6981         1716 :             gimple_seq_add_stmt (seq, g);
    6982         1716 :             tree t = build_int_cst (unsigned_type_node, 0);
    6983         1716 :             g = gimple_build_assign (sctx.idx, INTEGER_CST, t);
    6984         1716 :             gimple_seq_add_stmt (seq, g);
    6985         1716 :             tree body = create_artificial_label (UNKNOWN_LOCATION);
    6986         1716 :             tree header = create_artificial_label (UNKNOWN_LOCATION);
    6987         1716 :             tree end = create_artificial_label (UNKNOWN_LOCATION);
    6988         1716 :             gimple_seq_add_stmt (seq, gimple_build_goto (header));
    6989         1716 :             gimple_seq_add_stmt (seq, gimple_build_label (body));
    6990         1716 :             gimple_seq_add_seq (seq, llist[i]);
    6991         1716 :             t = build_int_cst (unsigned_type_node, 1);
    6992         1716 :             g = gimple_build_assign (sctx.idx, PLUS_EXPR, sctx.idx, t);
    6993         1716 :             gimple_seq_add_stmt (seq, g);
    6994         1716 :             gimple_seq_add_stmt (seq, gimple_build_label (header));
    6995         1716 :             g = gimple_build_cond (LT_EXPR, sctx.idx, vf, body, end);
    6996         1716 :             gimple_seq_add_stmt (seq, g);
    6997         1716 :             gimple_seq_add_stmt (seq, gimple_build_label (end));
    6998              :           }
    6999              :     }
    7000        77122 :   if (sctx.is_simt)
    7001              :     {
    7002            0 :       gimple_seq_add_seq (dlist, sctx.simt_dlist);
    7003            0 :       gimple *g
    7004            0 :         = gimple_build_call_internal (IFN_GOMP_SIMT_EXIT, 1, simtrec);
    7005            0 :       gimple_seq_add_stmt (dlist, g);
    7006              :     }
    7007              : 
    7008              :   /* The copyin sequence is not to be executed by the main thread, since
    7009              :      that would result in self-copies.  Perhaps not visible to scalars,
    7010              :      but it certainly is to C++ operator=.  */
    7011        77122 :   if (copyin_seq)
    7012              :     {
    7013          436 :       x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
    7014              :                            0);
    7015          436 :       x = build2 (NE_EXPR, boolean_type_node, x,
    7016          436 :                   build_int_cst (TREE_TYPE (x), 0));
    7017          436 :       x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
    7018          436 :       gimplify_and_add (x, ilist);
    7019              :     }
    7020              : 
    7021              :   /* If any copyin variable is passed by reference, we must ensure the
    7022              :      master thread doesn't modify it before it is copied over in all
    7023              :      threads.  Similarly for variables in both firstprivate and
    7024              :      lastprivate clauses we need to ensure the lastprivate copying
    7025              :      happens after firstprivate copying in all threads.  And similarly
    7026              :      for UDRs if initializer expression refers to omp_orig.  */
    7027        77122 :   if (copyin_by_ref || lastprivate_firstprivate
    7028        75192 :       || (reduction_omp_orig_ref
    7029           89 :           && !ctx->scan_inclusive
    7030           89 :           && !ctx->scan_exclusive))
    7031              :     {
    7032              :       /* Don't add any barrier for #pragma omp simd or
    7033              :          #pragma omp distribute.  */
    7034         2019 :       if (!is_task_ctx (ctx)
    7035         2019 :           && (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
    7036         1485 :               || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR))
    7037          882 :         gimple_seq_add_stmt (ilist, omp_build_barrier (NULL_TREE));
    7038              :     }
    7039              : 
    7040              :   /* If max_vf is non-zero, then we can use only a vectorization factor
    7041              :      up to the max_vf we chose.  So stick it into the safelen clause.  */
    7042        77122 :   if (maybe_ne (sctx.max_vf, 0U))
    7043              :     {
    7044         5212 :       tree c = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    7045              :                                 OMP_CLAUSE_SAFELEN);
    7046         5212 :       poly_uint64 safe_len;
    7047         5212 :       if (c == NULL_TREE
    7048         5212 :           || (poly_int_tree_p (OMP_CLAUSE_SAFELEN_EXPR (c), &safe_len)
    7049          613 :               && maybe_gt (safe_len, sctx.max_vf)))
    7050              :         {
    7051         5122 :           c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
    7052         5122 :           OMP_CLAUSE_SAFELEN_EXPR (c) = build_int_cst (integer_type_node,
    7053         5122 :                                                        sctx.max_vf);
    7054         5122 :           OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
    7055         5122 :           gimple_omp_for_set_clauses (ctx->stmt, c);
    7056              :         }
    7057              :     }
    7058        77122 : }
    7059              : 
    7060              : /* Create temporary variables for lastprivate(conditional:) implementation
    7061              :    in context CTX with CLAUSES.  */
    7062              : 
    7063              : static void
    7064        47266 : lower_lastprivate_conditional_clauses (tree *clauses, omp_context *ctx)
    7065              : {
    7066        47266 :   tree iter_type = NULL_TREE;
    7067        47266 :   tree cond_ptr = NULL_TREE;
    7068        47266 :   tree iter_var = NULL_TREE;
    7069        47266 :   bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    7070        47266 :                   && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD);
    7071        47266 :   tree next = *clauses;
    7072       227048 :   for (tree c = *clauses; c; c = OMP_CLAUSE_CHAIN (c))
    7073       179782 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7074       179782 :         && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
    7075              :       {
    7076          386 :         if (is_simd)
    7077              :           {
    7078          107 :             tree cc = omp_find_clause (next, OMP_CLAUSE__CONDTEMP_);
    7079          107 :             gcc_assert (cc);
    7080          107 :             if (iter_type == NULL_TREE)
    7081              :               {
    7082           77 :                 iter_type = TREE_TYPE (OMP_CLAUSE_DECL (cc));
    7083           77 :                 iter_var = create_tmp_var_raw (iter_type);
    7084           77 :                 DECL_CONTEXT (iter_var) = current_function_decl;
    7085           77 :                 DECL_SEEN_IN_BIND_EXPR_P (iter_var) = 1;
    7086           77 :                 DECL_CHAIN (iter_var) = ctx->block_vars;
    7087           77 :                 ctx->block_vars = iter_var;
    7088           77 :                 tree c3
    7089           77 :                   = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
    7090           77 :                 OMP_CLAUSE__CONDTEMP__ITER (c3) = 1;
    7091           77 :                 OMP_CLAUSE_DECL (c3) = iter_var;
    7092           77 :                 OMP_CLAUSE_CHAIN (c3) = *clauses;
    7093           77 :                 *clauses = c3;
    7094           77 :                 ctx->lastprivate_conditional_map = new hash_map<tree, tree>;
    7095              :               }
    7096          107 :             next = OMP_CLAUSE_CHAIN (cc);
    7097          107 :             tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
    7098          107 :             tree v = lookup_decl (OMP_CLAUSE_DECL (cc), ctx);
    7099          107 :             ctx->lastprivate_conditional_map->put (o, v);
    7100          107 :             continue;
    7101          107 :           }
    7102          279 :         if (iter_type == NULL)
    7103              :           {
    7104          205 :             if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR)
    7105              :               {
    7106          193 :                 struct omp_for_data fd;
    7107          193 :                 omp_extract_for_data (as_a <gomp_for *> (ctx->stmt), &fd,
    7108              :                                       NULL);
    7109          193 :                 iter_type = unsigned_type_for (fd.iter_type);
    7110              :               }
    7111           12 :             else if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
    7112           12 :               iter_type = unsigned_type_node;
    7113          205 :             tree c2 = omp_find_clause (*clauses, OMP_CLAUSE__CONDTEMP_);
    7114          205 :             if (c2)
    7115              :               {
    7116          103 :                 cond_ptr
    7117          103 :                   = lookup_decl_in_outer_ctx (OMP_CLAUSE_DECL (c2), ctx);
    7118          103 :                 OMP_CLAUSE_DECL (c2) = cond_ptr;
    7119              :               }
    7120              :             else
    7121              :               {
    7122          102 :                 cond_ptr = create_tmp_var_raw (build_pointer_type (iter_type));
    7123          102 :                 DECL_CONTEXT (cond_ptr) = current_function_decl;
    7124          102 :                 DECL_SEEN_IN_BIND_EXPR_P (cond_ptr) = 1;
    7125          102 :                 DECL_CHAIN (cond_ptr) = ctx->block_vars;
    7126          102 :                 ctx->block_vars = cond_ptr;
    7127          102 :                 c2 = build_omp_clause (UNKNOWN_LOCATION,
    7128              :                                        OMP_CLAUSE__CONDTEMP_);
    7129          102 :                 OMP_CLAUSE_DECL (c2) = cond_ptr;
    7130          102 :                 OMP_CLAUSE_CHAIN (c2) = *clauses;
    7131          102 :                 *clauses = c2;
    7132              :               }
    7133          205 :             iter_var = create_tmp_var_raw (iter_type);
    7134          205 :             DECL_CONTEXT (iter_var) = current_function_decl;
    7135          205 :             DECL_SEEN_IN_BIND_EXPR_P (iter_var) = 1;
    7136          205 :             DECL_CHAIN (iter_var) = ctx->block_vars;
    7137          205 :             ctx->block_vars = iter_var;
    7138          205 :             tree c3
    7139          205 :               = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
    7140          205 :             OMP_CLAUSE__CONDTEMP__ITER (c3) = 1;
    7141          205 :             OMP_CLAUSE_DECL (c3) = iter_var;
    7142          205 :             OMP_CLAUSE_CHAIN (c3) = OMP_CLAUSE_CHAIN (c2);
    7143          205 :             OMP_CLAUSE_CHAIN (c2) = c3;
    7144          205 :             ctx->lastprivate_conditional_map = new hash_map<tree, tree>;
    7145              :           }
    7146          279 :         tree v = create_tmp_var_raw (iter_type);
    7147          279 :         DECL_CONTEXT (v) = current_function_decl;
    7148          279 :         DECL_SEEN_IN_BIND_EXPR_P (v) = 1;
    7149          279 :         DECL_CHAIN (v) = ctx->block_vars;
    7150          279 :         ctx->block_vars = v;
    7151          279 :         tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
    7152          279 :         ctx->lastprivate_conditional_map->put (o, v);
    7153              :       }
    7154        47266 : }
    7155              : 
    7156              : 
    7157              : /* Generate code to implement the LASTPRIVATE clauses.  This is used for
    7158              :    both parallel and workshare constructs.  PREDICATE may be NULL if it's
    7159              :    always true.  BODY_P is the sequence to insert early initialization
    7160              :    if needed, STMT_LIST is where the non-conditional lastprivate handling
    7161              :    goes into and CSTMT_LIST is a sequence that needs to be run in a critical
    7162              :    section.  */
    7163              : 
    7164              : static void
    7165        47266 : lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p,
    7166              :                            gimple_seq *stmt_list, gimple_seq *cstmt_list,
    7167              :                            omp_context *ctx)
    7168              : {
    7169        47266 :   tree x, c, label = NULL, orig_clauses = clauses;
    7170        47266 :   bool par_clauses = false;
    7171        47266 :   tree simduid = NULL, lastlane = NULL, simtcond = NULL, simtlast = NULL;
    7172        47266 :   unsigned HOST_WIDE_INT conditional_off = 0;
    7173        47266 :   gimple_seq post_stmt_list = NULL;
    7174              : 
    7175              :   /* Early exit if there are no lastprivate or linear clauses.  */
    7176       196308 :   for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
    7177       161524 :     if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LASTPRIVATE
    7178       161524 :         || (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LINEAR
    7179         6763 :             && !OMP_CLAUSE_LINEAR_NO_COPYOUT (clauses)))
    7180              :       break;
    7181        47266 :   if (clauses == NULL)
    7182              :     {
    7183              :       /* If this was a workshare clause, see if it had been combined
    7184              :          with its parallel.  In that case, look for the clauses on the
    7185              :          parallel statement itself.  */
    7186        34784 :       if (is_parallel_ctx (ctx))
    7187        30785 :         return;
    7188              : 
    7189        34784 :       ctx = ctx->outer;
    7190        34784 :       if (ctx == NULL || !is_parallel_ctx (ctx))
    7191              :         return;
    7192              : 
    7193        12256 :       clauses = omp_find_clause (gimple_omp_parallel_clauses (ctx->stmt),
    7194              :                                  OMP_CLAUSE_LASTPRIVATE);
    7195        12256 :       if (clauses == NULL)
    7196              :         return;
    7197              :       par_clauses = true;
    7198              :     }
    7199              : 
    7200        16481 :   bool maybe_simt = false;
    7201        16481 :   if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    7202        16481 :       && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
    7203              :     {
    7204         7424 :       maybe_simt = omp_find_clause (orig_clauses, OMP_CLAUSE__SIMT_);
    7205         7424 :       simduid = omp_find_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
    7206         7424 :       if (simduid)
    7207         3558 :         simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
    7208              :     }
    7209              : 
    7210        16481 :   if (predicate)
    7211              :     {
    7212        16362 :       gcond *stmt;
    7213        16362 :       tree label_true, arm1, arm2;
    7214        16362 :       enum tree_code pred_code = TREE_CODE (predicate);
    7215              : 
    7216        16362 :       label = create_artificial_label (UNKNOWN_LOCATION);
    7217        16362 :       label_true = create_artificial_label (UNKNOWN_LOCATION);
    7218        16362 :       if (TREE_CODE_CLASS (pred_code) == tcc_comparison)
    7219              :         {
    7220        16362 :           arm1 = TREE_OPERAND (predicate, 0);
    7221        16362 :           arm2 = TREE_OPERAND (predicate, 1);
    7222        16362 :           gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
    7223        16362 :           gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
    7224              :         }
    7225              :       else
    7226              :         {
    7227            0 :           arm1 = predicate;
    7228            0 :           gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
    7229            0 :           arm2 = boolean_false_node;
    7230            0 :           pred_code = NE_EXPR;
    7231              :         }
    7232        16362 :       if (maybe_simt)
    7233              :         {
    7234            0 :           c = build2 (pred_code, boolean_type_node, arm1, arm2);
    7235            0 :           c = fold_convert (integer_type_node, c);
    7236            0 :           simtcond = create_tmp_var (integer_type_node);
    7237            0 :           gimplify_assign (simtcond, c, stmt_list);
    7238            0 :           gcall *g = gimple_build_call_internal (IFN_GOMP_SIMT_VOTE_ANY,
    7239              :                                                  1, simtcond);
    7240            0 :           c = create_tmp_var (integer_type_node);
    7241            0 :           gimple_call_set_lhs (g, c);
    7242            0 :           gimple_seq_add_stmt (stmt_list, g);
    7243            0 :           stmt = gimple_build_cond (NE_EXPR, c, integer_zero_node,
    7244              :                                     label_true, label);
    7245              :         }
    7246              :       else
    7247        16362 :         stmt = gimple_build_cond (pred_code, arm1, arm2, label_true, label);
    7248        16362 :       gimple_seq_add_stmt (stmt_list, stmt);
    7249        16362 :       gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
    7250              :     }
    7251              : 
    7252        16481 :   tree cond_ptr = NULL_TREE;
    7253        61575 :   for (c = clauses; c ;)
    7254              :     {
    7255        56348 :       tree var, new_var;
    7256        56348 :       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
    7257        56348 :       gimple_seq *this_stmt_list = stmt_list;
    7258        56348 :       tree lab2 = NULL_TREE;
    7259              : 
    7260        56348 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7261        21813 :           && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
    7262          386 :           && ctx->lastprivate_conditional_map
    7263        56721 :           && !ctx->combined_into_simd_safelen1)
    7264              :         {
    7265          316 :           gcc_assert (body_p);
    7266          316 :           if (simduid)
    7267           37 :             goto next;
    7268          279 :           if (cond_ptr == NULL_TREE)
    7269              :             {
    7270          205 :               cond_ptr = omp_find_clause (orig_clauses, OMP_CLAUSE__CONDTEMP_);
    7271          205 :               cond_ptr = OMP_CLAUSE_DECL (cond_ptr);
    7272              :             }
    7273          279 :           tree type = TREE_TYPE (TREE_TYPE (cond_ptr));
    7274          279 :           tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
    7275          279 :           tree v = *ctx->lastprivate_conditional_map->get (o);
    7276          279 :           gimplify_assign (v, build_zero_cst (type), body_p);
    7277          279 :           this_stmt_list = cstmt_list;
    7278          279 :           tree mem;
    7279          279 :           if (POINTER_TYPE_P (TREE_TYPE (cond_ptr)))
    7280              :             {
    7281          136 :               mem = build2 (MEM_REF, type, cond_ptr,
    7282          136 :                             build_int_cst (TREE_TYPE (cond_ptr),
    7283          136 :                                            conditional_off));
    7284          136 :               conditional_off += tree_to_uhwi (TYPE_SIZE_UNIT (type));
    7285              :             }
    7286              :           else
    7287          143 :             mem = build4 (ARRAY_REF, type, cond_ptr,
    7288          143 :                           size_int (conditional_off++), NULL_TREE, NULL_TREE);
    7289          279 :           tree mem2 = copy_node (mem);
    7290          279 :           gimple_seq seq = NULL;
    7291          279 :           mem = force_gimple_operand (mem, &seq, true, NULL_TREE);
    7292          279 :           gimple_seq_add_seq (this_stmt_list, seq);
    7293          279 :           tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
    7294          279 :           lab2 = create_artificial_label (UNKNOWN_LOCATION);
    7295          279 :           gimple *g = gimple_build_cond (GT_EXPR, v, mem, lab1, lab2);
    7296          279 :           gimple_seq_add_stmt (this_stmt_list, g);
    7297          279 :           gimple_seq_add_stmt (this_stmt_list, gimple_build_label (lab1));
    7298          279 :           gimplify_assign (mem2, v, this_stmt_list);
    7299              :         }
    7300        56032 :       else if (predicate
    7301        55794 :                && ctx->combined_into_simd_safelen1
    7302          116 :                && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7303           57 :                && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
    7304        56089 :                && ctx->lastprivate_conditional_map)
    7305              :         this_stmt_list = &post_stmt_list;
    7306              : 
    7307        56311 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7308        56311 :           || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
    7309         4867 :               && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
    7310              :         {
    7311        26643 :           var = OMP_CLAUSE_DECL (c);
    7312        26643 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7313        21776 :               && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
    7314        27670 :               && is_taskloop_ctx (ctx))
    7315              :             {
    7316          312 :               gcc_checking_assert (ctx->outer && is_task_ctx (ctx->outer));
    7317          312 :               new_var = lookup_decl (var, ctx->outer);
    7318              :             }
    7319              :           else
    7320              :             {
    7321        26331 :               new_var = lookup_decl (var, ctx);
    7322              :               /* Avoid uninitialized warnings for lastprivate and
    7323              :                  for linear iterators.  */
    7324        26331 :               if (predicate
    7325        52473 :                   && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7326         4867 :                       || OMP_CLAUSE_LINEAR_NO_COPYIN (c)))
    7327        24873 :                 suppress_warning (new_var, OPT_Wuninitialized);
    7328              :             }
    7329              : 
    7330        26643 :           if (!maybe_simt && simduid && DECL_HAS_VALUE_EXPR_P (new_var))
    7331              :             {
    7332         5879 :               tree val = DECL_VALUE_EXPR (new_var);
    7333         5879 :               if (TREE_CODE (val) == ARRAY_REF
    7334         5831 :                   && VAR_P (TREE_OPERAND (val, 0))
    7335        11710 :                   && lookup_attribute ("omp simd array",
    7336         5831 :                                        DECL_ATTRIBUTES (TREE_OPERAND (val,
    7337              :                                                                       0))))
    7338              :                 {
    7339         5831 :                   if (lastlane == NULL)
    7340              :                     {
    7341         2766 :                       lastlane = create_tmp_var (unsigned_type_node);
    7342         2766 :                       gcall *g
    7343         2766 :                         = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE,
    7344              :                                                       2, simduid,
    7345         2766 :                                                       TREE_OPERAND (val, 1));
    7346         2766 :                       gimple_call_set_lhs (g, lastlane);
    7347         2766 :                       gimple_seq_add_stmt (this_stmt_list, g);
    7348              :                     }
    7349         5831 :                   new_var = build4 (ARRAY_REF, TREE_TYPE (val),
    7350         5831 :                                     TREE_OPERAND (val, 0), lastlane,
    7351              :                                     NULL_TREE, NULL_TREE);
    7352         5831 :                   TREE_THIS_NOTRAP (new_var) = 1;
    7353              :                 }
    7354              :             }
    7355        20764 :           else if (maybe_simt)
    7356              :             {
    7357            0 :               tree val = (DECL_HAS_VALUE_EXPR_P (new_var)
    7358            0 :                           ? DECL_VALUE_EXPR (new_var)
    7359              :                           : new_var);
    7360            0 :               if (simtlast == NULL)
    7361              :                 {
    7362            0 :                   simtlast = create_tmp_var (unsigned_type_node);
    7363            0 :                   gcall *g = gimple_build_call_internal
    7364            0 :                     (IFN_GOMP_SIMT_LAST_LANE, 1, simtcond);
    7365            0 :                   gimple_call_set_lhs (g, simtlast);
    7366            0 :                   gimple_seq_add_stmt (this_stmt_list, g);
    7367              :                 }
    7368            0 :               x = build_call_expr_internal_loc
    7369            0 :                 (UNKNOWN_LOCATION, IFN_GOMP_SIMT_XCHG_IDX,
    7370            0 :                  TREE_TYPE (val), 2, val, simtlast);
    7371            0 :               new_var = unshare_expr (new_var);
    7372            0 :               gimplify_assign (new_var, x, this_stmt_list);
    7373            0 :               new_var = unshare_expr (new_var);
    7374              :             }
    7375              : 
    7376        26643 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7377        26643 :               && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
    7378              :             {
    7379         7159 :               lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
    7380         7159 :               gimple_seq_add_seq (this_stmt_list,
    7381         7159 :                                   OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
    7382         7159 :               OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
    7383              :             }
    7384        19484 :           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
    7385        19484 :                    && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
    7386              :             {
    7387          426 :               lower_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
    7388          426 :               gimple_seq_add_seq (this_stmt_list,
    7389          426 :                                   OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
    7390          426 :               OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) = NULL;
    7391              :             }
    7392              : 
    7393        26643 :           x = NULL_TREE;
    7394        26643 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7395        21776 :               && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)
    7396        26703 :               && is_taskloop_ctx (ctx))
    7397              :             {
    7398           76 :               tree ovar = maybe_lookup_decl_in_outer_ctx (var,
    7399           38 :                                                           ctx->outer->outer);
    7400           38 :               if (is_global_var (ovar))
    7401            7 :                 x = ovar;
    7402              :             }
    7403            7 :           if (!x)
    7404        26636 :             x = build_outer_var_ref (var, ctx, OMP_CLAUSE_LASTPRIVATE);
    7405        26643 :           if (omp_privatize_by_reference (var))
    7406          657 :             new_var = build_simple_mem_ref_loc (clause_loc, new_var);
    7407        26643 :           x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
    7408        26643 :           gimplify_and_add (x, this_stmt_list);
    7409              : 
    7410        26643 :           if (lab2)
    7411          279 :             gimple_seq_add_stmt (this_stmt_list, gimple_build_label (lab2));
    7412              :         }
    7413              : 
    7414        56348 :      next:
    7415        56348 :       c = OMP_CLAUSE_CHAIN (c);
    7416        56348 :       if (c == NULL && !par_clauses)
    7417              :         {
    7418              :           /* If this was a workshare clause, see if it had been combined
    7419              :              with its parallel.  In that case, continue looking for the
    7420              :              clauses also on the parallel statement itself.  */
    7421        12482 :           if (is_parallel_ctx (ctx))
    7422              :             break;
    7423              : 
    7424        12482 :           ctx = ctx->outer;
    7425        12482 :           if (ctx == NULL || !is_parallel_ctx (ctx))
    7426              :             break;
    7427              : 
    7428         1228 :           c = omp_find_clause (gimple_omp_parallel_clauses (ctx->stmt),
    7429              :                                OMP_CLAUSE_LASTPRIVATE);
    7430         1228 :           par_clauses = true;
    7431              :         }
    7432              :     }
    7433              : 
    7434        16481 :   if (label)
    7435        16362 :     gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
    7436        16481 :   gimple_seq_add_seq (stmt_list, post_stmt_list);
    7437              : }
    7438              : 
    7439              : /* Lower the OpenACC reductions of CLAUSES for compute axis LEVEL
    7440              :    (which might be a placeholder).  INNER is true if this is an inner
    7441              :    axis of a multi-axis loop.  FORK and JOIN are (optional) fork and
    7442              :    join markers.  Generate the before-loop forking sequence in
    7443              :    FORK_SEQ and the after-loop joining sequence to JOIN_SEQ.  The
    7444              :    general form of these sequences is
    7445              : 
    7446              :      GOACC_REDUCTION_SETUP
    7447              :      GOACC_FORK
    7448              :      GOACC_REDUCTION_INIT
    7449              :      ...
    7450              :      GOACC_REDUCTION_FINI
    7451              :      GOACC_JOIN
    7452              :      GOACC_REDUCTION_TEARDOWN.  */
    7453              : 
    7454              : static void
    7455        25946 : lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner,
    7456              :                        gcall *fork, gcall *private_marker, gcall *join,
    7457              :                        gimple_seq *fork_seq, gimple_seq *join_seq,
    7458              :                        omp_context *ctx)
    7459              : {
    7460        25946 :   gimple_seq before_fork = NULL;
    7461        25946 :   gimple_seq after_fork = NULL;
    7462        25946 :   gimple_seq before_join = NULL;
    7463        25946 :   gimple_seq after_join = NULL;
    7464        25946 :   tree init_code = NULL_TREE, fini_code = NULL_TREE,
    7465        25946 :     setup_code = NULL_TREE, teardown_code = NULL_TREE;
    7466        25946 :   unsigned offset = 0;
    7467              : 
    7468        96516 :   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    7469        70570 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
    7470              :       {
    7471              :         /* No 'reduction' clauses on OpenACC 'kernels'.  */
    7472         7751 :         gcc_checking_assert (!is_oacc_kernels (ctx));
    7473              :         /* Likewise, on OpenACC 'kernels' decomposed parts.  */
    7474         7751 :         gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));
    7475              : 
    7476         7751 :         tree orig = OMP_CLAUSE_DECL (c);
    7477         7751 :         tree orig_clause;
    7478         7751 :         tree var = maybe_lookup_decl (orig, ctx);
    7479         7751 :         tree ref_to_res = NULL_TREE;
    7480         7751 :         tree incoming, outgoing, v1, v2, v3;
    7481         7751 :         bool is_private = false;
    7482              : 
    7483         7751 :         enum tree_code rcode = OMP_CLAUSE_REDUCTION_CODE (c);
    7484         7751 :         if (rcode == MINUS_EXPR)
    7485              :           rcode = PLUS_EXPR;
    7486         6609 :         else if (rcode == TRUTH_ANDIF_EXPR)
    7487              :           rcode = BIT_AND_EXPR;
    7488         6431 :         else if (rcode == TRUTH_ORIF_EXPR)
    7489          433 :           rcode = BIT_IOR_EXPR;
    7490         7751 :         tree op = build_int_cst (unsigned_type_node, rcode);
    7491              : 
    7492         7751 :         if (!var)
    7493            4 :           var = orig;
    7494              : 
    7495         7751 :         incoming = outgoing = var;
    7496              : 
    7497         7751 :         if (!inner)
    7498              :           {
    7499              :             /* See if an outer construct also reduces this variable.  */
    7500              :             omp_context *outer = ctx;
    7501              : 
    7502         7385 :             while (omp_context *probe = outer->outer)
    7503              :               {
    7504         4708 :                 enum gimple_code type = gimple_code (probe->stmt);
    7505         4708 :                 tree cls;
    7506              : 
    7507         4708 :                 switch (type)
    7508              :                   {
    7509         2220 :                   case GIMPLE_OMP_FOR:
    7510         2220 :                     cls = gimple_omp_for_clauses (probe->stmt);
    7511         2220 :                     break;
    7512              : 
    7513         2488 :                   case GIMPLE_OMP_TARGET:
    7514              :                     /* No 'reduction' clauses inside OpenACC 'kernels'
    7515              :                        regions.  */
    7516         2488 :                     gcc_checking_assert (!is_oacc_kernels (probe));
    7517              : 
    7518         2488 :                     if (!is_gimple_omp_offloaded (probe->stmt))
    7519           26 :                       goto do_lookup;
    7520              : 
    7521         2462 :                     cls = gimple_omp_target_clauses (probe->stmt);
    7522         2462 :                     break;
    7523              : 
    7524            0 :                   default:
    7525            0 :                     goto do_lookup;
    7526              :                   }
    7527              : 
    7528        14249 :                 outer = probe;
    7529        14249 :                 for (; cls;  cls = OMP_CLAUSE_CHAIN (cls))
    7530        11632 :                   if (OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_REDUCTION
    7531        11632 :                       && orig == OMP_CLAUSE_DECL (cls))
    7532              :                     {
    7533         1772 :                       incoming = outgoing = lookup_decl (orig, probe);
    7534         1772 :                       goto has_outer_reduction;
    7535              :                     }
    7536         9860 :                   else if ((OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_FIRSTPRIVATE
    7537         8971 :                             || OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_PRIVATE)
    7538        11164 :                            && orig == OMP_CLAUSE_DECL (cls))
    7539              :                     {
    7540          293 :                       is_private = true;
    7541          293 :                       goto do_lookup;
    7542              :                     }
    7543              :               }
    7544              : 
    7545         2677 :           do_lookup:
    7546              :             /* This is the outermost construct with this reduction,
    7547              :                see if there's a mapping for it.  */
    7548         2996 :             orig_clause = NULL_TREE;
    7549         2996 :             if (gimple_code (outer->stmt) == GIMPLE_OMP_TARGET)
    7550         7557 :               for (tree cls = gimple_omp_target_clauses (outer->stmt);
    7551         7557 :                    cls; cls = OMP_CLAUSE_CHAIN (cls))
    7552         7250 :                 if (OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_MAP
    7553         4823 :                     && orig == OMP_CLAUSE_DECL (cls)
    7554         9805 :                     && maybe_lookup_field (cls, outer))
    7555              :                   {
    7556              :                     orig_clause = cls;
    7557              :                     break;
    7558              :                   }
    7559         2996 :             if (orig_clause != NULL_TREE && !is_private)
    7560              :               {
    7561         2553 :                 ref_to_res = build_receiver_ref (orig_clause, false, outer);
    7562         2553 :                 if (omp_privatize_by_reference (orig))
    7563           79 :                   ref_to_res = build_simple_mem_ref (ref_to_res);
    7564              : 
    7565         2553 :                 tree type = TREE_TYPE (var);
    7566         2553 :                 if (POINTER_TYPE_P (type))
    7567           79 :                   type = TREE_TYPE (type);
    7568              : 
    7569         2553 :                 outgoing = var;
    7570         2553 :                 incoming = omp_reduction_init_op (loc, rcode, type);
    7571              :               }
    7572              :             else
    7573              :               {
    7574              :                 /* Try to look at enclosing contexts for reduction var,
    7575              :                    use original if no mapping found.  */
    7576          443 :                 tree t = NULL_TREE;
    7577          443 :                 omp_context *c = ctx->outer;
    7578          895 :                 while (c && !t)
    7579              :                   {
    7580          452 :                     t = maybe_lookup_decl (orig, c);
    7581          452 :                     c = c->outer;
    7582              :                   }
    7583          443 :                 incoming = outgoing = (t ? t : orig);
    7584              :               }
    7585              : 
    7586         2553 :           has_outer_reduction:;
    7587              :           }
    7588              : 
    7589         4325 :         if (!ref_to_res)
    7590         5198 :           ref_to_res = integer_zero_node;
    7591              : 
    7592         7751 :         if (omp_privatize_by_reference (orig))
    7593              :           {
    7594          159 :             tree type = TREE_TYPE (var);
    7595          159 :             const char *id = IDENTIFIER_POINTER (DECL_NAME (var));
    7596              : 
    7597          159 :             if (!inner)
    7598              :               {
    7599          110 :                 tree x = create_tmp_var (TREE_TYPE (type), id);
    7600          110 :                 gimplify_assign (var, build_fold_addr_expr (x), fork_seq);
    7601              :               }
    7602              : 
    7603          159 :             v1 = create_tmp_var (type, id);
    7604          159 :             v2 = create_tmp_var (type, id);
    7605          159 :             v3 = create_tmp_var (type, id);
    7606              : 
    7607          159 :             gimplify_assign (v1, var, fork_seq);
    7608          159 :             gimplify_assign (v2, var, fork_seq);
    7609          159 :             gimplify_assign (v3, var, fork_seq);
    7610              : 
    7611          159 :             var = build_simple_mem_ref (var);
    7612          159 :             v1 = build_simple_mem_ref (v1);
    7613          159 :             v2 = build_simple_mem_ref (v2);
    7614          159 :             v3 = build_simple_mem_ref (v3);
    7615          159 :             outgoing = build_simple_mem_ref (outgoing);
    7616              : 
    7617          159 :             if (!TREE_CONSTANT (incoming))
    7618           80 :               incoming = build_simple_mem_ref (incoming);
    7619              :           }
    7620              :         else
    7621              :           /* Note that 'var' might be a mem ref.  */
    7622              :           v1 = v2 = v3 = var;
    7623              : 
    7624              :         /* Determine position in reduction buffer, which may be used
    7625              :            by target.  The parser has ensured that this is not a
    7626              :            variable-sized type.  */
    7627         7751 :         fixed_size_mode mode
    7628         7751 :           = as_a <fixed_size_mode> (TYPE_MODE (TREE_TYPE (var)));
    7629         7751 :         unsigned align = GET_MODE_ALIGNMENT (mode) /  BITS_PER_UNIT;
    7630         7751 :         offset = (offset + align - 1) & ~(align - 1);
    7631         7751 :         tree off = build_int_cst (sizetype, offset);
    7632         7751 :         offset += GET_MODE_SIZE (mode);
    7633              : 
    7634         7751 :         if (!init_code)
    7635              :           {
    7636         6969 :             init_code = build_int_cst (integer_type_node,
    7637              :                                        IFN_GOACC_REDUCTION_INIT);
    7638         6969 :             fini_code = build_int_cst (integer_type_node,
    7639              :                                        IFN_GOACC_REDUCTION_FINI);
    7640         6969 :             setup_code = build_int_cst (integer_type_node,
    7641              :                                         IFN_GOACC_REDUCTION_SETUP);
    7642         6969 :             teardown_code = build_int_cst (integer_type_node,
    7643              :                                            IFN_GOACC_REDUCTION_TEARDOWN);
    7644              :           }
    7645              : 
    7646         7751 :         tree setup_call
    7647        15502 :           = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
    7648         7751 :                                           TREE_TYPE (var), 6, setup_code,
    7649              :                                           unshare_expr (ref_to_res),
    7650              :                                           unshare_expr (incoming),
    7651              :                                           level, op, off);
    7652         7751 :         tree init_call
    7653        15502 :           = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
    7654         7751 :                                           TREE_TYPE (var), 6, init_code,
    7655              :                                           unshare_expr (ref_to_res),
    7656              :                                           unshare_expr (v1), level, op, off);
    7657         7751 :         tree fini_call
    7658        15502 :           = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
    7659         7751 :                                           TREE_TYPE (var), 6, fini_code,
    7660              :                                           unshare_expr (ref_to_res),
    7661              :                                           unshare_expr (v2), level, op, off);
    7662         7751 :         tree teardown_call
    7663        15502 :           = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
    7664         7751 :                                           TREE_TYPE (var), 6, teardown_code,
    7665              :                                           ref_to_res, unshare_expr (v3),
    7666              :                                           level, op, off);
    7667              : 
    7668         7751 :         gimplify_assign (unshare_expr (v1), setup_call, &before_fork);
    7669         7751 :         gimplify_assign (unshare_expr (v2), init_call, &after_fork);
    7670         7751 :         gimplify_assign (unshare_expr (v3), fini_call, &before_join);
    7671         7751 :         gimplify_assign (unshare_expr (outgoing), teardown_call, &after_join);
    7672              :       }
    7673              : 
    7674              :   /* Now stitch things together.  */
    7675        25946 :   gimple_seq_add_seq (fork_seq, before_fork);
    7676        25946 :   if (private_marker)
    7677          259 :     gimple_seq_add_stmt (fork_seq, private_marker);
    7678        25946 :   if (fork)
    7679        16551 :     gimple_seq_add_stmt (fork_seq, fork);
    7680        25946 :   gimple_seq_add_seq (fork_seq, after_fork);
    7681              : 
    7682        25946 :   gimple_seq_add_seq (join_seq, before_join);
    7683        25946 :   if (join)
    7684        16551 :     gimple_seq_add_stmt (join_seq, join);
    7685        25946 :   gimple_seq_add_seq (join_seq, after_join);
    7686        25946 : }
    7687              : 
    7688              : /* Generate code to implement the REDUCTION clauses, append it
    7689              :    to STMT_SEQP.  CLIST if non-NULL is a pointer to a sequence
    7690              :    that should be emitted also inside of the critical section,
    7691              :    in that case clear *CLIST afterwards, otherwise leave it as is
    7692              :    and let the caller emit it itself.  */
    7693              : 
    7694              : static void
    7695        71912 : lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp,
    7696              :                          gimple_seq *clist, omp_context *ctx)
    7697              : {
    7698        71912 :   gimple_seq sub_seq = NULL;
    7699        71912 :   gimple *stmt;
    7700        71912 :   tree x, c;
    7701        71912 :   int count = 0;
    7702              : 
    7703              :   /* OpenACC loop reductions are handled elsewhere.  */
    7704        71912 :   if (is_gimple_omp_oacc (ctx->stmt))
    7705        70887 :     return;
    7706              : 
    7707              :   /* SIMD reductions are handled in lower_rec_input_clauses.  */
    7708        60587 :   if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    7709        60587 :       && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
    7710              :     return;
    7711              : 
    7712              :   /* inscan reductions are handled elsewhere.  */
    7713        51232 :   if (ctx->scan_inclusive || ctx->scan_exclusive)
    7714              :     return;
    7715              : 
    7716              :   /* First see if there is exactly one reduction clause.  Use OMP_ATOMIC
    7717              :      update in that case, otherwise use a lock.  */
    7718       242115 :   for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
    7719       191904 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    7720       191904 :         && !OMP_CLAUSE_REDUCTION_TASK (c))
    7721              :       {
    7722         4581 :         if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
    7723         4581 :             || TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
    7724              :           {
    7725              :             /* Never use OMP_ATOMIC for array reductions or UDRs.  */
    7726              :             count = -1;
    7727              :             break;
    7728              :           }
    7729         3733 :         count++;
    7730              :       }
    7731              : 
    7732        51059 :   if (count == 0)
    7733              :     return;
    7734              : 
    7735        14912 :   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    7736              :     {
    7737        13887 :       tree var, ref, new_var, orig_var;
    7738        13887 :       enum tree_code code;
    7739        13887 :       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
    7740              : 
    7741        22381 :       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
    7742        13887 :           || OMP_CLAUSE_REDUCTION_TASK (c))
    7743         8494 :         continue;
    7744              : 
    7745         5393 :       enum omp_clause_code ccode = OMP_CLAUSE_REDUCTION;
    7746         5393 :       orig_var = var = OMP_CLAUSE_DECL (c);
    7747         5393 :       if (TREE_CODE (var) == MEM_REF)
    7748              :         {
    7749          689 :           var = TREE_OPERAND (var, 0);
    7750          689 :           if (TREE_CODE (var) == POINTER_PLUS_EXPR)
    7751           50 :             var = TREE_OPERAND (var, 0);
    7752          689 :           if (TREE_CODE (var) == ADDR_EXPR)
    7753          304 :             var = TREE_OPERAND (var, 0);
    7754              :           else
    7755              :             {
    7756              :               /* If this is a pointer or referenced based array
    7757              :                  section, the var could be private in the outer
    7758              :                  context e.g. on orphaned loop construct.  Pretend this
    7759              :                  is private variable's outer reference.  */
    7760          385 :               ccode = OMP_CLAUSE_PRIVATE;
    7761          385 :               if (INDIRECT_REF_P (var))
    7762           54 :                 var = TREE_OPERAND (var, 0);
    7763              :             }
    7764          689 :           orig_var = var;
    7765          689 :           if (is_variable_sized (var))
    7766              :             {
    7767           25 :               gcc_assert (DECL_HAS_VALUE_EXPR_P (var));
    7768           25 :               var = DECL_VALUE_EXPR (var);
    7769           25 :               gcc_assert (INDIRECT_REF_P (var));
    7770           25 :               var = TREE_OPERAND (var, 0);
    7771           25 :               gcc_assert (DECL_P (var));
    7772              :             }
    7773              :         }
    7774         5393 :       new_var = lookup_decl (var, ctx);
    7775         5393 :       if (var == OMP_CLAUSE_DECL (c)
    7776         5393 :           && omp_privatize_by_reference (var))
    7777          152 :         new_var = build_simple_mem_ref_loc (clause_loc, new_var);
    7778         5393 :       ref = build_outer_var_ref (var, ctx, ccode);
    7779         5393 :       code = OMP_CLAUSE_REDUCTION_CODE (c);
    7780              : 
    7781              :       /* reduction(-:var) sums up the partial results, so it acts
    7782              :          identically to reduction(+:var).  */
    7783         5393 :       if (code == MINUS_EXPR)
    7784           57 :         code = PLUS_EXPR;
    7785              : 
    7786         5393 :       bool is_truth_op = (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR);
    7787         5393 :       if (count == 1)
    7788              :         {
    7789         3324 :           tree addr = build_fold_addr_expr_loc (clause_loc, ref);
    7790              : 
    7791         3324 :           addr = save_expr (addr);
    7792         3324 :           ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
    7793         3324 :           tree new_var2 = new_var;
    7794         3324 :           tree ref2 = ref;
    7795         3324 :           if (is_truth_op)
    7796              :             {
    7797          784 :               tree zero = build_zero_cst (TREE_TYPE (new_var));
    7798          784 :               new_var2 = fold_build2_loc (clause_loc, NE_EXPR,
    7799              :                                           boolean_type_node, new_var, zero);
    7800          784 :               ref2 = fold_build2_loc (clause_loc, NE_EXPR, boolean_type_node,
    7801              :                                       ref, zero);
    7802              :             }
    7803         3324 :           x = fold_build2_loc (clause_loc, code, TREE_TYPE (new_var2), ref2,
    7804              :                                new_var2);
    7805         3324 :           if (is_truth_op)
    7806          784 :             x = fold_convert (TREE_TYPE (new_var), x);
    7807         3324 :           x = build2 (OMP_ATOMIC, void_type_node, addr, x);
    7808         3324 :           OMP_ATOMIC_MEMORY_ORDER (x) = OMP_MEMORY_ORDER_RELAXED;
    7809         3324 :           gimplify_and_add (x, stmt_seqp);
    7810         3324 :           return;
    7811              :         }
    7812         2069 :       else if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
    7813              :         {
    7814          689 :           tree d = OMP_CLAUSE_DECL (c);
    7815          689 :           tree type = TREE_TYPE (d);
    7816          689 :           tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
    7817          689 :           tree i = create_tmp_var (TREE_TYPE (v));
    7818          689 :           tree ptype = build_pointer_type (TREE_TYPE (type));
    7819          689 :           tree bias = TREE_OPERAND (d, 1);
    7820          689 :           d = TREE_OPERAND (d, 0);
    7821          689 :           if (TREE_CODE (d) == POINTER_PLUS_EXPR)
    7822              :             {
    7823           50 :               tree b = TREE_OPERAND (d, 1);
    7824           50 :               b = maybe_lookup_decl (b, ctx);
    7825           50 :               if (b == NULL)
    7826              :                 {
    7827            2 :                   b = TREE_OPERAND (d, 1);
    7828            2 :                   b = maybe_lookup_decl_in_outer_ctx (b, ctx);
    7829              :                 }
    7830           50 :               if (integer_zerop (bias))
    7831              :                 bias = b;
    7832              :               else
    7833              :                 {
    7834            0 :                   bias = fold_convert_loc (clause_loc, TREE_TYPE (b), bias);
    7835            0 :                   bias = fold_build2_loc (clause_loc, PLUS_EXPR,
    7836            0 :                                           TREE_TYPE (b), b, bias);
    7837              :                 }
    7838           50 :               d = TREE_OPERAND (d, 0);
    7839              :             }
    7840              :           /* For ref build_outer_var_ref already performs this, so
    7841              :              only new_var needs a dereference.  */
    7842          689 :           if (INDIRECT_REF_P (d))
    7843              :             {
    7844           54 :               new_var = build_simple_mem_ref_loc (clause_loc, new_var);
    7845           54 :               gcc_assert (omp_privatize_by_reference (var)
    7846              :                           && var == orig_var);
    7847              :             }
    7848          635 :           else if (TREE_CODE (d) == ADDR_EXPR)
    7849              :             {
    7850          304 :               if (orig_var == var)
    7851              :                 {
    7852          279 :                   new_var = build_fold_addr_expr (new_var);
    7853          279 :                   ref = build_fold_addr_expr (ref);
    7854              :                 }
    7855              :             }
    7856              :           else
    7857              :             {
    7858          331 :               gcc_assert (orig_var == var);
    7859          331 :               if (omp_privatize_by_reference (var))
    7860           79 :                 ref = build_fold_addr_expr (ref);
    7861              :             }
    7862          689 :           if (DECL_P (v))
    7863              :             {
    7864           93 :               tree t = maybe_lookup_decl (v, ctx);
    7865           93 :               if (t)
    7866           88 :                 v = t;
    7867              :               else
    7868            5 :                 v = maybe_lookup_decl_in_outer_ctx (v, ctx);
    7869           93 :               gimplify_expr (&v, stmt_seqp, NULL, is_gimple_val, fb_rvalue);
    7870              :             }
    7871          689 :           if (!integer_zerop (bias))
    7872              :             {
    7873          402 :               bias = fold_convert_loc (clause_loc, sizetype, bias);
    7874          804 :               new_var = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
    7875          402 :                                          TREE_TYPE (new_var), new_var,
    7876              :                                          unshare_expr (bias));
    7877          402 :               ref = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
    7878          402 :                                          TREE_TYPE (ref), ref, bias);
    7879              :             }
    7880          689 :           new_var = fold_convert_loc (clause_loc, ptype, new_var);
    7881          689 :           ref = fold_convert_loc (clause_loc, ptype, ref);
    7882          689 :           tree m = create_tmp_var (ptype);
    7883          689 :           gimplify_assign (m, new_var, stmt_seqp);
    7884          689 :           new_var = m;
    7885          689 :           m = create_tmp_var (ptype);
    7886          689 :           gimplify_assign (m, ref, stmt_seqp);
    7887          689 :           ref = m;
    7888          689 :           gimplify_assign (i, build_int_cst (TREE_TYPE (v), 0), stmt_seqp);
    7889          689 :           tree body = create_artificial_label (UNKNOWN_LOCATION);
    7890          689 :           tree end = create_artificial_label (UNKNOWN_LOCATION);
    7891          689 :           gimple_seq_add_stmt (&sub_seq, gimple_build_label (body));
    7892          689 :           tree priv = build_simple_mem_ref_loc (clause_loc, new_var);
    7893          689 :           tree out = build_simple_mem_ref_loc (clause_loc, ref);
    7894          689 :           if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    7895              :             {
    7896           72 :               tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
    7897           72 :               tree decl_placeholder
    7898           72 :                 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c);
    7899           72 :               SET_DECL_VALUE_EXPR (placeholder, out);
    7900           72 :               DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
    7901           72 :               SET_DECL_VALUE_EXPR (decl_placeholder, priv);
    7902           72 :               DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 1;
    7903           72 :               lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
    7904           72 :               gimple_seq_add_seq (&sub_seq,
    7905           72 :                                   OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
    7906           72 :               OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    7907           72 :               OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
    7908           72 :               OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) = NULL;
    7909              :             }
    7910              :           else
    7911              :             {
    7912          617 :               tree out2 = out;
    7913          617 :               tree priv2 = priv;
    7914          617 :               if (is_truth_op)
    7915              :                 {
    7916            0 :                   tree zero = build_zero_cst (TREE_TYPE (out));
    7917            0 :                   out2 = fold_build2_loc (clause_loc, NE_EXPR,
    7918              :                                           boolean_type_node, out, zero);
    7919            0 :                   priv2 = fold_build2_loc (clause_loc, NE_EXPR,
    7920              :                                            boolean_type_node, priv, zero);
    7921              :                 }
    7922          617 :               x = build2 (code, TREE_TYPE (out2), out2, priv2);
    7923          617 :               if (is_truth_op)
    7924            0 :                 x = fold_convert (TREE_TYPE (out), x);
    7925          617 :               out = unshare_expr (out);
    7926          617 :               gimplify_assign (out, x, &sub_seq);
    7927              :             }
    7928          689 :           gimple *g = gimple_build_assign (new_var, POINTER_PLUS_EXPR, new_var,
    7929          689 :                                            TYPE_SIZE_UNIT (TREE_TYPE (type)));
    7930          689 :           gimple_seq_add_stmt (&sub_seq, g);
    7931          689 :           g = gimple_build_assign (ref, POINTER_PLUS_EXPR, ref,
    7932          689 :                                    TYPE_SIZE_UNIT (TREE_TYPE (type)));
    7933          689 :           gimple_seq_add_stmt (&sub_seq, g);
    7934          689 :           g = gimple_build_assign (i, PLUS_EXPR, i,
    7935          689 :                                    build_int_cst (TREE_TYPE (i), 1));
    7936          689 :           gimple_seq_add_stmt (&sub_seq, g);
    7937          689 :           g = gimple_build_cond (LE_EXPR, i, v, body, end);
    7938          689 :           gimple_seq_add_stmt (&sub_seq, g);
    7939          689 :           gimple_seq_add_stmt (&sub_seq, gimple_build_label (end));
    7940              :         }
    7941         1380 :       else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    7942              :         {
    7943          774 :           tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
    7944              : 
    7945          774 :           if (omp_privatize_by_reference (var)
    7946          831 :               && !useless_type_conversion_p (TREE_TYPE (placeholder),
    7947           57 :                                              TREE_TYPE (ref)))
    7948           49 :             ref = build_fold_addr_expr_loc (clause_loc, ref);
    7949          774 :           SET_DECL_VALUE_EXPR (placeholder, ref);
    7950          774 :           DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
    7951          774 :           lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
    7952          774 :           gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
    7953          774 :           OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    7954          774 :           OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
    7955              :         }
    7956              :       else
    7957              :         {
    7958          606 :           tree new_var2 = new_var;
    7959          606 :           tree ref2 = ref;
    7960          606 :           if (is_truth_op)
    7961              :             {
    7962           78 :               tree zero = build_zero_cst (TREE_TYPE (new_var));
    7963           78 :               new_var2 = fold_build2_loc (clause_loc, NE_EXPR,
    7964              :                                           boolean_type_node, new_var, zero);
    7965           78 :               ref2 = fold_build2_loc (clause_loc, NE_EXPR, boolean_type_node,
    7966              :                                       ref, zero);
    7967              :             }
    7968          606 :           x = build2 (code, TREE_TYPE (ref), ref2, new_var2);
    7969          606 :           if (is_truth_op)
    7970           78 :             x = fold_convert (TREE_TYPE (new_var), x);
    7971          606 :           ref = build_outer_var_ref (var, ctx);
    7972          606 :           gimplify_assign (ref, x, &sub_seq);
    7973              :         }
    7974              :     }
    7975              : 
    7976         1025 :   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
    7977              :                             0);
    7978         1025 :   gimple_seq_add_stmt (stmt_seqp, stmt);
    7979              : 
    7980         1025 :   gimple_seq_add_seq (stmt_seqp, sub_seq);
    7981              : 
    7982         1025 :   if (clist)
    7983              :     {
    7984          157 :       gimple_seq_add_seq (stmt_seqp, *clist);
    7985          157 :       *clist = NULL;
    7986              :     }
    7987              : 
    7988         1025 :   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
    7989              :                             0);
    7990         1025 :   gimple_seq_add_stmt (stmt_seqp, stmt);
    7991              : }
    7992              : 
    7993              : 
    7994              : /* Generate code to implement the COPYPRIVATE clauses.  */
    7995              : 
    7996              : static void
    7997          115 : lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
    7998              :                             omp_context *ctx)
    7999              : {
    8000          115 :   tree c;
    8001              : 
    8002          463 :   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    8003              :     {
    8004          348 :       tree var, new_var, ref, x;
    8005          348 :       bool by_ref;
    8006          348 :       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
    8007              : 
    8008          348 :       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
    8009            6 :         continue;
    8010              : 
    8011          342 :       var = OMP_CLAUSE_DECL (c);
    8012          342 :       by_ref = use_pointer_for_field (var, NULL);
    8013              : 
    8014          342 :       ref = build_sender_ref (var, ctx);
    8015          342 :       x = new_var = lookup_decl_in_outer_ctx (var, ctx);
    8016          342 :       if (by_ref)
    8017              :         {
    8018           74 :           x = build_fold_addr_expr_loc (clause_loc, new_var);
    8019           74 :           x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
    8020              :         }
    8021          342 :       gimplify_assign (ref, x, slist);
    8022              : 
    8023          342 :       ref = build_receiver_ref (var, false, ctx);
    8024          342 :       if (by_ref)
    8025              :         {
    8026           74 :           ref = fold_convert_loc (clause_loc,
    8027           74 :                                   build_pointer_type (TREE_TYPE (new_var)),
    8028              :                                   ref);
    8029           74 :           ref = build_fold_indirect_ref_loc (clause_loc, ref);
    8030              :         }
    8031          342 :       if (omp_privatize_by_reference (var))
    8032              :         {
    8033          171 :           ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
    8034          171 :           ref = build_simple_mem_ref_loc (clause_loc, ref);
    8035          171 :           new_var = build_simple_mem_ref_loc (clause_loc, new_var);
    8036              :         }
    8037          342 :       x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
    8038          342 :       gimplify_and_add (x, rlist);
    8039              :     }
    8040          115 : }
    8041              : 
    8042              : 
    8043              : /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
    8044              :    and REDUCTION from the sender (aka parent) side.  */
    8045              : 
    8046              : static void
    8047        22373 : lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
    8048              :                     omp_context *ctx)
    8049              : {
    8050        22373 :   tree c, t;
    8051        22373 :   int ignored_looptemp = 0;
    8052        22373 :   bool is_taskloop = false;
    8053              : 
    8054              :   /* For taskloop, ignore first two _looptemp_ clauses, those are initialized
    8055              :      by GOMP_taskloop.  */
    8056        22373 :   if (is_task_ctx (ctx) && gimple_omp_task_taskloop_p (ctx->stmt))
    8057              :     {
    8058              :       ignored_looptemp = 2;
    8059              :       is_taskloop = true;
    8060              :     }
    8061              : 
    8062       116872 :   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    8063              :     {
    8064        94499 :       tree val, ref, x, var;
    8065        94499 :       bool by_ref, do_in = false, do_out = false;
    8066        94499 :       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
    8067              : 
    8068        94499 :       switch (OMP_CLAUSE_CODE (c))
    8069              :         {
    8070         4658 :         case OMP_CLAUSE_PRIVATE:
    8071         4658 :           if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
    8072              :             break;
    8073         4503 :           continue;
    8074              :         case OMP_CLAUSE_FIRSTPRIVATE:
    8075              :         case OMP_CLAUSE_COPYIN:
    8076              :         case OMP_CLAUSE_LASTPRIVATE:
    8077              :         case OMP_CLAUSE_IN_REDUCTION:
    8078              :         case OMP_CLAUSE__REDUCTEMP_:
    8079              :           break;
    8080         4785 :         case OMP_CLAUSE_REDUCTION:
    8081         4785 :           if (is_task_ctx (ctx) || OMP_CLAUSE_REDUCTION_TASK (c))
    8082          745 :             continue;
    8083              :           break;
    8084        17559 :         case OMP_CLAUSE_SHARED:
    8085        17559 :           if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
    8086              :             break;
    8087        17247 :           continue;
    8088        18795 :         case OMP_CLAUSE__LOOPTEMP_:
    8089        18795 :           if (ignored_looptemp)
    8090              :             {
    8091         2660 :               ignored_looptemp--;
    8092         2660 :               continue;
    8093              :             }
    8094              :           break;
    8095        11928 :         default:
    8096        11928 :           continue;
    8097              :         }
    8098              : 
    8099        57416 :       val = OMP_CLAUSE_DECL (c);
    8100        57416 :       if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    8101        53376 :            || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
    8102        59056 :           && TREE_CODE (val) == MEM_REF)
    8103              :         {
    8104         1578 :           val = TREE_OPERAND (val, 0);
    8105         1578 :           if (TREE_CODE (val) == POINTER_PLUS_EXPR)
    8106          351 :             val = TREE_OPERAND (val, 0);
    8107         1578 :           if (INDIRECT_REF_P (val)
    8108         1494 :               || TREE_CODE (val) == ADDR_EXPR)
    8109          906 :             val = TREE_OPERAND (val, 0);
    8110         1578 :           if (is_variable_sized (val))
    8111           56 :             continue;
    8112              :         }
    8113              : 
    8114              :       /* For OMP_CLAUSE_SHARED_FIRSTPRIVATE, look beyond the
    8115              :          outer taskloop region.  */
    8116        57360 :       omp_context *ctx_for_o = ctx;
    8117        57360 :       if (is_taskloop
    8118         3911 :           && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
    8119        57672 :           && OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
    8120          312 :         ctx_for_o = ctx->outer;
    8121              : 
    8122        57360 :       var = lookup_decl_in_outer_ctx (val, ctx_for_o);
    8123              : 
    8124        57360 :       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
    8125        56850 :           && is_global_var (var)
    8126        59659 :           && (val == OMP_CLAUSE_DECL (c)
    8127          273 :               || !is_task_ctx (ctx)
    8128          241 :               || (TREE_CODE (TREE_TYPE (val)) != POINTER_TYPE
    8129          187 :                   && (TREE_CODE (TREE_TYPE (val)) != REFERENCE_TYPE
    8130            0 :                       || (TREE_CODE (TREE_TYPE (TREE_TYPE (val)))
    8131              :                           != POINTER_TYPE)))))
    8132         2245 :         continue;
    8133              : 
    8134        55115 :       t = omp_member_access_dummy_var (var);
    8135        55115 :       if (t)
    8136              :         {
    8137          249 :           var = DECL_VALUE_EXPR (var);
    8138          249 :           tree o = maybe_lookup_decl_in_outer_ctx (t, ctx_for_o);
    8139          249 :           if (o != t)
    8140           69 :             var = unshare_and_remap (var, t, o);
    8141              :           else
    8142          180 :             var = unshare_expr (var);
    8143              :         }
    8144              : 
    8145        55115 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
    8146              :         {
    8147              :           /* Handle taskloop firstprivate/lastprivate, where the
    8148              :              lastprivate on GIMPLE_OMP_TASK is represented as
    8149              :              OMP_CLAUSE_SHARED_FIRSTPRIVATE.  */
    8150           79 :           tree f = lookup_sfield ((splay_tree_key) &DECL_UID (val), ctx);
    8151           79 :           x = omp_build_component_ref (ctx->sender_decl, f);
    8152           79 :           if (use_pointer_for_field (val, ctx))
    8153           59 :             var = build_fold_addr_expr (var);
    8154           79 :           gimplify_assign (x, var, ilist);
    8155           79 :           DECL_ABSTRACT_ORIGIN (f) = NULL;
    8156           79 :           continue;
    8157           79 :         }
    8158              : 
    8159        55090 :       if (((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
    8160        51741 :             && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION)
    8161         4431 :            || val == OMP_CLAUSE_DECL (c))
    8162       108769 :           && is_variable_sized (val))
    8163           54 :         continue;
    8164        54982 :       by_ref = use_pointer_for_field (val, NULL);
    8165              : 
    8166        54982 :       switch (OMP_CLAUSE_CODE (c))
    8167              :         {
    8168        26732 :         case OMP_CLAUSE_FIRSTPRIVATE:
    8169        26732 :           if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)
    8170         7218 :               && !by_ref
    8171        33898 :               && is_task_ctx (ctx))
    8172         2329 :             suppress_warning (var);
    8173              :           do_in = true;
    8174              :           break;
    8175              : 
    8176              :         case OMP_CLAUSE_PRIVATE:
    8177              :         case OMP_CLAUSE_COPYIN:
    8178              :         case OMP_CLAUSE__LOOPTEMP_:
    8179              :         case OMP_CLAUSE__REDUCTEMP_:
    8180              :           do_in = true;
    8181              :           break;
    8182              : 
    8183         6463 :         case OMP_CLAUSE_LASTPRIVATE:
    8184         6463 :           if (by_ref || omp_privatize_by_reference (val))
    8185              :             {
    8186          383 :               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
    8187          239 :                 continue;
    8188              :               do_in = true;
    8189              :             }
    8190              :           else
    8191              :             {
    8192         6080 :               do_out = true;
    8193         6080 :               if (lang_hooks.decls.omp_private_outer_ref (val))
    8194              :                 do_in = true;
    8195              :             }
    8196              :           break;
    8197              : 
    8198         4431 :         case OMP_CLAUSE_REDUCTION:
    8199         4431 :         case OMP_CLAUSE_IN_REDUCTION:
    8200         4431 :           do_in = true;
    8201         4431 :           if (val == OMP_CLAUSE_DECL (c))
    8202              :             {
    8203         3128 :               if (is_task_ctx (ctx))
    8204          301 :                 by_ref = use_pointer_for_field (val, ctx);
    8205              :               else
    8206         2827 :                 do_out = !(by_ref || omp_privatize_by_reference (val));
    8207              :             }
    8208              :           else
    8209         1303 :             by_ref = TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE;
    8210              :           break;
    8211              : 
    8212            0 :         default:
    8213            0 :           gcc_unreachable ();
    8214              :         }
    8215              : 
    8216         1604 :       if (do_in)
    8217              :         {
    8218        48687 :           ref = build_sender_ref (val, ctx);
    8219        48687 :           x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
    8220        48687 :           gimplify_assign (ref, x, ilist);
    8221        48687 :           if (is_task_ctx (ctx))
    8222         6229 :             DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
    8223              :         }
    8224              : 
    8225        54743 :       if (do_out)
    8226              :         {
    8227         8374 :           ref = build_sender_ref (val, ctx);
    8228         8374 :           gimplify_assign (var, ref, olist);
    8229              :         }
    8230              :     }
    8231        22373 : }
    8232              : 
    8233              : /* Generate code to implement SHARED from the sender (aka parent)
    8234              :    side.  This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
    8235              :    list things that got automatically shared.  */
    8236              : 
    8237              : static void
    8238        22373 : lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
    8239              : {
    8240        22373 :   tree var, ovar, nvar, t, f, x, record_type;
    8241              : 
    8242        22373 :   if (ctx->record_type == NULL)
    8243         4451 :     return;
    8244              : 
    8245        17922 :   record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
    8246        86681 :   for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
    8247              :     {
    8248        68759 :       ovar = DECL_ABSTRACT_ORIGIN (f);
    8249        68759 :       if (!ovar || TREE_CODE (ovar) == FIELD_DECL)
    8250         6308 :         continue;
    8251              : 
    8252        62451 :       nvar = maybe_lookup_decl (ovar, ctx);
    8253       113269 :       if (!nvar
    8254        62042 :           || !DECL_HAS_VALUE_EXPR_P (nvar)
    8255        74265 :           || (ctx->allocate_map
    8256          274 :               && ctx->allocate_map->get (ovar)))
    8257        50818 :         continue;
    8258              : 
    8259              :       /* If CTX is a nested parallel directive.  Find the immediately
    8260              :          enclosing parallel or workshare construct that contains a
    8261              :          mapping for OVAR.  */
    8262        11633 :       var = lookup_decl_in_outer_ctx (ovar, ctx);
    8263              : 
    8264        11633 :       t = omp_member_access_dummy_var (var);
    8265        11633 :       if (t)
    8266              :         {
    8267           49 :           var = DECL_VALUE_EXPR (var);
    8268           49 :           tree o = maybe_lookup_decl_in_outer_ctx (t, ctx);
    8269           49 :           if (o != t)
    8270           18 :             var = unshare_and_remap (var, t, o);
    8271              :           else
    8272           31 :             var = unshare_expr (var);
    8273              :         }
    8274              : 
    8275        11633 :       if (use_pointer_for_field (ovar, ctx))
    8276              :         {
    8277         6432 :           x = build_sender_ref (ovar, ctx);
    8278         6432 :           if (TREE_CODE (TREE_TYPE (f)) == ARRAY_TYPE
    8279         6432 :               && TREE_TYPE (f) == TREE_TYPE (ovar))
    8280              :             {
    8281          103 :               gcc_assert (is_parallel_ctx (ctx)
    8282              :                           && DECL_ARTIFICIAL (ovar));
    8283              :               /* _condtemp_ clause.  */
    8284          103 :               var = build_constructor (TREE_TYPE (x), NULL);
    8285              :             }
    8286              :           else
    8287         6329 :             var = build_fold_addr_expr (var);
    8288         6432 :           gimplify_assign (x, var, ilist);
    8289              :         }
    8290              :       else
    8291              :         {
    8292         5201 :           x = build_sender_ref (ovar, ctx);
    8293         5201 :           gimplify_assign (x, var, ilist);
    8294              : 
    8295         5201 :           if (!TREE_READONLY (var)
    8296              :               /* We don't need to receive a new reference to a result
    8297              :                  or parm decl.  In fact we may not store to it as we will
    8298              :                  invalidate any pending RSO and generate wrong gimple
    8299              :                  during inlining.  */
    8300         5201 :               && !((TREE_CODE (var) == RESULT_DECL
    8301         3304 :                     || TREE_CODE (var) == PARM_DECL)
    8302          182 :                    && DECL_BY_REFERENCE (var)))
    8303              :             {
    8304         3233 :               x = build_sender_ref (ovar, ctx);
    8305         3233 :               gimplify_assign (var, x, olist);
    8306              :             }
    8307              :         }
    8308              :     }
    8309              : }
    8310              : 
    8311              : /* Emit an OpenACC head marker call, encapulating the partitioning and
    8312              :    other information that must be processed by the target compiler.
    8313              :    Return the maximum number of dimensions the associated loop might
    8314              :    be partitioned over.  */
    8315              : 
    8316              : static unsigned
    8317         9665 : lower_oacc_head_mark (location_t loc, tree ddvar, tree clauses,
    8318              :                       gimple_seq *seq, omp_context *ctx)
    8319              : {
    8320         9665 :   unsigned levels = 0;
    8321         9665 :   unsigned tag = 0;
    8322         9665 :   tree gang_static = NULL_TREE;
    8323         9665 :   auto_vec<tree, 5> args;
    8324              : 
    8325        19330 :   args.quick_push (build_int_cst
    8326         9665 :                    (integer_type_node, IFN_UNIQUE_OACC_HEAD_MARK));
    8327         9665 :   args.quick_push (ddvar);
    8328        30854 :   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    8329              :     {
    8330        21189 :       switch (OMP_CLAUSE_CODE (c))
    8331              :         {
    8332         1856 :         case OMP_CLAUSE_GANG:
    8333         1856 :           tag |= OLF_DIM_GANG;
    8334         1856 :           gang_static = OMP_CLAUSE_GANG_STATIC_EXPR (c);
    8335              :           /* static:* is represented by -1, and we can ignore it, as
    8336              :              scheduling is always static.  */
    8337         1856 :           if (gang_static && integer_minus_onep (gang_static))
    8338           70 :             gang_static = NULL_TREE;
    8339         1856 :           levels++;
    8340         1856 :           break;
    8341              : 
    8342         1330 :         case OMP_CLAUSE_WORKER:
    8343         1330 :           tag |= OLF_DIM_WORKER;
    8344         1330 :           levels++;
    8345         1330 :           break;
    8346              : 
    8347         1523 :         case OMP_CLAUSE_VECTOR:
    8348         1523 :           tag |= OLF_DIM_VECTOR;
    8349         1523 :           levels++;
    8350         1523 :           break;
    8351              : 
    8352          314 :         case OMP_CLAUSE_SEQ:
    8353          314 :           tag |= OLF_SEQ;
    8354          314 :           break;
    8355              : 
    8356          409 :         case OMP_CLAUSE_AUTO:
    8357          409 :           tag |= OLF_AUTO;
    8358          409 :           break;
    8359              : 
    8360          260 :         case OMP_CLAUSE_INDEPENDENT:
    8361          260 :           tag |= OLF_INDEPENDENT;
    8362          260 :           break;
    8363              : 
    8364          136 :         case OMP_CLAUSE_TILE:
    8365          136 :           tag |= OLF_TILE;
    8366          136 :           break;
    8367              : 
    8368         3986 :         case OMP_CLAUSE_REDUCTION:
    8369         3986 :           tag |= OLF_REDUCTION;
    8370         3986 :           break;
    8371              : 
    8372        11375 :         default:
    8373        11375 :           continue;
    8374              :         }
    8375              :     }
    8376              : 
    8377         9665 :   if (gang_static)
    8378              :     {
    8379          146 :       if (DECL_P (gang_static))
    8380           16 :         gang_static = build_outer_var_ref (gang_static, ctx);
    8381          146 :       tag |= OLF_GANG_STATIC;
    8382              :     }
    8383              : 
    8384         9665 :   omp_context *tgt = enclosing_target_ctx (ctx);
    8385         9665 :   if (!tgt || is_oacc_parallel_or_serial (tgt))
    8386              :     ;
    8387           62 :   else if (is_oacc_kernels (tgt))
    8388              :     /* Not using this loops handling inside OpenACC 'kernels' regions.  */
    8389            0 :     gcc_unreachable ();
    8390           62 :   else if (is_oacc_kernels_decomposed_part (tgt))
    8391              :     ;
    8392              :   else
    8393            0 :     gcc_unreachable ();
    8394              : 
    8395              :   /* In a parallel region, loops are implicitly INDEPENDENT.  */
    8396         9665 :   if (!tgt || is_oacc_parallel_or_serial (tgt))
    8397         9603 :     tag |= OLF_INDEPENDENT;
    8398              : 
    8399              :   /* Loops inside OpenACC 'kernels' decomposed parts' regions are expected to
    8400              :      have an explicit 'seq' or 'independent' clause, and no 'auto' clause.  */
    8401         9665 :   if (tgt && is_oacc_kernels_decomposed_part (tgt))
    8402              :     {
    8403           62 :       gcc_assert (tag & (OLF_SEQ | OLF_INDEPENDENT));
    8404           62 :       gcc_assert (!(tag & OLF_AUTO));
    8405              :     }
    8406              : 
    8407         9665 :   if (tag & OLF_TILE)
    8408              :     /* Tiling could use all 3 levels.  */
    8409              :     levels = 3;
    8410              :   else
    8411              :     {
    8412              :       /* A loop lacking SEQ, GANG, WORKER and/or VECTOR could be AUTO.
    8413              :          Ensure at least one level, or 2 for possible auto
    8414              :          partitioning */
    8415         9529 :       bool maybe_auto = !(tag & (((GOMP_DIM_MASK (GOMP_DIM_MAX) - 1)
    8416              :                                   << OLF_DIM_BASE) | OLF_SEQ));
    8417              : 
    8418         9529 :       if (levels < 1u + maybe_auto)
    8419              :         levels = 1u + maybe_auto;
    8420              :     }
    8421              : 
    8422         9665 :   args.quick_push (build_int_cst (integer_type_node, levels));
    8423         9665 :   args.quick_push (build_int_cst (integer_type_node, tag));
    8424         9665 :   if (gang_static)
    8425          146 :     args.quick_push (gang_static);
    8426              : 
    8427         9665 :   gcall *call = gimple_build_call_internal_vec (IFN_UNIQUE, args);
    8428         9665 :   gimple_set_location (call, loc);
    8429         9665 :   gimple_set_lhs (call, ddvar);
    8430         9665 :   gimple_seq_add_stmt (seq, call);
    8431              : 
    8432         9665 :   return levels;
    8433         9665 : }
    8434              : 
    8435              : /* Emit an OpenACC lopp head or tail marker to SEQ.  LEVEL is the
    8436              :    partitioning level of the enclosed region.  */
    8437              : 
    8438              : static void
    8439        42767 : lower_oacc_loop_marker (location_t loc, tree ddvar, bool head,
    8440              :                         tree tofollow, gimple_seq *seq)
    8441              : {
    8442        42767 :   int marker_kind = (head ? IFN_UNIQUE_OACC_HEAD_MARK
    8443              :                      : IFN_UNIQUE_OACC_TAIL_MARK);
    8444        42767 :   tree marker = build_int_cst (integer_type_node, marker_kind);
    8445        42767 :   int nargs = 2 + (tofollow != NULL_TREE);
    8446        42767 :   gcall *call = gimple_build_call_internal (IFN_UNIQUE, nargs,
    8447              :                                             marker, ddvar, tofollow);
    8448        42767 :   gimple_set_location (call, loc);
    8449        42767 :   gimple_set_lhs (call, ddvar);
    8450        42767 :   gimple_seq_add_stmt (seq, call);
    8451        42767 : }
    8452              : 
    8453              : /* Generate the before and after OpenACC loop sequences.  CLAUSES are
    8454              :    the loop clauses, from which we extract reductions.  Initialize
    8455              :    HEAD and TAIL.  */
    8456              : 
    8457              : static void
    8458         9665 : lower_oacc_head_tail (location_t loc, tree clauses, gcall *private_marker,
    8459              :                       gimple_seq *head, gimple_seq *tail, omp_context *ctx)
    8460              : {
    8461         9665 :   bool inner = false;
    8462         9665 :   tree ddvar = create_tmp_var (integer_type_node, ".data_dep");
    8463         9665 :   gimple_seq_add_stmt (head, gimple_build_assign (ddvar, integer_zero_node));
    8464              : 
    8465         9665 :   unsigned count = lower_oacc_head_mark (loc, ddvar, clauses, head, ctx);
    8466              : 
    8467         9665 :   if (private_marker)
    8468              :     {
    8469          229 :       gimple_set_location (private_marker, loc);
    8470          229 :       gimple_call_set_lhs (private_marker, ddvar);
    8471          229 :       gimple_call_set_arg (private_marker, 1, ddvar);
    8472              :     }
    8473              : 
    8474         9665 :   tree fork_kind = build_int_cst (unsigned_type_node, IFN_UNIQUE_OACC_FORK);
    8475         9665 :   tree join_kind = build_int_cst (unsigned_type_node, IFN_UNIQUE_OACC_JOIN);
    8476              : 
    8477         9665 :   gcc_assert (count);
    8478        26216 :   for (unsigned done = 1; count; count--, done++)
    8479              :     {
    8480        16551 :       gimple_seq fork_seq = NULL;
    8481        16551 :       gimple_seq join_seq = NULL;
    8482              : 
    8483        16551 :       tree place = build_int_cst (integer_type_node, -1);
    8484        16551 :       gcall *fork = gimple_build_call_internal (IFN_UNIQUE, 3,
    8485              :                                                 fork_kind, ddvar, place);
    8486        16551 :       gimple_set_location (fork, loc);
    8487        16551 :       gimple_set_lhs (fork, ddvar);
    8488              : 
    8489        16551 :       gcall *join = gimple_build_call_internal (IFN_UNIQUE, 3,
    8490              :                                                 join_kind, ddvar, place);
    8491        16551 :       gimple_set_location (join, loc);
    8492        16551 :       gimple_set_lhs (join, ddvar);
    8493              : 
    8494              :       /* Mark the beginning of this level sequence.  */
    8495        16551 :       if (inner)
    8496         6886 :         lower_oacc_loop_marker (loc, ddvar, true,
    8497         6886 :                                 build_int_cst (integer_type_node, count),
    8498              :                                 &fork_seq);
    8499        16551 :       lower_oacc_loop_marker (loc, ddvar, false,
    8500        16551 :                               build_int_cst (integer_type_node, done),
    8501              :                               &join_seq);
    8502              : 
    8503        23437 :       lower_oacc_reductions (loc, clauses, place, inner,
    8504              :                              fork, (count == 1) ? private_marker : NULL,
    8505              :                              join, &fork_seq, &join_seq,  ctx);
    8506              : 
    8507              :       /* Append this level to head. */
    8508        16551 :       gimple_seq_add_seq (head, fork_seq);
    8509              :       /* Prepend it to tail.  */
    8510        16551 :       gimple_seq_add_seq (&join_seq, *tail);
    8511        16551 :       *tail = join_seq;
    8512              : 
    8513        16551 :       inner = true;
    8514              :     }
    8515              : 
    8516              :   /* Mark the end of the sequence.  */
    8517         9665 :   lower_oacc_loop_marker (loc, ddvar, true, NULL_TREE, head);
    8518         9665 :   lower_oacc_loop_marker (loc, ddvar, false, NULL_TREE, tail);
    8519         9665 : }
    8520              : 
    8521              : /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
    8522              :    catch handler and return it.  This prevents programs from violating the
    8523              :    structured block semantics with throws.  */
    8524              : 
    8525              : static gimple_seq
    8526        94932 : maybe_catch_exception (gimple_seq body)
    8527              : {
    8528        94932 :   gimple *g;
    8529        94932 :   tree decl;
    8530              : 
    8531        94932 :   if (!flag_exceptions)
    8532              :     return body;
    8533              : 
    8534        42531 :   if (lang_hooks.eh_protect_cleanup_actions != NULL)
    8535        42503 :     decl = lang_hooks.eh_protect_cleanup_actions ();
    8536              :   else
    8537           28 :     decl = builtin_decl_explicit (BUILT_IN_TRAP);
    8538              : 
    8539        42531 :   g = gimple_build_eh_must_not_throw (decl);
    8540        42531 :   g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
    8541              :                         GIMPLE_TRY_CATCH);
    8542              : 
    8543        42531 :  return gimple_seq_alloc_with_stmt (g);
    8544              : }
    8545              : 
    8546              : 
    8547              : /* Routines to lower OMP directives into OMP-GIMPLE.  */
    8548              : 
    8549              : /* If ctx is a worksharing context inside of a cancellable parallel
    8550              :    region and it isn't nowait, add lhs to its GIMPLE_OMP_RETURN
    8551              :    and conditional branch to parallel's cancel_label to handle
    8552              :    cancellation in the implicit barrier.  */
    8553              : 
    8554              : static void
    8555        48518 : maybe_add_implicit_barrier_cancel (omp_context *ctx, gimple *omp_return,
    8556              :                                    gimple_seq *body)
    8557              : {
    8558        48518 :   gcc_assert (gimple_code (omp_return) == GIMPLE_OMP_RETURN);
    8559        48518 :   if (gimple_omp_return_nowait_p (omp_return))
    8560              :     return;
    8561        19559 :   for (omp_context *outer = ctx->outer; outer; outer = outer->outer)
    8562        16010 :     if (gimple_code (outer->stmt) == GIMPLE_OMP_PARALLEL
    8563        16010 :         && outer->cancellable)
    8564              :       {
    8565           64 :         tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
    8566           64 :         tree c_bool_type = TREE_TYPE (TREE_TYPE (fndecl));
    8567           64 :         tree lhs = create_tmp_var (c_bool_type);
    8568           64 :         gimple_omp_return_set_lhs (omp_return, lhs);
    8569           64 :         tree fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
    8570           64 :         gimple *g = gimple_build_cond (NE_EXPR, lhs,
    8571              :                                        fold_convert (c_bool_type,
    8572              :                                                      boolean_false_node),
    8573              :                                        outer->cancel_label, fallthru_label);
    8574           64 :         gimple_seq_add_stmt (body, g);
    8575           64 :         gimple_seq_add_stmt (body, gimple_build_label (fallthru_label));
    8576              :       }
    8577        15946 :     else if (gimple_code (outer->stmt) != GIMPLE_OMP_TASKGROUP
    8578        15946 :              && gimple_code (outer->stmt) != GIMPLE_OMP_SCOPE)
    8579              :       return;
    8580              : }
    8581              : 
    8582              : /* Find the first task_reduction or reduction clause or return NULL
    8583              :    if there are none.  */
    8584              : 
    8585              : static inline tree
    8586        48773 : omp_task_reductions_find_first (tree clauses, enum tree_code code,
    8587              :                                 enum omp_clause_code ccode)
    8588              : {
    8589        64091 :   while (1)
    8590              :     {
    8591        56432 :       clauses = omp_find_clause (clauses, ccode);
    8592        56432 :       if (clauses == NULL_TREE)
    8593              :         return NULL_TREE;
    8594         9105 :       if (ccode != OMP_CLAUSE_REDUCTION
    8595         9105 :           || code == OMP_TASKLOOP
    8596         9105 :           || OMP_CLAUSE_REDUCTION_TASK (clauses))
    8597              :         return clauses;
    8598         7659 :       clauses = OMP_CLAUSE_CHAIN (clauses);
    8599              :     }
    8600              : }
    8601              : 
    8602              : static void lower_omp_task_reductions (omp_context *, enum tree_code, tree,
    8603              :                                        gimple_seq *, gimple_seq *);
    8604              : 
    8605              : /* Lower the OpenMP sections directive in the current statement in GSI_P.
    8606              :    CTX is the enclosing OMP context for the current statement.  */
    8607              : 
    8608              : static void
    8609          378 : lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
    8610              : {
    8611          378 :   tree block, control;
    8612          378 :   gimple_stmt_iterator tgsi;
    8613          378 :   gomp_sections *stmt;
    8614          378 :   gimple *t;
    8615          378 :   gbind *new_stmt, *bind;
    8616          378 :   gimple_seq ilist, dlist, olist, tred_dlist = NULL, clist = NULL, new_body;
    8617              : 
    8618          378 :   stmt = as_a <gomp_sections *> (gsi_stmt (*gsi_p));
    8619              : 
    8620          378 :   push_gimplify_context ();
    8621              : 
    8622          378 :   dlist = NULL;
    8623          378 :   ilist = NULL;
    8624              : 
    8625          378 :   tree rclauses
    8626          378 :     = omp_task_reductions_find_first (gimple_omp_sections_clauses (stmt),
    8627              :                                       OMP_SECTIONS, OMP_CLAUSE_REDUCTION);
    8628          378 :   tree rtmp = NULL_TREE;
    8629          378 :   if (rclauses)
    8630              :     {
    8631            8 :       tree type = build_pointer_type (pointer_sized_int_node);
    8632            8 :       tree temp = create_tmp_var (type);
    8633            8 :       tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
    8634            8 :       OMP_CLAUSE_DECL (c) = temp;
    8635            8 :       OMP_CLAUSE_CHAIN (c) = gimple_omp_sections_clauses (stmt);
    8636            8 :       gimple_omp_sections_set_clauses (stmt, c);
    8637            8 :       lower_omp_task_reductions (ctx, OMP_SECTIONS,
    8638              :                                  gimple_omp_sections_clauses (stmt),
    8639              :                                  &ilist, &tred_dlist);
    8640            8 :       rclauses = c;
    8641            8 :       rtmp = make_ssa_name (type);
    8642            8 :       gimple_seq_add_stmt (&ilist, gimple_build_assign (rtmp, temp));
    8643              :     }
    8644              : 
    8645          378 :   tree *clauses_ptr = gimple_omp_sections_clauses_ptr (stmt);
    8646          378 :   lower_lastprivate_conditional_clauses (clauses_ptr, ctx);
    8647              : 
    8648          378 :   lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
    8649              :                            &ilist, &dlist, ctx, NULL);
    8650              : 
    8651          378 :   control = create_tmp_var (unsigned_type_node, ".section");
    8652          378 :   gimple_omp_sections_set_control (stmt, control);
    8653              : 
    8654          378 :   new_body = gimple_omp_body (stmt);
    8655          378 :   gimple_omp_set_body (stmt, NULL);
    8656          378 :   tgsi = gsi_start (new_body);
    8657         1233 :   for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
    8658              :     {
    8659          855 :       omp_context *sctx;
    8660          855 :       gimple *sec_start;
    8661              : 
    8662          855 :       sec_start = gsi_stmt (tgsi);
    8663          855 :       sctx = maybe_lookup_ctx (sec_start);
    8664          855 :       gcc_assert (sctx);
    8665              : 
    8666          855 :       lower_omp (gimple_omp_body_ptr (sec_start), sctx);
    8667          855 :       gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
    8668              :                             GSI_CONTINUE_LINKING);
    8669          855 :       gimple_omp_set_body (sec_start, NULL);
    8670              : 
    8671          855 :       if (gsi_one_before_end_p (tgsi))
    8672              :         {
    8673          378 :           gimple_seq l = NULL;
    8674          378 :           lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
    8675              :                                      &ilist, &l, &clist, ctx);
    8676          378 :           gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
    8677          378 :           gimple_omp_section_set_last (sec_start);
    8678              :         }
    8679              : 
    8680          855 :       gsi_insert_after (&tgsi, gimple_build_omp_return (false),
    8681              :                         GSI_CONTINUE_LINKING);
    8682              :     }
    8683              : 
    8684          378 :   block = make_node (BLOCK);
    8685          378 :   bind = gimple_build_bind (NULL, new_body, block);
    8686              : 
    8687          378 :   olist = NULL;
    8688          378 :   lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist,
    8689              :                            &clist, ctx);
    8690          378 :   if (clist)
    8691              :     {
    8692           10 :       tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
    8693           10 :       gcall *g = gimple_build_call (fndecl, 0);
    8694           10 :       gimple_seq_add_stmt (&olist, g);
    8695           10 :       gimple_seq_add_seq (&olist, clist);
    8696           10 :       fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
    8697           10 :       g = gimple_build_call (fndecl, 0);
    8698           10 :       gimple_seq_add_stmt (&olist, g);
    8699              :     }
    8700              : 
    8701          378 :   block = make_node (BLOCK);
    8702          378 :   new_stmt = gimple_build_bind (NULL, NULL, block);
    8703          378 :   gsi_replace (gsi_p, new_stmt, true);
    8704              : 
    8705          378 :   pop_gimplify_context (new_stmt);
    8706          378 :   gimple_bind_append_vars (new_stmt, ctx->block_vars);
    8707          378 :   BLOCK_VARS (block) = gimple_bind_vars (bind);
    8708          378 :   if (BLOCK_VARS (block))
    8709            0 :     TREE_USED (block) = 1;
    8710              : 
    8711          378 :   new_body = NULL;
    8712          378 :   gimple_seq_add_seq (&new_body, ilist);
    8713          378 :   gimple_seq_add_stmt (&new_body, stmt);
    8714          378 :   gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
    8715          378 :   gimple_seq_add_stmt (&new_body, bind);
    8716              : 
    8717          378 :   t = gimple_build_omp_continue (control, control);
    8718          378 :   gimple_seq_add_stmt (&new_body, t);
    8719              : 
    8720          378 :   gimple_seq_add_seq (&new_body, olist);
    8721          378 :   if (ctx->cancellable)
    8722           19 :     gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
    8723          378 :   gimple_seq_add_seq (&new_body, dlist);
    8724              : 
    8725          378 :   new_body = maybe_catch_exception (new_body);
    8726              : 
    8727          378 :   bool nowait = omp_find_clause (gimple_omp_sections_clauses (stmt),
    8728          378 :                                  OMP_CLAUSE_NOWAIT) != NULL_TREE;
    8729          378 :   t = gimple_build_omp_return (nowait);
    8730          378 :   gimple_seq_add_stmt (&new_body, t);
    8731          378 :   gimple_seq_add_seq (&new_body, tred_dlist);
    8732          378 :   maybe_add_implicit_barrier_cancel (ctx, t, &new_body);
    8733              : 
    8734          378 :   if (rclauses)
    8735            8 :     OMP_CLAUSE_DECL (rclauses) = rtmp;
    8736              : 
    8737          378 :   gimple_bind_set_body (new_stmt, new_body);
    8738          378 : }
    8739              : 
    8740              : 
    8741              : /* A subroutine of lower_omp_single.  Expand the simple form of
    8742              :    a GIMPLE_OMP_SINGLE, without a copyprivate clause:
    8743              : 
    8744              :         if (GOMP_single_start ())
    8745              :           BODY;
    8746              :         [ GOMP_barrier (); ]    -> unless 'nowait' is present.
    8747              : 
    8748              :   FIXME.  It may be better to delay expanding the logic of this until
    8749              :   pass_expand_omp.  The expanded logic may make the job more difficult
    8750              :   to a synchronization analysis pass.  */
    8751              : 
    8752              : static void
    8753         1004 : lower_omp_single_simple (gomp_single *single_stmt, gimple_seq *pre_p)
    8754              : {
    8755         1004 :   location_t loc = gimple_location (single_stmt);
    8756         1004 :   tree tlabel = create_artificial_label (loc);
    8757         1004 :   tree flabel = create_artificial_label (loc);
    8758         1004 :   gimple *call, *cond;
    8759         1004 :   tree lhs, decl;
    8760              : 
    8761         1004 :   decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
    8762         1004 :   lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)));
    8763         1004 :   call = gimple_build_call (decl, 0);
    8764         1004 :   gimple_call_set_lhs (call, lhs);
    8765         1004 :   gimple_seq_add_stmt (pre_p, call);
    8766              : 
    8767         1004 :   cond = gimple_build_cond (EQ_EXPR, lhs,
    8768         1004 :                             fold_convert_loc (loc, TREE_TYPE (lhs),
    8769              :                                               boolean_true_node),
    8770              :                             tlabel, flabel);
    8771         1004 :   gimple_seq_add_stmt (pre_p, cond);
    8772         1004 :   gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
    8773         1004 :   gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
    8774         1004 :   gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
    8775         1004 : }
    8776              : 
    8777              : 
    8778              : /* A subroutine of lower_omp_single.  Expand the simple form of
    8779              :    a GIMPLE_OMP_SINGLE, with a copyprivate clause:
    8780              : 
    8781              :         #pragma omp single copyprivate (a, b, c)
    8782              : 
    8783              :    Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
    8784              : 
    8785              :       {
    8786              :         if ((copyout_p = GOMP_single_copy_start ()) == NULL)
    8787              :           {
    8788              :             BODY;
    8789              :             copyout.a = a;
    8790              :             copyout.b = b;
    8791              :             copyout.c = c;
    8792              :             GOMP_single_copy_end (&copyout);
    8793              :           }
    8794              :         else
    8795              :           {
    8796              :             a = copyout_p->a;
    8797              :             b = copyout_p->b;
    8798              :             c = copyout_p->c;
    8799              :           }
    8800              :         GOMP_barrier ();
    8801              :       }
    8802              : 
    8803              :   FIXME.  It may be better to delay expanding the logic of this until
    8804              :   pass_expand_omp.  The expanded logic may make the job more difficult
    8805              :   to a synchronization analysis pass.  */
    8806              : 
    8807              : static void
    8808          115 : lower_omp_single_copy (gomp_single *single_stmt, gimple_seq *pre_p,
    8809              :                        omp_context *ctx)
    8810              : {
    8811          115 :   tree ptr_type, t, l0, l1, l2, bfn_decl;
    8812          115 :   gimple_seq copyin_seq;
    8813          115 :   location_t loc = gimple_location (single_stmt);
    8814              : 
    8815          115 :   ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
    8816              : 
    8817          115 :   ptr_type = build_pointer_type (ctx->record_type);
    8818          115 :   ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
    8819              : 
    8820          115 :   l0 = create_artificial_label (loc);
    8821          115 :   l1 = create_artificial_label (loc);
    8822          115 :   l2 = create_artificial_label (loc);
    8823              : 
    8824          115 :   bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
    8825          115 :   t = build_call_expr_loc (loc, bfn_decl, 0);
    8826          115 :   t = fold_convert_loc (loc, ptr_type, t);
    8827          115 :   gimplify_assign (ctx->receiver_decl, t, pre_p);
    8828              : 
    8829          115 :   t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
    8830              :               build_int_cst (ptr_type, 0));
    8831          115 :   t = build3 (COND_EXPR, void_type_node, t,
    8832              :               build_and_jump (&l0), build_and_jump (&l1));
    8833          115 :   gimplify_and_add (t, pre_p);
    8834              : 
    8835          115 :   gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
    8836              : 
    8837          115 :   gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
    8838              : 
    8839          115 :   copyin_seq = NULL;
    8840          115 :   lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
    8841              :                               &copyin_seq, ctx);
    8842              : 
    8843          115 :   t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
    8844          115 :   bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
    8845          115 :   t = build_call_expr_loc (loc, bfn_decl, 1, t);
    8846          115 :   gimplify_and_add (t, pre_p);
    8847              : 
    8848          115 :   t = build_and_jump (&l2);
    8849          115 :   gimplify_and_add (t, pre_p);
    8850              : 
    8851          115 :   gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
    8852              : 
    8853          115 :   gimple_seq_add_seq (pre_p, copyin_seq);
    8854              : 
    8855          115 :   gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
    8856          115 : }
    8857              : 
    8858              : 
    8859              : /* Expand code for an OpenMP single directive.  */
    8860              : 
    8861              : static void
    8862         1119 : lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
    8863              : {
    8864         1119 :   tree block;
    8865         1119 :   gomp_single *single_stmt = as_a <gomp_single *> (gsi_stmt (*gsi_p));
    8866         1119 :   gbind *bind;
    8867         1119 :   gimple_seq bind_body, bind_body_tail = NULL, dlist;
    8868              : 
    8869         1119 :   push_gimplify_context ();
    8870              : 
    8871         1119 :   block = make_node (BLOCK);
    8872         1119 :   bind = gimple_build_bind (NULL, NULL, block);
    8873         1119 :   gsi_replace (gsi_p, bind, true);
    8874         1119 :   bind_body = NULL;
    8875         1119 :   dlist = NULL;
    8876         1119 :   lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
    8877              :                            &bind_body, &dlist, ctx, NULL);
    8878         1119 :   lower_omp (gimple_omp_body_ptr (single_stmt), ctx);
    8879              : 
    8880         1119 :   gimple_seq_add_stmt (&bind_body, single_stmt);
    8881              : 
    8882         1119 :   if (ctx->record_type)
    8883          115 :     lower_omp_single_copy (single_stmt, &bind_body, ctx);
    8884              :   else
    8885         1004 :     lower_omp_single_simple (single_stmt, &bind_body);
    8886              : 
    8887         1119 :   gimple_omp_set_body (single_stmt, NULL);
    8888              : 
    8889         1119 :   gimple_seq_add_seq (&bind_body, dlist);
    8890              : 
    8891         1119 :   bind_body = maybe_catch_exception (bind_body);
    8892              : 
    8893         1119 :   bool nowait = omp_find_clause (gimple_omp_single_clauses (single_stmt),
    8894         1119 :                                  OMP_CLAUSE_NOWAIT) != NULL_TREE;
    8895         1119 :   gimple *g = gimple_build_omp_return (nowait);
    8896         1119 :   gimple_seq_add_stmt (&bind_body_tail, g);
    8897         1119 :   maybe_add_implicit_barrier_cancel (ctx, g, &bind_body_tail);
    8898         1119 :   if (ctx->record_type)
    8899              :     {
    8900          115 :       gimple_stmt_iterator gsi = gsi_start (bind_body_tail);
    8901          115 :       tree clobber = build_clobber (ctx->record_type);
    8902          115 :       gsi_insert_after (&gsi, gimple_build_assign (ctx->sender_decl,
    8903              :                                                    clobber), GSI_SAME_STMT);
    8904              :     }
    8905         1119 :   gimple_seq_add_seq (&bind_body, bind_body_tail);
    8906         1119 :   gimple_bind_set_body (bind, bind_body);
    8907              : 
    8908         1119 :   pop_gimplify_context (bind);
    8909              : 
    8910         1119 :   gimple_bind_append_vars (bind, ctx->block_vars);
    8911         1119 :   BLOCK_VARS (block) = ctx->block_vars;
    8912         1119 :   if (BLOCK_VARS (block))
    8913           26 :     TREE_USED (block) = 1;
    8914         1119 : }
    8915              : 
    8916              : 
    8917              : /* Lower code for an OMP scope directive.  */
    8918              : 
    8919              : static void
    8920          133 : lower_omp_scope (gimple_stmt_iterator *gsi_p, omp_context *ctx)
    8921              : {
    8922          133 :   tree block;
    8923          133 :   gimple *scope_stmt = gsi_stmt (*gsi_p);
    8924          133 :   gbind *bind;
    8925          133 :   gimple_seq bind_body, bind_body_tail = NULL, dlist;
    8926          133 :   gimple_seq tred_dlist = NULL;
    8927              : 
    8928          133 :   push_gimplify_context ();
    8929              : 
    8930          133 :   block = make_node (BLOCK);
    8931          133 :   bind = gimple_build_bind (NULL, NULL, block);
    8932          133 :   gsi_replace (gsi_p, bind, true);
    8933          133 :   bind_body = NULL;
    8934          133 :   dlist = NULL;
    8935              : 
    8936          133 :   tree rclauses
    8937          133 :     = omp_task_reductions_find_first (gimple_omp_scope_clauses (scope_stmt),
    8938              :                                       OMP_SCOPE, OMP_CLAUSE_REDUCTION);
    8939          133 :   if (rclauses)
    8940              :     {
    8941           46 :       tree type = build_pointer_type (pointer_sized_int_node);
    8942           46 :       tree temp = create_tmp_var (type);
    8943           46 :       tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
    8944           46 :       OMP_CLAUSE_DECL (c) = temp;
    8945           46 :       OMP_CLAUSE_CHAIN (c) = gimple_omp_scope_clauses (scope_stmt);
    8946           46 :       gimple_omp_scope_set_clauses (scope_stmt, c);
    8947           46 :       lower_omp_task_reductions (ctx, OMP_SCOPE,
    8948              :                                  gimple_omp_scope_clauses (scope_stmt),
    8949              :                                  &bind_body, &tred_dlist);
    8950           46 :       rclauses = c;
    8951           46 :       tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_SCOPE_START);
    8952           46 :       gimple *stmt = gimple_build_call (fndecl, 1, temp);
    8953           46 :       gimple_seq_add_stmt (&bind_body, stmt);
    8954              :     }
    8955              : 
    8956          133 :   lower_rec_input_clauses (gimple_omp_scope_clauses (scope_stmt),
    8957              :                            &bind_body, &dlist, ctx, NULL);
    8958          133 :   lower_omp (gimple_omp_body_ptr (scope_stmt), ctx);
    8959              : 
    8960          133 :   gimple_seq_add_stmt (&bind_body, scope_stmt);
    8961              : 
    8962          133 :   gimple_seq_add_seq (&bind_body, gimple_omp_body (scope_stmt));
    8963              : 
    8964          133 :   gimple_omp_set_body (scope_stmt, NULL);
    8965              : 
    8966          133 :   gimple_seq clist = NULL;
    8967          133 :   lower_reduction_clauses (gimple_omp_scope_clauses (scope_stmt),
    8968              :                            &bind_body, &clist, ctx);
    8969          133 :   if (clist)
    8970              :     {
    8971            0 :       tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
    8972            0 :       gcall *g = gimple_build_call (fndecl, 0);
    8973            0 :       gimple_seq_add_stmt (&bind_body, g);
    8974            0 :       gimple_seq_add_seq (&bind_body, clist);
    8975            0 :       fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
    8976            0 :       g = gimple_build_call (fndecl, 0);
    8977            0 :       gimple_seq_add_stmt (&bind_body, g);
    8978              :     }
    8979              : 
    8980          133 :   gimple_seq_add_seq (&bind_body, dlist);
    8981              : 
    8982          133 :   bind_body = maybe_catch_exception (bind_body);
    8983              : 
    8984          133 :   bool nowait = omp_find_clause (gimple_omp_scope_clauses (scope_stmt),
    8985          133 :                                  OMP_CLAUSE_NOWAIT) != NULL_TREE;
    8986          133 :   gimple *g = gimple_build_omp_return (nowait);
    8987          133 :   gimple_seq_add_stmt (&bind_body_tail, g);
    8988          133 :   gimple_seq_add_seq (&bind_body_tail, tred_dlist);
    8989          133 :   maybe_add_implicit_barrier_cancel (ctx, g, &bind_body_tail);
    8990          133 :   if (ctx->record_type)
    8991              :     {
    8992            0 :       gimple_stmt_iterator gsi = gsi_start (bind_body_tail);
    8993            0 :       tree clobber = build_clobber (ctx->record_type);
    8994            0 :       gsi_insert_after (&gsi, gimple_build_assign (ctx->sender_decl,
    8995              :                                                    clobber), GSI_SAME_STMT);
    8996              :     }
    8997          133 :   gimple_seq_add_seq (&bind_body, bind_body_tail);
    8998              : 
    8999          133 :   gimple_bind_set_body (bind, bind_body);
    9000              : 
    9001          133 :   pop_gimplify_context (bind);
    9002              : 
    9003          133 :   gimple_bind_append_vars (bind, ctx->block_vars);
    9004          133 :   BLOCK_VARS (block) = ctx->block_vars;
    9005          133 :   if (BLOCK_VARS (block))
    9006          105 :     TREE_USED (block) = 1;
    9007          133 : }
    9008              : 
    9009              : /* Lower code for an OMP dispatch directive.  */
    9010              : 
    9011              : static void
    9012          659 : lower_omp_dispatch (gimple_stmt_iterator *gsi_p, omp_context *ctx)
    9013              : {
    9014          659 :   tree block;
    9015          659 :   gimple *stmt = gsi_stmt (*gsi_p);
    9016          659 :   gbind *bind;
    9017              : 
    9018          659 :   push_gimplify_context ();
    9019              : 
    9020          659 :   block = make_node (BLOCK);
    9021          659 :   bind = gimple_build_bind (NULL, NULL, block);
    9022          659 :   gsi_replace (gsi_p, bind, true);
    9023              : 
    9024          659 :   lower_omp (gimple_omp_body_ptr (stmt), ctx);
    9025          659 :   gimple_bind_set_body (bind, maybe_catch_exception (gimple_omp_body (stmt)));
    9026              : 
    9027          659 :   pop_gimplify_context (bind);
    9028              : 
    9029          659 :   gimple_bind_append_vars (bind, ctx->block_vars);
    9030          659 :   BLOCK_VARS (block) = ctx->block_vars;
    9031          659 : }
    9032              : 
    9033              : /* Expand code for an OpenMP master or masked directive.  */
    9034              : 
    9035              : static void
    9036         1108 : lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
    9037              : {
    9038         1108 :   tree block, lab = NULL, x, bfn_decl;
    9039         1108 :   gimple *stmt = gsi_stmt (*gsi_p);
    9040         1108 :   gbind *bind;
    9041         1108 :   location_t loc = gimple_location (stmt);
    9042         1108 :   gimple_seq tseq;
    9043         1108 :   tree filter = integer_zero_node;
    9044              : 
    9045         1108 :   push_gimplify_context ();
    9046              : 
    9047         1108 :   if (gimple_code (stmt) == GIMPLE_OMP_MASKED)
    9048              :     {
    9049          377 :       filter = omp_find_clause (gimple_omp_masked_clauses (stmt),
    9050              :                                 OMP_CLAUSE_FILTER);
    9051          377 :       if (filter)
    9052          252 :         filter = fold_convert (integer_type_node,
    9053              :                                OMP_CLAUSE_FILTER_EXPR (filter));
    9054              :       else
    9055          125 :         filter = integer_zero_node;
    9056              :     }
    9057         1108 :   block = make_node (BLOCK);
    9058         1108 :   bind = gimple_build_bind (NULL, NULL, block);
    9059         1108 :   gsi_replace (gsi_p, bind, true);
    9060         1108 :   gimple_bind_add_stmt (bind, stmt);
    9061              : 
    9062         1108 :   bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
    9063         1108 :   x = build_call_expr_loc (loc, bfn_decl, 0);
    9064         1108 :   x = build2 (EQ_EXPR, boolean_type_node, x, filter);
    9065         1108 :   x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
    9066         1108 :   tseq = NULL;
    9067         1108 :   gimplify_and_add (x, &tseq);
    9068         1108 :   gimple_bind_add_seq (bind, tseq);
    9069              : 
    9070         1108 :   lower_omp (gimple_omp_body_ptr (stmt), ctx);
    9071         1108 :   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
    9072         1108 :   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
    9073         1108 :   gimple_omp_set_body (stmt, NULL);
    9074              : 
    9075         1108 :   gimple_bind_add_stmt (bind, gimple_build_label (lab));
    9076              : 
    9077         1108 :   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
    9078              : 
    9079         1108 :   pop_gimplify_context (bind);
    9080              : 
    9081         1108 :   gimple_bind_append_vars (bind, ctx->block_vars);
    9082         1108 :   BLOCK_VARS (block) = ctx->block_vars;
    9083         1108 : }
    9084              : 
    9085              : /* Helper function for lower_omp_task_reductions.  For a specific PASS
    9086              :    find out the current clause it should be processed, or return false
    9087              :    if all have been processed already.  */
    9088              : 
    9089              : static inline bool
    9090         7952 : omp_task_reduction_iterate (int pass, enum tree_code code,
    9091              :                             enum omp_clause_code ccode, tree *c, tree *decl,
    9092              :                             tree *type, tree *next)
    9093              : {
    9094        11300 :   for (; *c; *c = omp_find_clause (OMP_CLAUSE_CHAIN (*c), ccode))
    9095              :     {
    9096         6696 :       if (ccode == OMP_CLAUSE_REDUCTION
    9097         6640 :           && code != OMP_TASKLOOP
    9098         6640 :           && !OMP_CLAUSE_REDUCTION_TASK (*c))
    9099           56 :         continue;
    9100         6584 :       *decl = OMP_CLAUSE_DECL (*c);
    9101         6584 :       *type = TREE_TYPE (*decl);
    9102         6584 :       if (TREE_CODE (*decl) == MEM_REF)
    9103              :         {
    9104         1940 :           if (pass != 1)
    9105          970 :             continue;
    9106              :         }
    9107              :       else
    9108              :         {
    9109         4644 :           if (omp_privatize_by_reference (*decl))
    9110          152 :             *type = TREE_TYPE (*type);
    9111         4644 :           if (pass != (!TREE_CONSTANT (TYPE_SIZE_UNIT (*type))))
    9112         2322 :             continue;
    9113              :         }
    9114         3292 :       *next = omp_find_clause (OMP_CLAUSE_CHAIN (*c), ccode);
    9115         3292 :       return true;
    9116              :     }
    9117         4660 :   *decl = NULL_TREE;
    9118         4660 :   *type = NULL_TREE;
    9119         4660 :   *next = NULL_TREE;
    9120         4660 :   return false;
    9121              : }
    9122              : 
    9123              : /* Lower task_reduction and reduction clauses (the latter unless CODE is
    9124              :    OMP_TASKGROUP only with task modifier).  Register mapping of those in
    9125              :    START sequence and reducing them and unregister them in the END sequence.  */
    9126              : 
    9127              : static void
    9128         1374 : lower_omp_task_reductions (omp_context *ctx, enum tree_code code, tree clauses,
    9129              :                            gimple_seq *start, gimple_seq *end)
    9130              : {
    9131          838 :   enum omp_clause_code ccode
    9132              :     = (code == OMP_TASKGROUP
    9133         1374 :        ? OMP_CLAUSE_TASK_REDUCTION : OMP_CLAUSE_REDUCTION);
    9134         1374 :   tree cancellable = NULL_TREE;
    9135         1374 :   clauses = omp_task_reductions_find_first (clauses, code, ccode);
    9136         1374 :   if (clauses == NULL_TREE)
    9137          209 :     return;
    9138         1165 :   if (code == OMP_FOR || code == OMP_SECTIONS || code == OMP_SCOPE)
    9139              :     {
    9140          316 :       for (omp_context *outer = ctx->outer; outer; outer = outer->outer)
    9141          238 :         if (gimple_code (outer->stmt) == GIMPLE_OMP_PARALLEL
    9142          238 :             && outer->cancellable)
    9143              :           {
    9144           14 :             cancellable = error_mark_node;
    9145           14 :             break;
    9146              :           }
    9147          224 :         else if (gimple_code (outer->stmt) != GIMPLE_OMP_TASKGROUP
    9148          224 :                  && gimple_code (outer->stmt) != GIMPLE_OMP_SCOPE)
    9149              :           break;
    9150              :     }
    9151         1165 :   tree record_type = lang_hooks.types.make_type (RECORD_TYPE);
    9152         1165 :   tree *last = &TYPE_FIELDS (record_type);
    9153         1165 :   unsigned cnt = 0;
    9154         1165 :   if (cancellable)
    9155              :     {
    9156           14 :       tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
    9157              :                                ptr_type_node);
    9158           14 :       tree ifield = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
    9159              :                                 integer_type_node);
    9160           14 :       *last = field;
    9161           14 :       DECL_CHAIN (field) = ifield;
    9162           14 :       last = &DECL_CHAIN (ifield);
    9163           14 :       DECL_CONTEXT (field) = record_type;
    9164           14 :       if (TYPE_ALIGN (record_type) < DECL_ALIGN (field))
    9165            0 :         SET_TYPE_ALIGN (record_type, DECL_ALIGN (field));
    9166           14 :       DECL_CONTEXT (ifield) = record_type;
    9167           14 :       if (TYPE_ALIGN (record_type) < DECL_ALIGN (ifield))
    9168            0 :         SET_TYPE_ALIGN (record_type, DECL_ALIGN (ifield));
    9169              :     }
    9170         3495 :   for (int pass = 0; pass < 2; pass++)
    9171              :     {
    9172         2330 :       tree decl, type, next;
    9173         2330 :       for (tree c = clauses;
    9174         3976 :            omp_task_reduction_iterate (pass, code, ccode,
    9175         1646 :                                        &c, &decl, &type, &next); c = next)
    9176              :         {
    9177         1646 :           ++cnt;
    9178         1646 :           tree new_type = type;
    9179         1646 :           if (ctx->outer)
    9180         1165 :             new_type = remap_type (type, &ctx->outer->cb);
    9181         1646 :           tree field
    9182         1646 :             = build_decl (OMP_CLAUSE_LOCATION (c), FIELD_DECL,
    9183         1646 :                           DECL_P (decl) ? DECL_NAME (decl) : NULL_TREE,
    9184              :                           new_type);
    9185         1646 :           if (DECL_P (decl) && type == TREE_TYPE (decl))
    9186              :             {
    9187         1123 :               SET_DECL_ALIGN (field, DECL_ALIGN (decl));
    9188         1123 :               DECL_USER_ALIGN (field) = DECL_USER_ALIGN (decl);
    9189         1123 :               TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (decl);
    9190              :             }
    9191              :           else
    9192          523 :             SET_DECL_ALIGN (field, TYPE_ALIGN (type));
    9193         1646 :           DECL_CONTEXT (field) = record_type;
    9194         1646 :           if (TYPE_ALIGN (record_type) < DECL_ALIGN (field))
    9195         1187 :             SET_TYPE_ALIGN (record_type, DECL_ALIGN (field));
    9196         1646 :           *last = field;
    9197         1646 :           last = &DECL_CHAIN (field);
    9198         1646 :           tree bfield
    9199         1646 :             = build_decl (OMP_CLAUSE_LOCATION (c), FIELD_DECL, NULL_TREE,
    9200              :                           boolean_type_node);
    9201         1646 :           DECL_CONTEXT (bfield) = record_type;
    9202         1646 :           if (TYPE_ALIGN (record_type) < DECL_ALIGN (bfield))
    9203            0 :             SET_TYPE_ALIGN (record_type, DECL_ALIGN (bfield));
    9204         1646 :           *last = bfield;
    9205         1646 :           last = &DECL_CHAIN (bfield);
    9206              :         }
    9207              :     }
    9208         1165 :   *last = NULL_TREE;
    9209         1165 :   layout_type (record_type);
    9210              : 
    9211              :   /* Build up an array which registers with the runtime all the reductions
    9212              :      and deregisters them at the end.  Format documented in libgomp/task.c.  */
    9213         1165 :   tree atype = build_array_type_nelts (pointer_sized_int_node, 7 + cnt * 3);
    9214         1165 :   tree avar = create_tmp_var_raw (atype);
    9215         1165 :   gimple_add_tmp_var (avar);
    9216         1165 :   TREE_ADDRESSABLE (avar) = 1;
    9217         1165 :   tree r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_zero_node,
    9218              :                    NULL_TREE, NULL_TREE);
    9219         1165 :   tree t = build_int_cst (pointer_sized_int_node, cnt);
    9220         1165 :   gimple_seq_add_stmt (start, gimple_build_assign (r, t));
    9221         1165 :   gimple_seq seq = NULL;
    9222         1165 :   tree sz = fold_convert (pointer_sized_int_node,
    9223              :                           TYPE_SIZE_UNIT (record_type));
    9224         1165 :   int cachesz = 64;
    9225         1165 :   sz = fold_build2 (PLUS_EXPR, pointer_sized_int_node, sz,
    9226              :                     build_int_cst (pointer_sized_int_node, cachesz - 1));
    9227         1165 :   sz = fold_build2 (BIT_AND_EXPR, pointer_sized_int_node, sz,
    9228              :                     build_int_cst (pointer_sized_int_node, ~(cachesz - 1)));
    9229         1165 :   ctx->task_reductions.create (1 + cnt);
    9230         1165 :   ctx->task_reduction_map = new hash_map<tree, unsigned>;
    9231         2330 :   ctx->task_reductions.quick_push (TREE_CODE (sz) == INTEGER_CST
    9232         1205 :                                    ? sz : NULL_TREE);
    9233         1165 :   sz = force_gimple_operand (sz, &seq, true, NULL_TREE);
    9234         1165 :   gimple_seq_add_seq (start, seq);
    9235         1165 :   r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_one_node,
    9236              :               NULL_TREE, NULL_TREE);
    9237         1165 :   gimple_seq_add_stmt (start, gimple_build_assign (r, sz));
    9238         1165 :   r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_int (2),
    9239              :               NULL_TREE, NULL_TREE);
    9240         1165 :   t = build_int_cst (pointer_sized_int_node,
    9241         1165 :                      MAX (TYPE_ALIGN_UNIT (record_type), (unsigned) cachesz));
    9242         1165 :   gimple_seq_add_stmt (start, gimple_build_assign (r, t));
    9243         1165 :   r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_int (3),
    9244              :               NULL_TREE, NULL_TREE);
    9245         1165 :   t = build_int_cst (pointer_sized_int_node, -1);
    9246         1165 :   gimple_seq_add_stmt (start, gimple_build_assign (r, t));
    9247         1165 :   r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_int (4),
    9248              :               NULL_TREE, NULL_TREE);
    9249         1165 :   t = build_int_cst (pointer_sized_int_node, 0);
    9250         1165 :   gimple_seq_add_stmt (start, gimple_build_assign (r, t));
    9251              : 
    9252              :   /* In end, build a loop that iterates from 0 to < omp_get_num_threads ()
    9253              :      and for each task reduction checks a bool right after the private variable
    9254              :      within that thread's chunk; if the bool is clear, it hasn't been
    9255              :      initialized and thus isn't going to be reduced nor destructed, otherwise
    9256              :      reduce and destruct it.  */
    9257         1165 :   tree idx = create_tmp_var (size_type_node);
    9258         1165 :   gimple_seq_add_stmt (end, gimple_build_assign (idx, size_zero_node));
    9259         1165 :   tree num_thr_sz = create_tmp_var (size_type_node);
    9260         1165 :   tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
    9261         1165 :   tree lab2 = create_artificial_label (UNKNOWN_LOCATION);
    9262         1165 :   tree lab3 = NULL_TREE, lab7 = NULL_TREE;
    9263         1165 :   gimple *g;
    9264         1165 :   if (code == OMP_FOR || code == OMP_SECTIONS || code == OMP_SCOPE)
    9265              :     {
    9266              :       /* For worksharing constructs or scope, only perform it in the master
    9267              :          thread, with the exception of cancelled implicit barriers - then only
    9268              :          handle the current thread.  */
    9269          281 :       tree lab4 = create_artificial_label (UNKNOWN_LOCATION);
    9270          281 :       t = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
    9271          281 :       tree thr_num = create_tmp_var (integer_type_node);
    9272          281 :       g = gimple_build_call (t, 0);
    9273          281 :       gimple_call_set_lhs (g, thr_num);
    9274          281 :       gimple_seq_add_stmt (end, g);
    9275          281 :       if (cancellable)
    9276              :         {
    9277           14 :           tree c;
    9278           14 :           tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
    9279           14 :           tree lab6 = create_artificial_label (UNKNOWN_LOCATION);
    9280           14 :           lab3 = create_artificial_label (UNKNOWN_LOCATION);
    9281           14 :           if (code == OMP_FOR)
    9282            4 :             c = gimple_omp_for_clauses (ctx->stmt);
    9283           10 :           else if (code == OMP_SECTIONS)
    9284            0 :             c = gimple_omp_sections_clauses (ctx->stmt);
    9285              :           else /* if (code == OMP_SCOPE) */
    9286           10 :             c = gimple_omp_scope_clauses (ctx->stmt);
    9287           14 :           c = OMP_CLAUSE_DECL (omp_find_clause (c, OMP_CLAUSE__REDUCTEMP_));
    9288           14 :           cancellable = c;
    9289           14 :           g = gimple_build_cond (NE_EXPR, c, build_zero_cst (TREE_TYPE (c)),
    9290              :                                  lab5, lab6);
    9291           14 :           gimple_seq_add_stmt (end, g);
    9292           14 :           gimple_seq_add_stmt (end, gimple_build_label (lab5));
    9293           14 :           g = gimple_build_assign (idx, NOP_EXPR, thr_num);
    9294           14 :           gimple_seq_add_stmt (end, g);
    9295           14 :           g = gimple_build_assign (num_thr_sz, PLUS_EXPR, idx,
    9296           14 :                                    build_one_cst (TREE_TYPE (idx)));
    9297           14 :           gimple_seq_add_stmt (end, g);
    9298           14 :           gimple_seq_add_stmt (end, gimple_build_goto (lab3));
    9299           14 :           gimple_seq_add_stmt (end, gimple_build_label (lab6));
    9300              :         }
    9301          281 :       g = gimple_build_cond (NE_EXPR, thr_num, integer_zero_node, lab2, lab4);
    9302          281 :       gimple_seq_add_stmt (end, g);
    9303          281 :       gimple_seq_add_stmt (end, gimple_build_label (lab4));
    9304              :     }
    9305         1165 :   if (code != OMP_PARALLEL)
    9306              :     {
    9307         1105 :       t = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
    9308         1105 :       tree num_thr = create_tmp_var (integer_type_node);
    9309         1105 :       g = gimple_build_call (t, 0);
    9310         1105 :       gimple_call_set_lhs (g, num_thr);
    9311         1105 :       gimple_seq_add_stmt (end, g);
    9312         1105 :       g = gimple_build_assign (num_thr_sz, NOP_EXPR, num_thr);
    9313         1105 :       gimple_seq_add_stmt (end, g);
    9314         1105 :       if (cancellable)
    9315           14 :         gimple_seq_add_stmt (end, gimple_build_label (lab3));
    9316              :     }
    9317              :   else
    9318              :     {
    9319           60 :       tree c = omp_find_clause (gimple_omp_parallel_clauses (ctx->stmt),
    9320              :                                 OMP_CLAUSE__REDUCTEMP_);
    9321           60 :       t = fold_convert (pointer_sized_int_node, OMP_CLAUSE_DECL (c));
    9322           60 :       t = fold_convert (size_type_node, t);
    9323           60 :       gimplify_assign (num_thr_sz, t, end);
    9324              :     }
    9325         1165 :   t = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_int (2),
    9326              :               NULL_TREE, NULL_TREE);
    9327         1165 :   tree data = create_tmp_var (pointer_sized_int_node);
    9328         1165 :   gimple_seq_add_stmt (end, gimple_build_assign (data, t));
    9329         1165 :   if (code == OMP_TASKLOOP)
    9330              :     {
    9331          497 :       lab7 = create_artificial_label (UNKNOWN_LOCATION);
    9332          497 :       g = gimple_build_cond (NE_EXPR, data,
    9333              :                              build_zero_cst (pointer_sized_int_node),
    9334              :                              lab1, lab7);
    9335          497 :       gimple_seq_add_stmt (end, g);
    9336              :     }
    9337         1165 :   gimple_seq_add_stmt (end, gimple_build_label (lab1));
    9338         1165 :   tree ptr;
    9339         1165 :   if (TREE_CODE (TYPE_SIZE_UNIT (record_type)) == INTEGER_CST)
    9340         1125 :     ptr = create_tmp_var (build_pointer_type (record_type));
    9341              :   else
    9342           40 :     ptr = create_tmp_var (ptr_type_node);
    9343         1165 :   gimple_seq_add_stmt (end, gimple_build_assign (ptr, NOP_EXPR, data));
    9344              : 
    9345         1165 :   tree field = TYPE_FIELDS (record_type);
    9346         1165 :   cnt = 0;
    9347         1165 :   if (cancellable)
    9348           14 :     field = DECL_CHAIN (DECL_CHAIN (field));
    9349         3495 :   for (int pass = 0; pass < 2; pass++)
    9350              :     {
    9351         2330 :       tree decl, type, next;
    9352         2330 :       for (tree c = clauses;
    9353         3976 :            omp_task_reduction_iterate (pass, code, ccode,
    9354         1646 :                                        &c, &decl, &type, &next); c = next)
    9355              :         {
    9356         1646 :           tree var = decl, ref;
    9357         1646 :           if (TREE_CODE (decl) == MEM_REF)
    9358              :             {
    9359          485 :               var = TREE_OPERAND (var, 0);
    9360          485 :               if (TREE_CODE (var) == POINTER_PLUS_EXPR)
    9361          108 :                 var = TREE_OPERAND (var, 0);
    9362          485 :               tree v = var;
    9363          485 :               if (TREE_CODE (var) == ADDR_EXPR)
    9364          310 :                 var = TREE_OPERAND (var, 0);
    9365          175 :               else if (INDIRECT_REF_P (var))
    9366            4 :                 var = TREE_OPERAND (var, 0);
    9367          485 :               tree orig_var = var;
    9368          485 :               if (is_variable_sized (var))
    9369              :                 {
    9370           31 :                   gcc_assert (DECL_HAS_VALUE_EXPR_P (var));
    9371           31 :                   var = DECL_VALUE_EXPR (var);
    9372           31 :                   gcc_assert (INDIRECT_REF_P (var));
    9373           31 :                   var = TREE_OPERAND (var, 0);
    9374           31 :                   gcc_assert (DECL_P (var));
    9375              :                 }
    9376          485 :               t = ref = maybe_lookup_decl_in_outer_ctx (var, ctx);
    9377          485 :               if (orig_var != var)
    9378           31 :                 gcc_assert (TREE_CODE (v) == ADDR_EXPR);
    9379          454 :               else if (TREE_CODE (v) == ADDR_EXPR)
    9380          279 :                 t = build_fold_addr_expr (t);
    9381          175 :               else if (INDIRECT_REF_P (v))
    9382            4 :                 t = build_fold_indirect_ref (t);
    9383          485 :               if (TREE_CODE (TREE_OPERAND (decl, 0)) == POINTER_PLUS_EXPR)
    9384              :                 {
    9385          108 :                   tree b = TREE_OPERAND (TREE_OPERAND (decl, 0), 1);
    9386          108 :                   b = maybe_lookup_decl_in_outer_ctx (b, ctx);
    9387          108 :                   t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, b);
    9388              :                 }
    9389          485 :               if (!integer_zerop (TREE_OPERAND (decl, 1)))
    9390          219 :                 t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t,
    9391              :                                  fold_convert (size_type_node,
    9392              :                                                TREE_OPERAND (decl, 1)));
    9393              :             }
    9394              :           else
    9395              :             {
    9396         1161 :               t = ref = maybe_lookup_decl_in_outer_ctx (var, ctx);
    9397         1161 :               if (!omp_privatize_by_reference (decl))
    9398         1123 :                 t = build_fold_addr_expr (t);
    9399              :             }
    9400         1646 :           t = fold_convert (pointer_sized_int_node, t);
    9401         1646 :           seq = NULL;
    9402         1646 :           t = force_gimple_operand (t, &seq, true, NULL_TREE);
    9403         1646 :           gimple_seq_add_seq (start, seq);
    9404         1646 :           r = build4 (ARRAY_REF, pointer_sized_int_node, avar,
    9405         1646 :                       size_int (7 + cnt * 3), NULL_TREE, NULL_TREE);
    9406         1646 :           gimple_seq_add_stmt (start, gimple_build_assign (r, t));
    9407         1646 :           t = unshare_expr (byte_position (field));
    9408         1646 :           t = fold_convert (pointer_sized_int_node, t);
    9409         1646 :           ctx->task_reduction_map->put (c, cnt);
    9410         3292 :           ctx->task_reductions.quick_push (TREE_CODE (t) == INTEGER_CST
    9411         2018 :                                            ? t : NULL_TREE);
    9412         1646 :           seq = NULL;
    9413         1646 :           t = force_gimple_operand (t, &seq, true, NULL_TREE);
    9414         1646 :           gimple_seq_add_seq (start, seq);
    9415         1646 :           r = build4 (ARRAY_REF, pointer_sized_int_node, avar,
    9416         1646 :                       size_int (7 + cnt * 3 + 1), NULL_TREE, NULL_TREE);
    9417         1646 :           gimple_seq_add_stmt (start, gimple_build_assign (r, t));
    9418              : 
    9419         1646 :           tree bfield = DECL_CHAIN (field);
    9420         1646 :           tree cond;
    9421         1646 :           if (code == OMP_PARALLEL
    9422         1646 :               || code == OMP_FOR
    9423              :               || code == OMP_SECTIONS
    9424              :               || code == OMP_SCOPE)
    9425              :             /* In parallel, worksharing or scope all threads unconditionally
    9426              :                initialize all their task reduction private variables.  */
    9427          548 :             cond = boolean_true_node;
    9428         1098 :           else if (TREE_TYPE (ptr) == ptr_type_node)
    9429              :             {
    9430          261 :               cond = build2 (POINTER_PLUS_EXPR, ptr_type_node, ptr,
    9431              :                              unshare_expr (byte_position (bfield)));
    9432          261 :               seq = NULL;
    9433          261 :               cond = force_gimple_operand (cond, &seq, true, NULL_TREE);
    9434          261 :               gimple_seq_add_seq (end, seq);
    9435          261 :               tree pbool = build_pointer_type (TREE_TYPE (bfield));
    9436          261 :               cond = build2 (MEM_REF, TREE_TYPE (bfield), cond,
    9437              :                              build_int_cst (pbool, 0));
    9438              :             }
    9439              :           else
    9440          837 :             cond = build3 (COMPONENT_REF, TREE_TYPE (bfield),
    9441              :                            build_simple_mem_ref (ptr), bfield, NULL_TREE);
    9442         1646 :           tree lab3 = create_artificial_label (UNKNOWN_LOCATION);
    9443         1646 :           tree lab4 = create_artificial_label (UNKNOWN_LOCATION);
    9444         1646 :           tree condv = create_tmp_var (boolean_type_node);
    9445         1646 :           gimple_seq_add_stmt (end, gimple_build_assign (condv, cond));
    9446         1646 :           g = gimple_build_cond (NE_EXPR, condv, boolean_false_node,
    9447              :                                  lab3, lab4);
    9448         1646 :           gimple_seq_add_stmt (end, g);
    9449         1646 :           gimple_seq_add_stmt (end, gimple_build_label (lab3));
    9450         1646 :           if (cancellable && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == NULL_TREE)
    9451              :             {
    9452              :               /* If this reduction doesn't need destruction and parallel
    9453              :                  has been cancelled, there is nothing to do for this
    9454              :                  reduction, so jump around the merge operation.  */
    9455           18 :               tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
    9456           18 :               g = gimple_build_cond (NE_EXPR, cancellable,
    9457           18 :                                      build_zero_cst (TREE_TYPE (cancellable)),
    9458              :                                      lab4, lab5);
    9459           18 :               gimple_seq_add_stmt (end, g);
    9460           18 :               gimple_seq_add_stmt (end, gimple_build_label (lab5));
    9461              :             }
    9462              : 
    9463         1646 :           tree new_var;
    9464         1646 :           if (TREE_TYPE (ptr) == ptr_type_node)
    9465              :             {
    9466          428 :               new_var = build2 (POINTER_PLUS_EXPR, ptr_type_node, ptr,
    9467              :                                 unshare_expr (byte_position (field)));
    9468          428 :               seq = NULL;
    9469          428 :               new_var = force_gimple_operand (new_var, &seq, true, NULL_TREE);
    9470          428 :               gimple_seq_add_seq (end, seq);
    9471          428 :               tree pbool = build_pointer_type (TREE_TYPE (field));
    9472          428 :               new_var = build2 (MEM_REF, TREE_TYPE (field), new_var,
    9473              :                                 build_int_cst (pbool, 0));
    9474              :             }
    9475              :           else
    9476         1218 :             new_var = build3 (COMPONENT_REF, TREE_TYPE (field),
    9477              :                               build_simple_mem_ref (ptr), field, NULL_TREE);
    9478              : 
    9479         1646 :           enum tree_code rcode = OMP_CLAUSE_REDUCTION_CODE (c);
    9480         1646 :           if (TREE_CODE (decl) != MEM_REF
    9481         1646 :               && omp_privatize_by_reference (decl))
    9482           38 :             ref = build_simple_mem_ref (ref);
    9483              :           /* reduction(-:var) sums up the partial results, so it acts
    9484              :              identically to reduction(+:var).  */
    9485         1646 :           if (rcode == MINUS_EXPR)
    9486            0 :             rcode = PLUS_EXPR;
    9487         1646 :           if (TREE_CODE (decl) == MEM_REF)
    9488              :             {
    9489          485 :               tree type = TREE_TYPE (new_var);
    9490          485 :               tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
    9491          485 :               tree i = create_tmp_var (TREE_TYPE (v));
    9492          485 :               tree ptype = build_pointer_type (TREE_TYPE (type));
    9493          485 :               if (DECL_P (v))
    9494              :                 {
    9495          142 :                   v = maybe_lookup_decl_in_outer_ctx (v, ctx);
    9496          142 :                   tree vv = create_tmp_var (TREE_TYPE (v));
    9497          142 :                   gimplify_assign (vv, v, start);
    9498          142 :                   v = vv;
    9499              :                 }
    9500          485 :               ref = build4 (ARRAY_REF, pointer_sized_int_node, avar,
    9501          485 :                             size_int (7 + cnt * 3), NULL_TREE, NULL_TREE);
    9502          485 :               new_var = build_fold_addr_expr (new_var);
    9503          485 :               new_var = fold_convert (ptype, new_var);
    9504          485 :               ref = fold_convert (ptype, ref);
    9505          485 :               tree m = create_tmp_var (ptype);
    9506          485 :               gimplify_assign (m, new_var, end);
    9507          485 :               new_var = m;
    9508          485 :               m = create_tmp_var (ptype);
    9509          485 :               gimplify_assign (m, ref, end);
    9510          485 :               ref = m;
    9511          485 :               gimplify_assign (i, build_int_cst (TREE_TYPE (v), 0), end);
    9512          485 :               tree body = create_artificial_label (UNKNOWN_LOCATION);
    9513          485 :               tree endl = create_artificial_label (UNKNOWN_LOCATION);
    9514          485 :               gimple_seq_add_stmt (end, gimple_build_label (body));
    9515          485 :               tree priv = build_simple_mem_ref (new_var);
    9516          485 :               tree out = build_simple_mem_ref (ref);
    9517          485 :               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    9518              :                 {
    9519          161 :                   tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
    9520          161 :                   tree decl_placeholder
    9521          161 :                     = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c);
    9522          161 :                   tree lab6 = NULL_TREE;
    9523          161 :                   if (cancellable)
    9524              :                     {
    9525              :                       /* If this reduction needs destruction and parallel
    9526              :                          has been cancelled, jump around the merge operation
    9527              :                          to the destruction.  */
    9528            4 :                       tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
    9529            4 :                       lab6 = create_artificial_label (UNKNOWN_LOCATION);
    9530            4 :                       tree zero = build_zero_cst (TREE_TYPE (cancellable));
    9531            4 :                       g = gimple_build_cond (NE_EXPR, cancellable, zero,
    9532              :                                              lab6, lab5);
    9533            4 :                       gimple_seq_add_stmt (end, g);
    9534            4 :                       gimple_seq_add_stmt (end, gimple_build_label (lab5));
    9535              :                     }
    9536          161 :                   SET_DECL_VALUE_EXPR (placeholder, out);
    9537          161 :                   DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
    9538          161 :                   SET_DECL_VALUE_EXPR (decl_placeholder, priv);
    9539          161 :                   DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 1;
    9540          161 :                   lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
    9541          322 :                   gimple_seq_add_seq (end,
    9542          161 :                                       OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
    9543          161 :                   OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    9544          161 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
    9545              :                     {
    9546           56 :                       OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
    9547           56 :                       OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) = NULL;
    9548              :                     }
    9549          161 :                   if (cancellable)
    9550            4 :                     gimple_seq_add_stmt (end, gimple_build_label (lab6));
    9551          161 :                   tree x = lang_hooks.decls.omp_clause_dtor (c, priv);
    9552          161 :                   if (x)
    9553              :                     {
    9554          137 :                       gimple_seq tseq = NULL;
    9555          137 :                       gimplify_stmt (&x, &tseq);
    9556          137 :                       gimple_seq_add_seq (end, tseq);
    9557              :                     }
    9558              :                 }
    9559              :               else
    9560              :                 {
    9561          324 :                   tree x = build2 (rcode, TREE_TYPE (out), out, priv);
    9562          324 :                   out = unshare_expr (out);
    9563          324 :                   gimplify_assign (out, x, end);
    9564              :                 }
    9565          485 :               gimple *g
    9566          485 :                 = gimple_build_assign (new_var, POINTER_PLUS_EXPR, new_var,
    9567          485 :                                        TYPE_SIZE_UNIT (TREE_TYPE (type)));
    9568          485 :               gimple_seq_add_stmt (end, g);
    9569          485 :               g = gimple_build_assign (ref, POINTER_PLUS_EXPR, ref,
    9570          485 :                                        TYPE_SIZE_UNIT (TREE_TYPE (type)));
    9571          485 :               gimple_seq_add_stmt (end, g);
    9572          485 :               g = gimple_build_assign (i, PLUS_EXPR, i,
    9573          485 :                                        build_int_cst (TREE_TYPE (i), 1));
    9574          485 :               gimple_seq_add_stmt (end, g);
    9575          485 :               g = gimple_build_cond (LE_EXPR, i, v, body, endl);
    9576          485 :               gimple_seq_add_stmt (end, g);
    9577          485 :               gimple_seq_add_stmt (end, gimple_build_label (endl));
    9578              :             }
    9579         1161 :           else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    9580              :             {
    9581          127 :               tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
    9582          127 :               tree oldv = NULL_TREE;
    9583          127 :               tree lab6 = NULL_TREE;
    9584          127 :               if (cancellable)
    9585              :                 {
    9586              :                   /* If this reduction needs destruction and parallel
    9587              :                      has been cancelled, jump around the merge operation
    9588              :                      to the destruction.  */
    9589            4 :                   tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
    9590            4 :                   lab6 = create_artificial_label (UNKNOWN_LOCATION);
    9591            4 :                   tree zero = build_zero_cst (TREE_TYPE (cancellable));
    9592            4 :                   g = gimple_build_cond (NE_EXPR, cancellable, zero,
    9593              :                                          lab6, lab5);
    9594            4 :                   gimple_seq_add_stmt (end, g);
    9595            4 :                   gimple_seq_add_stmt (end, gimple_build_label (lab5));
    9596              :                 }
    9597          127 :               if (omp_privatize_by_reference (decl)
    9598          137 :                   && !useless_type_conversion_p (TREE_TYPE (placeholder),
    9599           10 :                                                  TREE_TYPE (ref)))
    9600            0 :                 ref = build_fold_addr_expr_loc (OMP_CLAUSE_LOCATION (c), ref);
    9601          127 :               ref = build_fold_addr_expr_loc (OMP_CLAUSE_LOCATION (c), ref);
    9602          127 :               tree refv = create_tmp_var (TREE_TYPE (ref));
    9603          127 :               gimplify_assign (refv, ref, end);
    9604          127 :               ref = build_simple_mem_ref_loc (OMP_CLAUSE_LOCATION (c), refv);
    9605          127 :               SET_DECL_VALUE_EXPR (placeholder, ref);
    9606          127 :               DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
    9607          127 :               tree d = maybe_lookup_decl (decl, ctx);
    9608          127 :               gcc_assert (d);
    9609          127 :               if (DECL_HAS_VALUE_EXPR_P (d))
    9610            7 :                 oldv = DECL_VALUE_EXPR (d);
    9611          127 :               if (omp_privatize_by_reference (var))
    9612              :                 {
    9613           10 :                   tree v = fold_convert (TREE_TYPE (d),
    9614              :                                          build_fold_addr_expr (new_var));
    9615           10 :                   SET_DECL_VALUE_EXPR (d, v);
    9616              :                 }
    9617              :               else
    9618          117 :                 SET_DECL_VALUE_EXPR (d, new_var);
    9619          127 :               DECL_HAS_VALUE_EXPR_P (d) = 1;
    9620          127 :               lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
    9621          127 :               if (oldv)
    9622            7 :                 SET_DECL_VALUE_EXPR (d, oldv);
    9623              :               else
    9624              :                 {
    9625          120 :                   SET_DECL_VALUE_EXPR (d, NULL_TREE);
    9626          120 :                   DECL_HAS_VALUE_EXPR_P (d) = 0;
    9627              :                 }
    9628          127 :               gimple_seq_add_seq (end, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
    9629          127 :               OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    9630          127 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
    9631           24 :                 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
    9632          127 :               if (cancellable)
    9633            4 :                 gimple_seq_add_stmt (end, gimple_build_label (lab6));
    9634          127 :               tree x = lang_hooks.decls.omp_clause_dtor (c, new_var);
    9635          127 :               if (x)
    9636              :                 {
    9637           29 :                   gimple_seq tseq = NULL;
    9638           29 :                   gimplify_stmt (&x, &tseq);
    9639           29 :                   gimple_seq_add_seq (end, tseq);
    9640              :                 }
    9641              :             }
    9642              :           else
    9643              :             {
    9644         1034 :               tree x = build2 (rcode, TREE_TYPE (ref), ref, new_var);
    9645         1034 :               ref = unshare_expr (ref);
    9646         1034 :               gimplify_assign (ref, x, end);
    9647              :             }
    9648         1646 :           gimple_seq_add_stmt (end, gimple_build_label (lab4));
    9649         1646 :           ++cnt;
    9650         1646 :           field = DECL_CHAIN (bfield);
    9651              :         }
    9652              :     }
    9653              : 
    9654         1165 :   if (code == OMP_TASKGROUP)
    9655              :     {
    9656          327 :       t = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_REDUCTION_REGISTER);
    9657          327 :       g = gimple_build_call (t, 1, build_fold_addr_expr (avar));
    9658          327 :       gimple_seq_add_stmt (start, g);
    9659              :     }
    9660              :   else
    9661              :     {
    9662          838 :       tree c;
    9663          838 :       if (code == OMP_FOR)
    9664          227 :         c = gimple_omp_for_clauses (ctx->stmt);
    9665          611 :       else if (code == OMP_SECTIONS)
    9666            8 :         c = gimple_omp_sections_clauses (ctx->stmt);
    9667          603 :       else if (code == OMP_SCOPE)
    9668           46 :         c = gimple_omp_scope_clauses (ctx->stmt);
    9669              :       else
    9670          557 :         c = gimple_omp_taskreg_clauses (ctx->stmt);
    9671          838 :       c = omp_find_clause (c, OMP_CLAUSE__REDUCTEMP_);
    9672          838 :       t = fold_convert (TREE_TYPE (OMP_CLAUSE_DECL (c)),
    9673              :                         build_fold_addr_expr (avar));
    9674          838 :       gimplify_assign (OMP_CLAUSE_DECL (c), t, start);
    9675              :     }
    9676              : 
    9677         1165 :   gimple_seq_add_stmt (end, gimple_build_assign (data, PLUS_EXPR, data, sz));
    9678         1165 :   gimple_seq_add_stmt (end, gimple_build_assign (idx, PLUS_EXPR, idx,
    9679              :                                                  size_one_node));
    9680         1165 :   g = gimple_build_cond (NE_EXPR, idx, num_thr_sz, lab1, lab2);
    9681         1165 :   gimple_seq_add_stmt (end, g);
    9682         1165 :   gimple_seq_add_stmt (end, gimple_build_label (lab2));
    9683         1165 :   if (code == OMP_FOR || code == OMP_SECTIONS || code == OMP_SCOPE)
    9684              :     {
    9685          281 :       enum built_in_function bfn
    9686              :         = BUILT_IN_GOMP_WORKSHARE_TASK_REDUCTION_UNREGISTER;
    9687          281 :       t = builtin_decl_explicit (bfn);
    9688          281 :       tree c_bool_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (t)));
    9689          281 :       tree arg;
    9690          281 :       if (cancellable)
    9691              :         {
    9692           14 :           arg = create_tmp_var (c_bool_type);
    9693           14 :           gimple_seq_add_stmt (end, gimple_build_assign (arg, NOP_EXPR,
    9694              :                                                          cancellable));
    9695              :         }
    9696              :       else
    9697          267 :         arg = build_int_cst (c_bool_type, 0);
    9698          281 :       g = gimple_build_call (t, 1, arg);
    9699          281 :     }
    9700              :   else
    9701              :     {
    9702          884 :       t = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_REDUCTION_UNREGISTER);
    9703          884 :       g = gimple_build_call (t, 1, build_fold_addr_expr (avar));
    9704              :     }
    9705         1165 :   gimple_seq_add_stmt (end, g);
    9706         1165 :   if (lab7)
    9707          497 :     gimple_seq_add_stmt (end, gimple_build_label (lab7));
    9708         1165 :   t = build_constructor (atype, NULL);
    9709         1165 :   TREE_THIS_VOLATILE (t) = 1;
    9710         1165 :   gimple_seq_add_stmt (end, gimple_build_assign (avar, t));
    9711              : }
    9712              : 
    9713              : /* Expand code for an OpenMP taskgroup directive.  */
    9714              : 
    9715              : static void
    9716          536 : lower_omp_taskgroup (gimple_stmt_iterator *gsi_p, omp_context *ctx)
    9717              : {
    9718          536 :   gimple *stmt = gsi_stmt (*gsi_p);
    9719          536 :   gcall *x;
    9720          536 :   gbind *bind;
    9721          536 :   gimple_seq dseq = NULL;
    9722          536 :   tree block = make_node (BLOCK);
    9723              : 
    9724          536 :   bind = gimple_build_bind (NULL, NULL, block);
    9725          536 :   gsi_replace (gsi_p, bind, true);
    9726          536 :   gimple_bind_add_stmt (bind, stmt);
    9727              : 
    9728          536 :   push_gimplify_context ();
    9729              : 
    9730          536 :   x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_START),
    9731              :                          0);
    9732          536 :   gimple_bind_add_stmt (bind, x);
    9733              : 
    9734          536 :   lower_omp_task_reductions (ctx, OMP_TASKGROUP,
    9735              :                              gimple_omp_taskgroup_clauses (stmt),
    9736              :                              gimple_bind_body_ptr (bind), &dseq);
    9737              : 
    9738          536 :   lower_omp (gimple_omp_body_ptr (stmt), ctx);
    9739          536 :   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
    9740          536 :   gimple_omp_set_body (stmt, NULL);
    9741              : 
    9742          536 :   gimple_bind_add_seq (bind, dseq);
    9743              : 
    9744          536 :   pop_gimplify_context (bind);
    9745              : 
    9746          536 :   gimple_bind_append_vars (bind, ctx->block_vars);
    9747          536 :   BLOCK_VARS (block) = ctx->block_vars;
    9748          536 : }
    9749              : 
    9750              : 
    9751              : /* Fold the OMP_ORDERED_CLAUSES for the OMP_ORDERED in STMT if possible.  */
    9752              : 
    9753              : static void
    9754            0 : lower_omp_ordered_clauses (gimple_stmt_iterator *gsi_p, gomp_ordered *ord_stmt,
    9755              :                            omp_context *ctx)
    9756              : {
    9757            0 :   struct omp_for_data fd;
    9758            0 :   if (!ctx->outer || gimple_code (ctx->outer->stmt) != GIMPLE_OMP_FOR)
    9759            0 :     return;
    9760              : 
    9761            0 :   unsigned int len = gimple_omp_for_collapse (ctx->outer->stmt);
    9762            0 :   struct omp_for_data_loop *loops = XALLOCAVEC (struct omp_for_data_loop, len);
    9763            0 :   omp_extract_for_data (as_a <gomp_for *> (ctx->outer->stmt), &fd, loops);
    9764            0 :   if (!fd.ordered)
    9765              :     return;
    9766              : 
    9767            0 :   tree *list_p = gimple_omp_ordered_clauses_ptr (ord_stmt);
    9768            0 :   tree c = gimple_omp_ordered_clauses (ord_stmt);
    9769            0 :   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
    9770            0 :       && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
    9771              :     {
    9772              :       /* Merge depend clauses from multiple adjacent
    9773              :          #pragma omp ordered depend(sink:...) constructs
    9774              :          into one #pragma omp ordered depend(sink:...), so that
    9775              :          we can optimize them together.  */
    9776            0 :       gimple_stmt_iterator gsi = *gsi_p;
    9777            0 :       gsi_next (&gsi);
    9778            0 :       while (!gsi_end_p (gsi))
    9779              :         {
    9780            0 :           gimple *stmt = gsi_stmt (gsi);
    9781            0 :           if (is_gimple_debug (stmt)
    9782            0 :               || gimple_code (stmt) == GIMPLE_NOP)
    9783              :             {
    9784            0 :               gsi_next (&gsi);
    9785            0 :               continue;
    9786              :             }
    9787            0 :           if (gimple_code (stmt) != GIMPLE_OMP_ORDERED)
    9788              :             break;
    9789            0 :           gomp_ordered *ord_stmt2 = as_a <gomp_ordered *> (stmt);
    9790            0 :           c = gimple_omp_ordered_clauses (ord_stmt2);
    9791            0 :           if (c == NULL_TREE
    9792            0 :               || OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DOACROSS
    9793            0 :               || OMP_CLAUSE_DOACROSS_KIND (c) != OMP_CLAUSE_DOACROSS_SINK)
    9794              :             break;
    9795            0 :           while (*list_p)
    9796            0 :             list_p = &OMP_CLAUSE_CHAIN (*list_p);
    9797            0 :           *list_p = c;
    9798            0 :           gsi_remove (&gsi, true);
    9799              :         }
    9800              :     }
    9801              : 
    9802              :   /* Canonicalize sink dependence clauses into one folded clause if
    9803              :      possible.
    9804              : 
    9805              :      The basic algorithm is to create a sink vector whose first
    9806              :      element is the GCD of all the first elements, and whose remaining
    9807              :      elements are the minimum of the subsequent columns.
    9808              : 
    9809              :      We ignore dependence vectors whose first element is zero because
    9810              :      such dependencies are known to be executed by the same thread.
    9811              : 
    9812              :      We take into account the direction of the loop, so a minimum
    9813              :      becomes a maximum if the loop is iterating forwards.  We also
    9814              :      ignore sink clauses where the loop direction is unknown, or where
    9815              :      the offsets are clearly invalid because they are not a multiple
    9816              :      of the loop increment.
    9817              : 
    9818              :      For example:
    9819              : 
    9820              :         #pragma omp for ordered(2)
    9821              :         for (i=0; i < N; ++i)
    9822              :           for (j=0; j < M; ++j)
    9823              :             {
    9824              :               #pragma omp ordered \
    9825              :                 depend(sink:i-8,j-2) \
    9826              :                 depend(sink:i,j-1) \    // Completely ignored because i+0.
    9827              :                 depend(sink:i-4,j-3) \
    9828              :                 depend(sink:i-6,j-4)
    9829              :               #pragma omp ordered depend(source)
    9830              :             }
    9831              : 
    9832              :      Folded clause is:
    9833              : 
    9834              :         depend(sink:-gcd(8,4,6),-min(2,3,4))
    9835              :           -or-
    9836              :         depend(sink:-2,-2)
    9837              :   */
    9838              : 
    9839              :   /* FIXME: Computing GCD's where the first element is zero is
    9840              :      non-trivial in the presence of collapsed loops.  Do this later.  */
    9841            0 :   if (fd.collapse > 1)
    9842              :     return;
    9843              : 
    9844            0 :   wide_int *folded_deps = XALLOCAVEC (wide_int, 2 * len - 1);
    9845              : 
    9846              :   /* wide_int is not a POD so it must be default-constructed.  */
    9847            0 :   for (unsigned i = 0; i != 2 * len - 1; ++i)
    9848            0 :     new (static_cast<void*>(folded_deps + i)) wide_int ();
    9849              : 
    9850              :   tree folded_dep = NULL_TREE;
    9851              :   /* TRUE if the first dimension's offset is negative.  */
    9852              :   bool neg_offset_p = false;
    9853              : 
    9854              :   list_p = gimple_omp_ordered_clauses_ptr (ord_stmt);
    9855              :   unsigned int i;
    9856            0 :   while ((c = *list_p) != NULL)
    9857              :     {
    9858            0 :       bool remove = false;
    9859              : 
    9860            0 :       gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS);
    9861            0 :       if (OMP_CLAUSE_DOACROSS_KIND (c) != OMP_CLAUSE_DOACROSS_SINK)
    9862            0 :         goto next_ordered_clause;
    9863              : 
    9864            0 :       tree vec;
    9865            0 :       for (vec = OMP_CLAUSE_DECL (c), i = 0;
    9866            0 :            vec && TREE_CODE (vec) == TREE_LIST;
    9867            0 :            vec = TREE_CHAIN (vec), ++i)
    9868              :         {
    9869            0 :           gcc_assert (i < len);
    9870              : 
    9871              :           /* omp_extract_for_data has canonicalized the condition.  */
    9872            0 :           gcc_assert (fd.loops[i].cond_code == LT_EXPR
    9873              :                       || fd.loops[i].cond_code == GT_EXPR);
    9874            0 :           bool forward = fd.loops[i].cond_code == LT_EXPR;
    9875            0 :           bool maybe_lexically_later = true;
    9876              : 
    9877              :           /* While the committee makes up its mind, bail if we have any
    9878              :              non-constant steps.  */
    9879            0 :           if (TREE_CODE (fd.loops[i].step) != INTEGER_CST)
    9880            0 :             goto lower_omp_ordered_ret;
    9881              : 
    9882            0 :           tree itype = TREE_TYPE (TREE_VALUE (vec));
    9883            0 :           if (POINTER_TYPE_P (itype))
    9884            0 :             itype = sizetype;
    9885            0 :           wide_int offset = wide_int::from (wi::to_wide (TREE_PURPOSE (vec)),
    9886            0 :                                             TYPE_PRECISION (itype),
    9887            0 :                                             TYPE_SIGN (itype));
    9888              : 
    9889              :           /* Ignore invalid offsets that are not multiples of the step.  */
    9890            0 :           if (!wi::multiple_of_p (wi::abs (offset),
    9891            0 :                                   wi::abs (wi::to_wide (fd.loops[i].step)),
    9892              :                                   UNSIGNED))
    9893              :             {
    9894            0 :               warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
    9895              :                           "ignoring %<sink%> clause with offset that is not "
    9896              :                           "a multiple of the loop step");
    9897            0 :               remove = true;
    9898            0 :               goto next_ordered_clause;
    9899              :             }
    9900              : 
    9901              :           /* Calculate the first dimension.  The first dimension of
    9902              :              the folded dependency vector is the GCD of the first
    9903              :              elements, while ignoring any first elements whose offset
    9904              :              is 0.  */
    9905            0 :           if (i == 0)
    9906              :             {
    9907              :               /* Ignore dependence vectors whose first dimension is 0.  */
    9908            0 :               if (offset == 0)
    9909              :                 {
    9910            0 :                   remove = true;
    9911            0 :                   goto next_ordered_clause;
    9912              :                 }
    9913              :               else
    9914              :                 {
    9915            0 :                   if (!TYPE_UNSIGNED (itype) && (forward ^ wi::neg_p (offset)))
    9916              :                     {
    9917            0 :                       error_at (OMP_CLAUSE_LOCATION (c),
    9918              :                                 "first offset must be in opposite direction "
    9919              :                                 "of loop iterations");
    9920            0 :                       goto lower_omp_ordered_ret;
    9921              :                     }
    9922            0 :                   if (forward)
    9923            0 :                     offset = -offset;
    9924            0 :                   neg_offset_p = forward;
    9925              :                   /* Initialize the first time around.  */
    9926            0 :                   if (folded_dep == NULL_TREE)
    9927              :                     {
    9928            0 :                       folded_dep = c;
    9929            0 :                       folded_deps[0] = offset;
    9930              :                     }
    9931              :                   else
    9932            0 :                     folded_deps[0] = wi::gcd (folded_deps[0],
    9933            0 :                                               offset, UNSIGNED);
    9934              :                 }
    9935              :             }
    9936              :           /* Calculate minimum for the remaining dimensions.  */
    9937              :           else
    9938              :             {
    9939            0 :               folded_deps[len + i - 1] = offset;
    9940            0 :               if (folded_dep == c)
    9941            0 :                 folded_deps[i] = offset;
    9942            0 :               else if (maybe_lexically_later
    9943            0 :                        && !wi::eq_p (folded_deps[i], offset))
    9944              :                 {
    9945            0 :                   if (forward ^ wi::gts_p (folded_deps[i], offset))
    9946              :                     {
    9947              :                       unsigned int j;
    9948            0 :                       folded_dep = c;
    9949            0 :                       for (j = 1; j <= i; j++)
    9950            0 :                         folded_deps[j] = folded_deps[len + j - 1];
    9951              :                     }
    9952              :                   else
    9953            0 :                     maybe_lexically_later = false;
    9954              :                 }
    9955              :             }
    9956            0 :         }
    9957            0 :       gcc_assert (i == len);
    9958              : 
    9959              :       remove = true;
    9960              : 
    9961            0 :     next_ordered_clause:
    9962            0 :       if (remove)
    9963            0 :         *list_p = OMP_CLAUSE_CHAIN (c);
    9964              :       else
    9965            0 :         list_p = &OMP_CLAUSE_CHAIN (c);
    9966              :     }
    9967              : 
    9968            0 :   if (folded_dep)
    9969              :     {
    9970            0 :       if (neg_offset_p)
    9971            0 :         folded_deps[0] = -folded_deps[0];
    9972              : 
    9973            0 :       tree itype = TREE_TYPE (TREE_VALUE (OMP_CLAUSE_DECL (folded_dep)));
    9974            0 :       if (POINTER_TYPE_P (itype))
    9975            0 :         itype = sizetype;
    9976              : 
    9977            0 :       TREE_PURPOSE (OMP_CLAUSE_DECL (folded_dep))
    9978            0 :         = wide_int_to_tree (itype, folded_deps[0]);
    9979            0 :       OMP_CLAUSE_CHAIN (folded_dep) = gimple_omp_ordered_clauses (ord_stmt);
    9980            0 :       *gimple_omp_ordered_clauses_ptr (ord_stmt) = folded_dep;
    9981              :     }
    9982              : 
    9983            0 :  lower_omp_ordered_ret:
    9984              : 
    9985              :   /* Ordered without clauses is #pragma omp threads, while we want
    9986              :      a nop instead if we remove all clauses.  */
    9987            0 :   if (gimple_omp_ordered_clauses (ord_stmt) == NULL_TREE)
    9988            0 :     gsi_replace (gsi_p, gimple_build_nop (), true);
    9989              : }
    9990              : 
    9991              : 
    9992              : /* Expand code for an OpenMP ordered directive.  */
    9993              : 
    9994              : static void
    9995         1124 : lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
    9996              : {
    9997         1124 :   tree block;
    9998         1124 :   gimple *stmt = gsi_stmt (*gsi_p), *g;
    9999         1124 :   gomp_ordered *ord_stmt = as_a <gomp_ordered *> (stmt);
   10000         1124 :   gcall *x;
   10001         1124 :   gbind *bind;
   10002         1124 :   bool simd = omp_find_clause (gimple_omp_ordered_clauses (ord_stmt),
   10003         1124 :                                OMP_CLAUSE_SIMD);
   10004              :   /* FIXME: this should check presence of OMP_CLAUSE__SIMT_ on the enclosing
   10005              :      loop.  */
   10006         1124 :   bool maybe_simt
   10007         1124 :     = simd && omp_maybe_offloaded_ctx (ctx) && omp_max_simt_vf () > 1;
   10008         1124 :   bool threads = omp_find_clause (gimple_omp_ordered_clauses (ord_stmt),
   10009         1124 :                                   OMP_CLAUSE_THREADS);
   10010              : 
   10011         1124 :   if (gimple_omp_ordered_standalone_p (ord_stmt))
   10012              :     {
   10013              :       /* FIXME: This is needs to be moved to the expansion to verify various
   10014              :          conditions only testable on cfg with dominators computed, and also
   10015              :          all the depend clauses to be merged still might need to be available
   10016              :          for the runtime checks.  */
   10017              :       if (0)
   10018              :         lower_omp_ordered_clauses (gsi_p, ord_stmt, ctx);
   10019         1124 :       return;
   10020              :     }
   10021              : 
   10022          411 :   push_gimplify_context ();
   10023              : 
   10024          411 :   block = make_node (BLOCK);
   10025          411 :   bind = gimple_build_bind (NULL, NULL, block);
   10026          411 :   gsi_replace (gsi_p, bind, true);
   10027          411 :   gimple_bind_add_stmt (bind, stmt);
   10028              : 
   10029          411 :   if (simd)
   10030              :     {
   10031           79 :       x = gimple_build_call_internal (IFN_GOMP_SIMD_ORDERED_START, 1,
   10032           79 :                                       build_int_cst (NULL_TREE, threads));
   10033           79 :       cfun->has_simduid_loops = true;
   10034              :     }
   10035              :   else
   10036          332 :     x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
   10037              :                            0);
   10038          411 :   gimple_bind_add_stmt (bind, x);
   10039              : 
   10040          411 :   tree counter = NULL_TREE, test = NULL_TREE, body = NULL_TREE;
   10041          411 :   if (maybe_simt)
   10042              :     {
   10043            0 :       counter = create_tmp_var (integer_type_node);
   10044            0 :       g = gimple_build_call_internal (IFN_GOMP_SIMT_LANE, 0);
   10045            0 :       gimple_call_set_lhs (g, counter);
   10046            0 :       gimple_bind_add_stmt (bind, g);
   10047              : 
   10048            0 :       body = create_artificial_label (UNKNOWN_LOCATION);
   10049            0 :       test = create_artificial_label (UNKNOWN_LOCATION);
   10050            0 :       gimple_bind_add_stmt (bind, gimple_build_label (body));
   10051              : 
   10052            0 :       tree simt_pred = create_tmp_var (integer_type_node);
   10053            0 :       g = gimple_build_call_internal (IFN_GOMP_SIMT_ORDERED_PRED, 1, counter);
   10054            0 :       gimple_call_set_lhs (g, simt_pred);
   10055            0 :       gimple_bind_add_stmt (bind, g);
   10056              : 
   10057            0 :       tree t = create_artificial_label (UNKNOWN_LOCATION);
   10058            0 :       g = gimple_build_cond (EQ_EXPR, simt_pred, integer_zero_node, t, test);
   10059            0 :       gimple_bind_add_stmt (bind, g);
   10060              : 
   10061            0 :       gimple_bind_add_stmt (bind, gimple_build_label (t));
   10062              :     }
   10063          411 :   lower_omp (gimple_omp_body_ptr (stmt), ctx);
   10064          411 :   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
   10065          411 :   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
   10066          411 :   gimple_omp_set_body (stmt, NULL);
   10067              : 
   10068          411 :   if (maybe_simt)
   10069              :     {
   10070            0 :       gimple_bind_add_stmt (bind, gimple_build_label (test));
   10071            0 :       g = gimple_build_assign (counter, MINUS_EXPR, counter, integer_one_node);
   10072            0 :       gimple_bind_add_stmt (bind, g);
   10073              : 
   10074            0 :       tree c = build2 (GE_EXPR, boolean_type_node, counter, integer_zero_node);
   10075            0 :       tree nonneg = create_tmp_var (integer_type_node);
   10076            0 :       gimple_seq tseq = NULL;
   10077            0 :       gimplify_assign (nonneg, fold_convert (integer_type_node, c), &tseq);
   10078            0 :       gimple_bind_add_seq (bind, tseq);
   10079              : 
   10080            0 :       g = gimple_build_call_internal (IFN_GOMP_SIMT_VOTE_ANY, 1, nonneg);
   10081            0 :       gimple_call_set_lhs (g, nonneg);
   10082            0 :       gimple_bind_add_stmt (bind, g);
   10083              : 
   10084            0 :       tree end = create_artificial_label (UNKNOWN_LOCATION);
   10085            0 :       g = gimple_build_cond (NE_EXPR, nonneg, integer_zero_node, body, end);
   10086            0 :       gimple_bind_add_stmt (bind, g);
   10087              : 
   10088            0 :       gimple_bind_add_stmt (bind, gimple_build_label (end));
   10089              :     }
   10090          411 :   if (simd)
   10091           79 :     x = gimple_build_call_internal (IFN_GOMP_SIMD_ORDERED_END, 1,
   10092           79 :                                     build_int_cst (NULL_TREE, threads));
   10093              :   else
   10094          332 :     x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END),
   10095              :                            0);
   10096          411 :   gimple_bind_add_stmt (bind, x);
   10097              : 
   10098          411 :   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
   10099              : 
   10100          411 :   pop_gimplify_context (bind);
   10101              : 
   10102          411 :   gimple_bind_append_vars (bind, ctx->block_vars);
   10103          411 :   BLOCK_VARS (block) = gimple_bind_vars (bind);
   10104              : }
   10105              : 
   10106              : 
   10107              : /* Expand code for an OpenMP scan directive and the structured block
   10108              :    before the scan directive.  */
   10109              : 
   10110              : static void
   10111         1536 : lower_omp_scan (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   10112              : {
   10113         1536 :   gimple *stmt = gsi_stmt (*gsi_p);
   10114         1536 :   bool has_clauses
   10115         1536 :     = gimple_omp_scan_clauses (as_a <gomp_scan *> (stmt)) != NULL;
   10116         1536 :   tree lane = NULL_TREE;
   10117         1536 :   gimple_seq before = NULL;
   10118         1536 :   omp_context *octx = ctx->outer;
   10119         1536 :   gcc_assert (octx);
   10120         1536 :   if (octx->scan_exclusive && !has_clauses)
   10121              :     {
   10122          536 :       gimple_stmt_iterator gsi2 = *gsi_p;
   10123          536 :       gsi_next (&gsi2);
   10124          536 :       gimple *stmt2 = gsi_stmt (gsi2);
   10125              :       /* For exclusive scan, swap GIMPLE_OMP_SCAN without clauses
   10126              :          with following GIMPLE_OMP_SCAN with clauses, so that input_phase,
   10127              :          the one with exclusive clause(s), comes first.  */
   10128          536 :       if (stmt2
   10129          274 :           && gimple_code (stmt2) == GIMPLE_OMP_SCAN
   10130          804 :           && gimple_omp_scan_clauses (as_a <gomp_scan *> (stmt2)) != NULL)
   10131              :         {
   10132          268 :           gsi_remove (gsi_p, false);
   10133          268 :           gsi_insert_after (gsi_p, stmt, GSI_SAME_STMT);
   10134          268 :           ctx = maybe_lookup_ctx (stmt2);
   10135          268 :           gcc_assert (ctx);
   10136          268 :           lower_omp_scan (gsi_p, ctx);
   10137          268 :           return;
   10138              :         }
   10139              :     }
   10140              : 
   10141         1268 :   bool input_phase = has_clauses ^ octx->scan_inclusive;
   10142         1268 :   bool is_simd = (gimple_code (octx->stmt) == GIMPLE_OMP_FOR
   10143         1268 :                   && gimple_omp_for_kind (octx->stmt) == GF_OMP_FOR_KIND_SIMD);
   10144         1268 :   bool is_for = (gimple_code (octx->stmt) == GIMPLE_OMP_FOR
   10145         1268 :                  && gimple_omp_for_kind (octx->stmt) == GF_OMP_FOR_KIND_FOR
   10146         1614 :                  && !gimple_omp_for_combined_p (octx->stmt));
   10147         1268 :   bool is_for_simd = is_simd && gimple_omp_for_combined_into_p (octx->stmt);
   10148          332 :   if (is_for_simd && octx->for_simd_scan_phase)
   10149              :     is_simd = false;
   10150         1102 :   if (is_simd)
   10151          756 :     if (tree c = omp_find_clause (gimple_omp_for_clauses (octx->stmt),
   10152              :                                   OMP_CLAUSE__SIMDUID_))
   10153              :       {
   10154          368 :         tree uid = OMP_CLAUSE__SIMDUID__DECL (c);
   10155          368 :         lane = create_tmp_var (unsigned_type_node);
   10156          368 :         tree t = build_int_cst (integer_type_node,
   10157          552 :                                 input_phase ? 1
   10158          184 :                                 : octx->scan_inclusive ? 2 : 3);
   10159          368 :         gimple *g
   10160          368 :           = gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 2, uid, t);
   10161          368 :         gimple_call_set_lhs (g, lane);
   10162          368 :         gimple_seq_add_stmt (&before, g);
   10163              :       }
   10164              : 
   10165         1268 :   if (is_simd || is_for)
   10166              :     {
   10167         4980 :       for (tree c = gimple_omp_for_clauses (octx->stmt);
   10168         4980 :            c; c = OMP_CLAUSE_CHAIN (c))
   10169         4044 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   10170         4044 :             && OMP_CLAUSE_REDUCTION_INSCAN (c))
   10171              :           {
   10172         1160 :             location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   10173         1160 :             tree var = OMP_CLAUSE_DECL (c);
   10174         1160 :             tree new_var = lookup_decl (var, octx);
   10175         1160 :             tree val = new_var;
   10176         1160 :             tree var2 = NULL_TREE;
   10177         1160 :             tree var3 = NULL_TREE;
   10178         1160 :             tree var4 = NULL_TREE;
   10179         1160 :             tree lane0 = NULL_TREE;
   10180         1160 :             tree new_vard = new_var;
   10181         1160 :             if (omp_privatize_by_reference (var))
   10182              :               {
   10183          184 :                 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
   10184          184 :                 val = new_var;
   10185              :               }
   10186         1160 :             if (DECL_HAS_VALUE_EXPR_P (new_vard))
   10187              :               {
   10188          464 :                 val = DECL_VALUE_EXPR (new_vard);
   10189          464 :                 if (new_vard != new_var)
   10190              :                   {
   10191           76 :                     gcc_assert (TREE_CODE (val) == ADDR_EXPR);
   10192           76 :                     val = TREE_OPERAND (val, 0);
   10193              :                   }
   10194          464 :                 if (TREE_CODE (val) == ARRAY_REF
   10195          464 :                     && VAR_P (TREE_OPERAND (val, 0)))
   10196              :                   {
   10197          464 :                     tree v = TREE_OPERAND (val, 0);
   10198          464 :                     if (lookup_attribute ("omp simd array",
   10199          464 :                                           DECL_ATTRIBUTES (v)))
   10200              :                       {
   10201          464 :                         val = unshare_expr (val);
   10202          464 :                         lane0 = TREE_OPERAND (val, 1);
   10203          464 :                         TREE_OPERAND (val, 1) = lane;
   10204          464 :                         var2 = lookup_decl (v, octx);
   10205          464 :                         if (octx->scan_exclusive)
   10206          228 :                           var4 = lookup_decl (var2, octx);
   10207          464 :                         if (input_phase
   10208          464 :                             && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   10209          120 :                           var3 = maybe_lookup_decl (var4 ? var4 : var2, octx);
   10210          464 :                         if (!input_phase)
   10211              :                           {
   10212          232 :                             var2 = build4 (ARRAY_REF, TREE_TYPE (val),
   10213              :                                            var2, lane, NULL_TREE, NULL_TREE);
   10214          232 :                             TREE_THIS_NOTRAP (var2) = 1;
   10215          232 :                             if (octx->scan_exclusive)
   10216              :                               {
   10217          114 :                                 var4 = build4 (ARRAY_REF, TREE_TYPE (val),
   10218              :                                                var4, lane, NULL_TREE,
   10219              :                                                NULL_TREE);
   10220          114 :                                 TREE_THIS_NOTRAP (var4) = 1;
   10221              :                               }
   10222              :                           }
   10223              :                         else
   10224              :                           var2 = val;
   10225              :                       }
   10226              :                   }
   10227          464 :                 gcc_assert (var2);
   10228              :               }
   10229              :             else
   10230              :               {
   10231          696 :                 var2 = build_outer_var_ref (var, octx);
   10232          696 :                 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   10233              :                   {
   10234          220 :                     var3 = maybe_lookup_decl (new_vard, octx);
   10235          220 :                     if (var3 == new_vard || var3 == NULL_TREE)
   10236              :                       var3 = NULL_TREE;
   10237          108 :                     else if (is_simd && octx->scan_exclusive && !input_phase)
   10238              :                       {
   10239           16 :                         var4 = maybe_lookup_decl (var3, octx);
   10240           16 :                         if (var4 == var3 || var4 == NULL_TREE)
   10241              :                           {
   10242            0 :                             if (TREE_ADDRESSABLE (TREE_TYPE (new_var)))
   10243              :                               {
   10244              :                                 var4 = var3;
   10245              :                                 var3 = NULL_TREE;
   10246              :                               }
   10247              :                             else
   10248           16 :                               var4 = NULL_TREE;
   10249              :                           }
   10250              :                       }
   10251              :                   }
   10252          664 :                 if (is_simd
   10253          484 :                     && octx->scan_exclusive
   10254          244 :                     && !input_phase
   10255          244 :                     && var4 == NULL_TREE)
   10256          106 :                   var4 = create_tmp_var (TREE_TYPE (val));
   10257              :               }
   10258         1160 :             if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   10259              :               {
   10260          376 :                 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
   10261          376 :                 if (input_phase)
   10262              :                   {
   10263          188 :                     if (var3)
   10264              :                       {
   10265              :                         /* If we've added a separate identity element
   10266              :                            variable, copy it over into val.  */
   10267           92 :                         tree x = lang_hooks.decls.omp_clause_assign_op (c, val,
   10268              :                                                                         var3);
   10269           92 :                         gimplify_and_add (x, &before);
   10270              :                       }
   10271           96 :                     else if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
   10272              :                       {
   10273              :                         /* Otherwise, assign to it the identity element.  */
   10274           96 :                         gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
   10275           96 :                         if (is_for)
   10276           16 :                           tseq = copy_gimple_seq_and_replace_locals (tseq);
   10277           96 :                         tree ref = build_outer_var_ref (var, octx);
   10278           96 :                         tree x = (DECL_HAS_VALUE_EXPR_P (new_vard)
   10279           96 :                                   ? DECL_VALUE_EXPR (new_vard) : NULL_TREE);
   10280           40 :                         if (x)
   10281              :                           {
   10282           40 :                             if (new_vard != new_var)
   10283            8 :                               val = build_fold_addr_expr_loc (clause_loc, val);
   10284           40 :                             SET_DECL_VALUE_EXPR (new_vard, val);
   10285              :                           }
   10286           96 :                         SET_DECL_VALUE_EXPR (placeholder, ref);
   10287           96 :                         DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
   10288           96 :                         lower_omp (&tseq, octx);
   10289           96 :                         if (x)
   10290           40 :                           SET_DECL_VALUE_EXPR (new_vard, x);
   10291           96 :                         SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
   10292           96 :                         DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
   10293           96 :                         gimple_seq_add_seq (&before, tseq);
   10294           96 :                         if (is_simd)
   10295           80 :                           OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
   10296              :                       }
   10297              :                   }
   10298          188 :                 else if (is_simd)
   10299              :                   {
   10300          156 :                     tree x;
   10301          156 :                     if (octx->scan_exclusive)
   10302              :                       {
   10303           72 :                         tree v4 = unshare_expr (var4);
   10304           72 :                         tree v2 = unshare_expr (var2);
   10305           72 :                         x = lang_hooks.decls.omp_clause_assign_op (c, v4, v2);
   10306           72 :                         gimplify_and_add (x, &before);
   10307              :                       }
   10308          156 :                     gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
   10309          156 :                     x = (DECL_HAS_VALUE_EXPR_P (new_vard)
   10310          156 :                          ? DECL_VALUE_EXPR (new_vard) : NULL_TREE);
   10311          156 :                     tree vexpr = val;
   10312          156 :                     if (x && new_vard != new_var)
   10313           30 :                       vexpr = build_fold_addr_expr_loc (clause_loc, val);
   10314          156 :                     if (x)
   10315           78 :                       SET_DECL_VALUE_EXPR (new_vard, vexpr);
   10316          156 :                     SET_DECL_VALUE_EXPR (placeholder, var2);
   10317          156 :                     DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
   10318          156 :                     lower_omp (&tseq, octx);
   10319          156 :                     gimple_seq_add_seq (&before, tseq);
   10320          156 :                     OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
   10321          156 :                     if (x)
   10322           78 :                       SET_DECL_VALUE_EXPR (new_vard, x);
   10323          156 :                     SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
   10324          156 :                     DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
   10325          156 :                     if (octx->scan_inclusive)
   10326              :                       {
   10327           84 :                         x = lang_hooks.decls.omp_clause_assign_op (c, val,
   10328              :                                                                    var2);
   10329           84 :                         gimplify_and_add (x, &before);
   10330              :                       }
   10331           72 :                     else if (lane0 == NULL_TREE)
   10332              :                       {
   10333           36 :                         x = lang_hooks.decls.omp_clause_assign_op (c, val,
   10334              :                                                                    var4);
   10335           36 :                         gimplify_and_add (x, &before);
   10336              :                       }
   10337              :                   }
   10338              :               }
   10339              :             else
   10340              :               {
   10341          784 :                 if (input_phase)
   10342              :                   {
   10343              :                     /* input phase.  Set val to initializer before
   10344              :                        the body.  */
   10345          392 :                     tree x = omp_reduction_init (c, TREE_TYPE (new_var));
   10346          392 :                     gimplify_assign (val, x, &before);
   10347              :                   }
   10348          392 :                 else if (is_simd)
   10349              :                   {
   10350              :                     /* scan phase.  */
   10351          318 :                     enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
   10352          318 :                     if (code == MINUS_EXPR)
   10353            0 :                       code = PLUS_EXPR;
   10354              : 
   10355          318 :                     tree x = build2 (code, TREE_TYPE (var2),
   10356              :                                      unshare_expr (var2), unshare_expr (val));
   10357          318 :                     if (octx->scan_inclusive)
   10358              :                       {
   10359          154 :                         gimplify_assign (unshare_expr (var2), x, &before);
   10360          154 :                         gimplify_assign (val, var2, &before);
   10361              :                       }
   10362              :                     else
   10363              :                       {
   10364          164 :                         gimplify_assign (unshare_expr (var4),
   10365              :                                          unshare_expr (var2), &before);
   10366          164 :                         gimplify_assign (var2, x, &before);
   10367          164 :                         if (lane0 == NULL_TREE)
   10368           86 :                           gimplify_assign (val, var4, &before);
   10369              :                       }
   10370              :                   }
   10371              :               }
   10372         1160 :             if (octx->scan_exclusive && !input_phase && lane0)
   10373              :               {
   10374          114 :                 tree vexpr = unshare_expr (var4);
   10375          114 :                 TREE_OPERAND (vexpr, 1) = lane0;
   10376          114 :                 if (new_vard != new_var)
   10377           16 :                   vexpr = build_fold_addr_expr_loc (clause_loc, vexpr);
   10378          114 :                 SET_DECL_VALUE_EXPR (new_vard, vexpr);
   10379              :               }
   10380              :           }
   10381              :     }
   10382         1268 :   if (is_simd && !is_for_simd)
   10383              :     {
   10384          590 :       gsi_insert_seq_after (gsi_p, gimple_omp_body (stmt), GSI_SAME_STMT);
   10385          590 :       gsi_insert_seq_after (gsi_p, before, GSI_SAME_STMT);
   10386          590 :       gsi_replace (gsi_p, gimple_build_nop (), true);
   10387          590 :       return;
   10388              :     }
   10389          678 :   lower_omp (gimple_omp_body_ptr (stmt), octx);
   10390          678 :   if (before)
   10391              :     {
   10392          256 :       gimple_stmt_iterator gsi = gsi_start (*gimple_omp_body_ptr (stmt));
   10393          256 :       gsi_insert_seq_before (&gsi, before, GSI_SAME_STMT);
   10394              :     }
   10395              : }
   10396              : 
   10397              : 
   10398              : /* Gimplify a GIMPLE_OMP_CRITICAL statement.  This is a relatively simple
   10399              :    substitution of a couple of function calls.  But in the NAMED case,
   10400              :    requires that languages coordinate a symbol name.  It is therefore
   10401              :    best put here in common code.  */
   10402              : 
   10403              : static GTY(()) hash_map<tree, tree> *critical_name_mutexes;
   10404              : 
   10405              : static void
   10406          311 : lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   10407              : {
   10408          311 :   tree block;
   10409          311 :   tree name, lock, unlock;
   10410          311 :   gomp_critical *stmt = as_a <gomp_critical *> (gsi_stmt (*gsi_p));
   10411          311 :   gbind *bind;
   10412          311 :   location_t loc = gimple_location (stmt);
   10413          311 :   gimple_seq tbody;
   10414              : 
   10415          311 :   name = gimple_omp_critical_name (stmt);
   10416          311 :   if (name)
   10417              :     {
   10418           88 :       tree decl;
   10419              : 
   10420           88 :       if (!critical_name_mutexes)
   10421           48 :         critical_name_mutexes = hash_map<tree, tree>::create_ggc (10);
   10422              : 
   10423           88 :       tree *n = critical_name_mutexes->get (name);
   10424           88 :       if (n == NULL)
   10425              :         {
   10426           70 :           char *new_str;
   10427              : 
   10428           70 :           decl = create_tmp_var_raw (ptr_type_node);
   10429              : 
   10430           70 :           new_str = ACONCAT ((".gomp_critical_user_",
   10431              :                               IDENTIFIER_POINTER (name), NULL));
   10432           70 :           DECL_NAME (decl) = get_identifier (new_str);
   10433           70 :           TREE_PUBLIC (decl) = 1;
   10434           70 :           TREE_STATIC (decl) = 1;
   10435           70 :           DECL_COMMON (decl) = 1;
   10436           70 :           DECL_ARTIFICIAL (decl) = 1;
   10437           70 :           DECL_IGNORED_P (decl) = 1;
   10438              : 
   10439           70 :           varpool_node::finalize_decl (decl);
   10440              : 
   10441           70 :           critical_name_mutexes->put (name, decl);
   10442              :         }
   10443              :       else
   10444           18 :         decl = *n;
   10445              : 
   10446              :       /* If '#pragma omp critical' is inside offloaded region or
   10447              :          inside function marked as offloadable, the symbol must be
   10448              :          marked as offloadable too.  */
   10449           88 :       omp_context *octx;
   10450           88 :       if (cgraph_node::get (current_function_decl)->offloadable)
   10451            1 :         varpool_node::get_create (decl)->offloadable = 1;
   10452              :       else
   10453          173 :         for (octx = ctx->outer; octx; octx = octx->outer)
   10454           87 :           if (is_gimple_omp_offloaded (octx->stmt))
   10455              :             {
   10456            1 :               varpool_node::get_create (decl)->offloadable = 1;
   10457            1 :               break;
   10458              :             }
   10459              : 
   10460           88 :       lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
   10461           88 :       lock = build_call_expr_loc (loc, lock, 1,
   10462              :                                   build_fold_addr_expr_loc (loc, decl));
   10463              : 
   10464           88 :       unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
   10465           88 :       unlock = build_call_expr_loc (loc, unlock, 1,
   10466              :                                 build_fold_addr_expr_loc (loc, decl));
   10467              :     }
   10468              :   else
   10469              :     {
   10470          223 :       lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
   10471          223 :       lock = build_call_expr_loc (loc, lock, 0);
   10472              : 
   10473          223 :       unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
   10474          223 :       unlock = build_call_expr_loc (loc, unlock, 0);
   10475              :     }
   10476              : 
   10477          311 :   push_gimplify_context ();
   10478              : 
   10479          311 :   block = make_node (BLOCK);
   10480          311 :   bind = gimple_build_bind (NULL, NULL, block);
   10481          311 :   gsi_replace (gsi_p, bind, true);
   10482          311 :   gimple_bind_add_stmt (bind, stmt);
   10483              : 
   10484          311 :   tbody = gimple_bind_body (bind);
   10485          311 :   gimplify_and_add (lock, &tbody);
   10486          311 :   gimple_bind_set_body (bind, tbody);
   10487              : 
   10488          311 :   lower_omp (gimple_omp_body_ptr (stmt), ctx);
   10489          311 :   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
   10490          311 :   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
   10491          311 :   gimple_omp_set_body (stmt, NULL);
   10492              : 
   10493          311 :   tbody = gimple_bind_body (bind);
   10494          311 :   gimplify_and_add (unlock, &tbody);
   10495          311 :   gimple_bind_set_body (bind, tbody);
   10496              : 
   10497          311 :   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
   10498              : 
   10499          311 :   pop_gimplify_context (bind);
   10500          311 :   gimple_bind_append_vars (bind, ctx->block_vars);
   10501          311 :   BLOCK_VARS (block) = gimple_bind_vars (bind);
   10502          311 : }
   10503              : 
   10504              : /* A subroutine of lower_omp_for.  Generate code to emit the predicate
   10505              :    for a lastprivate clause.  Given a loop control predicate of (V
   10506              :    cond N2), we gate the clause on (!(V cond N2)).  The lowered form
   10507              :    is appended to *DLIST, iterator initialization is appended to
   10508              :    *BODY_P.  *CLIST is for lastprivate(conditional:) code that needs
   10509              :    to be emitted in a critical section.  */
   10510              : 
   10511              : static void
   10512        46888 : lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
   10513              :                            gimple_seq *dlist, gimple_seq *clist,
   10514              :                            struct omp_context *ctx)
   10515              : {
   10516        46888 :   tree clauses, cond, vinit;
   10517        46888 :   enum tree_code cond_code;
   10518        46888 :   gimple_seq stmts;
   10519              : 
   10520        46888 :   cond_code = fd->loop.cond_code;
   10521        46888 :   cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
   10522              : 
   10523              :   /* When possible, use a strict equality expression.  This can let VRP
   10524              :      type optimizations deduce the value and remove a copy.  */
   10525        46888 :   if (tree_fits_shwi_p (fd->loop.step))
   10526              :     {
   10527        44649 :       HOST_WIDE_INT step = tree_to_shwi (fd->loop.step);
   10528        44649 :       if (step == 1 || step == -1)
   10529        46888 :         cond_code = EQ_EXPR;
   10530              :     }
   10531              : 
   10532        46888 :   tree n2 = fd->loop.n2;
   10533        46888 :   if (fd->collapse > 1
   10534        11251 :       && TREE_CODE (n2) != INTEGER_CST
   10535        53102 :       && gimple_omp_for_combined_into_p (fd->for_stmt))
   10536              :     {
   10537         2692 :       struct omp_context *taskreg_ctx = NULL;
   10538         2692 :       if (gimple_code (ctx->outer->stmt) == GIMPLE_OMP_FOR)
   10539              :         {
   10540         1226 :           gomp_for *gfor = as_a <gomp_for *> (ctx->outer->stmt);
   10541         1226 :           if (gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_FOR
   10542         1226 :               || gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_DISTRIBUTE)
   10543              :             {
   10544         1194 :               if (gimple_omp_for_combined_into_p (gfor))
   10545              :                 {
   10546          672 :                   gcc_assert (ctx->outer->outer
   10547              :                               && is_parallel_ctx (ctx->outer->outer));
   10548              :                   taskreg_ctx = ctx->outer->outer;
   10549              :                 }
   10550              :               else
   10551              :                 {
   10552          522 :                   struct omp_for_data outer_fd;
   10553          522 :                   omp_extract_for_data (gfor, &outer_fd, NULL);
   10554          522 :                   n2 = fold_convert (TREE_TYPE (n2), outer_fd.loop.n2);
   10555              :                 }
   10556              :             }
   10557           32 :           else if (gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_TASKLOOP)
   10558           32 :             taskreg_ctx = ctx->outer->outer;
   10559              :         }
   10560         1466 :       else if (is_taskreg_ctx (ctx->outer))
   10561              :         taskreg_ctx = ctx->outer;
   10562         2692 :       if (taskreg_ctx)
   10563              :         {
   10564         2170 :           int i;
   10565         2170 :           tree taskreg_clauses
   10566         2170 :             = gimple_omp_taskreg_clauses (taskreg_ctx->stmt);
   10567         2170 :           tree innerc = omp_find_clause (taskreg_clauses,
   10568              :                                          OMP_CLAUSE__LOOPTEMP_);
   10569         2170 :           gcc_assert (innerc);
   10570         2170 :           int count = fd->collapse;
   10571         2170 :           if (fd->non_rect
   10572           24 :               && fd->last_nonrect == fd->first_nonrect + 1)
   10573           12 :             if (tree v = gimple_omp_for_index (fd->for_stmt, fd->last_nonrect))
   10574           12 :               if (!TYPE_UNSIGNED (TREE_TYPE (v)))
   10575           12 :                 count += 4;
   10576         8582 :           for (i = 0; i < count; i++)
   10577              :             {
   10578         6412 :               innerc = omp_find_clause (OMP_CLAUSE_CHAIN (innerc),
   10579              :                                         OMP_CLAUSE__LOOPTEMP_);
   10580         6412 :               gcc_assert (innerc);
   10581              :             }
   10582         2170 :           innerc = omp_find_clause (OMP_CLAUSE_CHAIN (innerc),
   10583              :                                     OMP_CLAUSE__LOOPTEMP_);
   10584         2170 :           if (innerc)
   10585         1419 :             n2 = fold_convert (TREE_TYPE (n2),
   10586              :                                lookup_decl (OMP_CLAUSE_DECL (innerc),
   10587              :                                             taskreg_ctx));
   10588              :         }
   10589              :     }
   10590        46888 :   cond = build2 (cond_code, boolean_type_node, fd->loop.v, n2);
   10591              : 
   10592        46888 :   clauses = gimple_omp_for_clauses (fd->for_stmt);
   10593        46888 :   stmts = NULL;
   10594        46888 :   lower_lastprivate_clauses (clauses, cond, body_p, &stmts, clist, ctx);
   10595        46888 :   if (!gimple_seq_empty_p (stmts))
   10596              :     {
   10597        16362 :       gimple_seq_add_seq (&stmts, *dlist);
   10598        16362 :       *dlist = stmts;
   10599              : 
   10600              :       /* Optimize: v = 0; is usually cheaper than v = some_other_constant.  */
   10601        16362 :       vinit = fd->loop.n1;
   10602        16362 :       if (cond_code == EQ_EXPR
   10603        14375 :           && tree_fits_shwi_p (fd->loop.n2)
   10604        25923 :           && ! integer_zerop (fd->loop.n2))
   10605         8345 :         vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
   10606              :       else
   10607         8017 :         vinit = unshare_expr (vinit);
   10608              : 
   10609              :       /* Initialize the iterator variable, so that threads that don't execute
   10610              :          any iterations don't execute the lastprivate clauses by accident.  */
   10611        16362 :       gimplify_assign (fd->loop.v, vinit, body_p);
   10612              :     }
   10613        46888 : }
   10614              : 
   10615              : /* OpenACC privatization.
   10616              : 
   10617              :    Or, in other words, *sharing* at the respective OpenACC level of
   10618              :    parallelism.
   10619              : 
   10620              :    From a correctness perspective, a non-addressable variable can't be accessed
   10621              :    outside the current thread, so it can go in a (faster than shared memory)
   10622              :    register -- though that register may need to be broadcast in some
   10623              :    circumstances.  A variable can only meaningfully be "shared" across workers
   10624              :    or vector lanes if its address is taken, e.g. by a call to an atomic
   10625              :    builtin.
   10626              : 
   10627              :    From an optimisation perspective, the answer might be fuzzier: maybe
   10628              :    sometimes, using shared memory directly would be faster than
   10629              :    broadcasting.  */
   10630              : 
   10631              : static void
   10632        18997 : oacc_privatization_begin_diagnose_var (const dump_flags_t l_dump_flags,
   10633              :                                        const location_t loc, const tree c,
   10634              :                                        const tree decl)
   10635              : {
   10636        18997 :   const dump_user_location_t d_u_loc
   10637        18997 :     = dump_user_location_t::from_location_t (loc);
   10638              : /* PR100695 "Format decoder, quoting in 'dump_printf' etc." */
   10639              : #if __GNUC__ >= 10
   10640        18997 : # pragma GCC diagnostic push
   10641        18997 : # pragma GCC diagnostic ignored "-Wformat"
   10642              : #endif
   10643        18997 :   dump_printf_loc (l_dump_flags, d_u_loc,
   10644              :                    "variable %<%T%> ", decl);
   10645              : #if __GNUC__ >= 10
   10646        18997 : # pragma GCC diagnostic pop
   10647              : #endif
   10648        18997 :   if (c)
   10649         2797 :     dump_printf (l_dump_flags,
   10650              :                  "in %qs clause ",
   10651         2797 :                  omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
   10652              :   else
   10653        16200 :     dump_printf (l_dump_flags,
   10654              :                  "declared in block ");
   10655        18997 : }
   10656              : 
   10657              : static bool
   10658        41114 : oacc_privatization_candidate_p (const location_t loc, const tree c,
   10659              :                                 const tree decl)
   10660              : {
   10661        41114 :   dump_flags_t l_dump_flags = get_openacc_privatization_dump_flags ();
   10662              : 
   10663              :   /* There is some differentiation depending on block vs. clause.  */
   10664        41114 :   bool block = !c;
   10665              : 
   10666        41114 :   bool res = true;
   10667              : 
   10668        41114 :   if (res && !VAR_P (decl))
   10669              :     {
   10670              :       /* A PARM_DECL (appearing in a 'private' clause) is expected to have been
   10671              :          privatized into a new VAR_DECL.  */
   10672          712 :       gcc_checking_assert (TREE_CODE (decl) != PARM_DECL);
   10673              : 
   10674          712 :       res = false;
   10675              : 
   10676          712 :       if (dump_enabled_p ())
   10677              :         {
   10678          683 :           oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
   10679          683 :           dump_printf (l_dump_flags,
   10680              :                        "potentially has improper OpenACC privatization level: %qs\n",
   10681          683 :                        get_tree_code_name (TREE_CODE (decl)));
   10682              :         }
   10683              :     }
   10684              : 
   10685        41085 :   if (res && block && TREE_STATIC (decl))
   10686              :     {
   10687           53 :       res = false;
   10688              : 
   10689           53 :       if (dump_enabled_p ())
   10690              :         {
   10691           28 :           oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
   10692           28 :           dump_printf (l_dump_flags,
   10693              :                        "isn%'t candidate for adjusting OpenACC privatization level: %s\n",
   10694              :                        "static");
   10695              :         }
   10696              :     }
   10697              : 
   10698        41089 :   if (res && block && DECL_EXTERNAL (decl))
   10699              :     {
   10700           12 :       res = false;
   10701              : 
   10702           12 :       if (dump_enabled_p ())
   10703              :         {
   10704           12 :           oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
   10705           12 :           dump_printf (l_dump_flags,
   10706              :                        "isn%'t candidate for adjusting OpenACC privatization level: %s\n",
   10707              :                        "external");
   10708              :         }
   10709              :     }
   10710              : 
   10711        41114 :   if (res && !TREE_ADDRESSABLE (decl))
   10712              :     {
   10713        39245 :       res = false;
   10714              : 
   10715        39245 :       if (dump_enabled_p ())
   10716              :         {
   10717        17456 :           oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
   10718        17456 :           dump_printf (l_dump_flags,
   10719              :                        "isn%'t candidate for adjusting OpenACC privatization level: %s\n",
   10720              :                        "not addressable");
   10721              :         }
   10722              :     }
   10723              : 
   10724              :   /* If an artificial variable has been added to a bind, e.g.
   10725              :      a compiler-generated temporary structure used by the Fortran front-end, do
   10726              :      not consider it as a privatization candidate.  Note that variables on
   10727              :      the stack are private per-thread by default: making them "gang-private"
   10728              :      for OpenACC actually means to share a single instance of a variable
   10729              :      amongst all workers and threads spawned within each gang.
   10730              :      At present, no compiler-generated artificial variables require such
   10731              :      sharing semantics, so this is safe.  */
   10732              : 
   10733        18548 :   if (res && block && DECL_ARTIFICIAL (decl))
   10734              :     {
   10735          548 :       res = false;
   10736              : 
   10737          548 :       if (dump_enabled_p ())
   10738              :         {
   10739          360 :           oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
   10740          360 :           dump_printf (l_dump_flags,
   10741              :                        "isn%'t candidate for adjusting OpenACC privatization "
   10742              :                        "level: %s\n", "artificial");
   10743              :         }
   10744              :     }
   10745              : 
   10746        40926 :   if (res)
   10747              :     {
   10748          544 :       if (dump_enabled_p ())
   10749              :         {
   10750          458 :           oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
   10751          458 :           dump_printf (l_dump_flags,
   10752              :                        "is candidate for adjusting OpenACC privatization level\n");
   10753              :         }
   10754              :     }
   10755              : 
   10756        41114 :   if (dump_file && (dump_flags & TDF_DETAILS))
   10757              :     {
   10758            0 :       print_generic_decl (dump_file, decl, dump_flags);
   10759            0 :       fprintf (dump_file, "\n");
   10760              :     }
   10761              : 
   10762        41114 :   return res;
   10763              : }
   10764              : 
   10765              : /* Scan CLAUSES for candidates for adjusting OpenACC privatization level in
   10766              :    CTX.  */
   10767              : 
   10768              : static void
   10769        11325 : oacc_privatization_scan_clause_chain (omp_context *ctx, tree clauses)
   10770              : {
   10771        35223 :   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   10772        23898 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE)
   10773              :       {
   10774        12986 :         tree decl = OMP_CLAUSE_DECL (c);
   10775              : 
   10776        12986 :         tree new_decl = lookup_decl (decl, ctx);
   10777              : 
   10778        12986 :         if (!oacc_privatization_candidate_p (OMP_CLAUSE_LOCATION (c), c,
   10779              :                                              new_decl))
   10780        12654 :           continue;
   10781              : 
   10782          332 :         gcc_checking_assert
   10783              :           (!ctx->oacc_privatization_candidates.contains (new_decl));
   10784          332 :         ctx->oacc_privatization_candidates.safe_push (new_decl);
   10785              :       }
   10786        11325 : }
   10787              : 
   10788              : /* Scan DECLS for candidates for adjusting OpenACC privatization level in
   10789              :    CTX.  */
   10790              : 
   10791              : static void
   10792        23090 : oacc_privatization_scan_decl_chain (omp_context *ctx, tree decls)
   10793              : {
   10794        51218 :   for (tree decl = decls; decl; decl = DECL_CHAIN (decl))
   10795              :     {
   10796        28128 :       tree new_decl = lookup_decl (decl, ctx);
   10797        28128 :       gcc_checking_assert (new_decl == decl);
   10798              : 
   10799        28128 :       if (!oacc_privatization_candidate_p (gimple_location (ctx->stmt), NULL,
   10800              :                                            new_decl))
   10801        27916 :         continue;
   10802              : 
   10803          212 :       gcc_checking_assert
   10804              :         (!ctx->oacc_privatization_candidates.contains (new_decl));
   10805          212 :       ctx->oacc_privatization_candidates.safe_push (new_decl);
   10806              :     }
   10807        23090 : }
   10808              : 
   10809              : /* Callback for walk_gimple_seq.  Find #pragma omp scan statement.  */
   10810              : 
   10811              : static tree
   10812         2225 : omp_find_scan (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
   10813              :                struct walk_stmt_info *wi)
   10814              : {
   10815         2225 :   gimple *stmt = gsi_stmt (*gsi_p);
   10816              : 
   10817         2225 :   *handled_ops_p = true;
   10818         2225 :   switch (gimple_code (stmt))
   10819              :     {
   10820          418 :     WALK_SUBSTMTS;
   10821              : 
   10822          166 :     case GIMPLE_OMP_FOR:
   10823          166 :       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD
   10824          166 :           && gimple_omp_for_combined_into_p (stmt))
   10825          166 :         *handled_ops_p = false;
   10826              :       break;
   10827              : 
   10828          678 :     case GIMPLE_OMP_SCAN:
   10829          678 :       *(gimple_stmt_iterator *) (wi->info) = *gsi_p;
   10830          678 :       return integer_zero_node;
   10831              :     default:
   10832              :       break;
   10833              :     }
   10834              :   return NULL;
   10835              : }
   10836              : 
   10837              : /* Helper function for lower_omp_for, add transformations for a worksharing
   10838              :    loop with scan directives inside of it.
   10839              :    For worksharing loop not combined with simd, transform:
   10840              :    #pragma omp for reduction(inscan,+:r) private(i)
   10841              :    for (i = 0; i < n; i = i + 1)
   10842              :      {
   10843              :        {
   10844              :          update (r);
   10845              :        }
   10846              :        #pragma omp scan inclusive(r)
   10847              :        {
   10848              :          use (r);
   10849              :        }
   10850              :      }
   10851              : 
   10852              :    into two worksharing loops + code to merge results:
   10853              : 
   10854              :    num_threads = omp_get_num_threads ();
   10855              :    thread_num = omp_get_thread_num ();
   10856              :    if (thread_num == 0) goto <D.2099>; else goto <D.2100>;
   10857              :    <D.2099>:
   10858              :    var2 = r;
   10859              :    goto <D.2101>;
   10860              :    <D.2100>:
   10861              :    // For UDRs this is UDR init, or if ctors are needed, copy from
   10862              :    // var3 that has been constructed to contain the neutral element.
   10863              :    var2 = 0;
   10864              :    <D.2101>:
   10865              :    ivar = 0;
   10866              :    // The _scantemp_ clauses will arrange for rpriva to be initialized to
   10867              :    // a shared array with num_threads elements and rprivb to a local array
   10868              :    // number of elements equal to the number of (contiguous) iterations the
   10869              :    // current thread will perform.  controlb and controlp variables are
   10870              :    // temporaries to handle deallocation of rprivb at the end of second
   10871              :    // GOMP_FOR.
   10872              :    #pragma omp for _scantemp_(rpriva) _scantemp_(rprivb) _scantemp_(controlb) \
   10873              :      _scantemp_(controlp) reduction(inscan,+:r) private(i) nowait
   10874              :    for (i = 0; i < n; i = i + 1)
   10875              :      {
   10876              :        {
   10877              :          // For UDRs this is UDR init or copy from var3.
   10878              :          r = 0;
   10879              :          // This is the input phase from user code.
   10880              :          update (r);
   10881              :        }
   10882              :        {
   10883              :          // For UDRs this is UDR merge.
   10884              :          var2 = var2 + r;
   10885              :          // Rather than handing it over to the user, save to local thread's
   10886              :          // array.
   10887              :          rprivb[ivar] = var2;
   10888              :          // For exclusive scan, the above two statements are swapped.
   10889              :          ivar = ivar + 1;
   10890              :        }
   10891              :      }
   10892              :    // And remember the final value from this thread's into the shared
   10893              :    // rpriva array.
   10894              :    rpriva[(sizetype) thread_num] = var2;
   10895              :    // If more than one thread, compute using Work-Efficient prefix sum
   10896              :    // the inclusive parallel scan of the rpriva array.
   10897              :    if (num_threads > 1) goto <D.2102>; else goto <D.2103>;
   10898              :    <D.2102>:
   10899              :    GOMP_barrier ();
   10900              :    down = 0;
   10901              :    k = 1;
   10902              :    num_threadsu = (unsigned int) num_threads;
   10903              :    thread_numup1 = (unsigned int) thread_num + 1;
   10904              :    <D.2108>:
   10905              :    twok = k << 1;
   10906              :    if (twok > num_threadsu) goto <D.2110>; else goto <D.2111>;
   10907              :    <D.2110>:
   10908              :    down = 4294967295;
   10909              :    k = k >> 1;
   10910              :    if (k == num_threadsu) goto <D.2112>; else goto <D.2111>;
   10911              :    <D.2112>:
   10912              :    k = k >> 1;
   10913              :    <D.2111>:
   10914              :    twok = k << 1;
   10915              :    cplx = .MUL_OVERFLOW (thread_nump1, twok);
   10916              :    mul = REALPART_EXPR <cplx>;
   10917              :    ovf = IMAGPART_EXPR <cplx>;
   10918              :    if (ovf == 0) goto <D.2116>; else goto <D.2117>;
   10919              :    <D.2116>:
   10920              :    andv = k & down;
   10921              :    andvm1 = andv + 4294967295;
   10922              :    l = mul + andvm1;
   10923              :    if (l < num_threadsu) goto <D.2120>; else goto <D.2117>;
   10924              :    <D.2120>:
   10925              :    // For UDRs this is UDR merge, performed using var2 variable as temporary,
   10926              :    // i.e. var2 = rpriva[l - k]; UDR merge (var2, rpriva[l]); rpriva[l] = var2;
   10927              :    rpriva[l] = rpriva[l - k] + rpriva[l];
   10928              :    <D.2117>:
   10929              :    if (down == 0) goto <D.2121>; else goto <D.2122>;
   10930              :    <D.2121>:
   10931              :    k = k << 1;
   10932              :    goto <D.2123>;
   10933              :    <D.2122>:
   10934              :    k = k >> 1;
   10935              :    <D.2123>:
   10936              :    GOMP_barrier ();
   10937              :    if (k != 0) goto <D.2108>; else goto <D.2103>;
   10938              :    <D.2103>:
   10939              :    if (thread_num == 0) goto <D.2124>; else goto <D.2125>;
   10940              :    <D.2124>:
   10941              :    // For UDRs this is UDR init or copy from var3.
   10942              :    var2 = 0;
   10943              :    goto <D.2126>;
   10944              :    <D.2125>:
   10945              :    var2 = rpriva[thread_num - 1];
   10946              :    <D.2126>:
   10947              :    ivar = 0;
   10948              :    #pragma omp for _scantemp_(controlb) _scantemp_(controlp) \
   10949              :      reduction(inscan,+:r) private(i)
   10950              :    for (i = 0; i < n; i = i + 1)
   10951              :      {
   10952              :        {
   10953              :          // For UDRs, this is r = var2; UDR merge (r, rprivb[ivar]);
   10954              :          r = var2 + rprivb[ivar];
   10955              :        }
   10956              :        {
   10957              :          // This is the scan phase from user code.
   10958              :          use (r);
   10959              :          // Plus a bump of the iterator.
   10960              :          ivar = ivar + 1;
   10961              :        }
   10962              :      }  */
   10963              : 
   10964              : static void
   10965          173 : lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
   10966              :                     struct omp_for_data *fd, omp_context *ctx)
   10967              : {
   10968          173 :   bool is_for_simd = gimple_omp_for_combined_p (stmt);
   10969          173 :   gcc_assert (ctx->scan_inclusive || ctx->scan_exclusive);
   10970              : 
   10971          173 :   gimple_seq body = gimple_omp_body (stmt);
   10972          173 :   gimple_stmt_iterator input1_gsi = gsi_none ();
   10973          173 :   struct walk_stmt_info wi;
   10974          173 :   memset (&wi, 0, sizeof (wi));
   10975          173 :   wi.val_only = true;
   10976          173 :   wi.info = (void *) &input1_gsi;
   10977          173 :   walk_gimple_seq_mod (&body, omp_find_scan, NULL, &wi);
   10978          173 :   gcc_assert (!gsi_end_p (input1_gsi));
   10979              : 
   10980          173 :   gimple *input_stmt1 = gsi_stmt (input1_gsi);
   10981          173 :   gimple_stmt_iterator gsi = input1_gsi;
   10982          173 :   gsi_next (&gsi);
   10983          173 :   gimple_stmt_iterator scan1_gsi = gsi;
   10984          173 :   gimple *scan_stmt1 = gsi_stmt (gsi);
   10985          173 :   gcc_assert (scan_stmt1 && gimple_code (scan_stmt1) == GIMPLE_OMP_SCAN);
   10986              : 
   10987          173 :   gimple_seq input_body = gimple_omp_body (input_stmt1);
   10988          173 :   gimple_seq scan_body = gimple_omp_body (scan_stmt1);
   10989          173 :   gimple_omp_set_body (input_stmt1, NULL);
   10990          173 :   gimple_omp_set_body (scan_stmt1, NULL);
   10991          173 :   gimple_omp_set_body (stmt, NULL);
   10992              : 
   10993          173 :   gomp_for *new_stmt = as_a <gomp_for *> (gimple_copy (stmt));
   10994          173 :   gimple_seq new_body = copy_gimple_seq_and_replace_locals (body);
   10995          173 :   gimple_omp_set_body (stmt, body);
   10996          173 :   gimple_omp_set_body (input_stmt1, input_body);
   10997              : 
   10998          173 :   gimple_stmt_iterator input2_gsi = gsi_none ();
   10999          173 :   memset (&wi, 0, sizeof (wi));
   11000          173 :   wi.val_only = true;
   11001          173 :   wi.info = (void *) &input2_gsi;
   11002          173 :   walk_gimple_seq_mod (&new_body, omp_find_scan, NULL, &wi);
   11003          173 :   gcc_assert (!gsi_end_p (input2_gsi));
   11004              : 
   11005          173 :   gimple *input_stmt2 = gsi_stmt (input2_gsi);
   11006          173 :   gsi = input2_gsi;
   11007          173 :   gsi_next (&gsi);
   11008          173 :   gimple_stmt_iterator scan2_gsi = gsi;
   11009          173 :   gimple *scan_stmt2 = gsi_stmt (gsi);
   11010          173 :   gcc_assert (scan_stmt2 && gimple_code (scan_stmt2) == GIMPLE_OMP_SCAN);
   11011          173 :   gimple_omp_set_body (scan_stmt2, scan_body);
   11012              : 
   11013          173 :   gimple_stmt_iterator input3_gsi = gsi_none ();
   11014          173 :   gimple_stmt_iterator scan3_gsi = gsi_none ();
   11015          173 :   gimple_stmt_iterator input4_gsi = gsi_none ();
   11016          173 :   gimple_stmt_iterator scan4_gsi = gsi_none ();
   11017          173 :   gimple *input_stmt3 = NULL, *scan_stmt3 = NULL;
   11018          173 :   gimple *input_stmt4 = NULL, *scan_stmt4 = NULL;
   11019          173 :   omp_context *input_simd_ctx = NULL, *scan_simd_ctx = NULL;
   11020          173 :   if (is_for_simd)
   11021              :     {
   11022           83 :       memset (&wi, 0, sizeof (wi));
   11023           83 :       wi.val_only = true;
   11024           83 :       wi.info = (void *) &input3_gsi;
   11025           83 :       walk_gimple_seq_mod (&input_body, omp_find_scan, NULL, &wi);
   11026           83 :       gcc_assert (!gsi_end_p (input3_gsi));
   11027              : 
   11028           83 :       input_stmt3 = gsi_stmt (input3_gsi);
   11029           83 :       gsi = input3_gsi;
   11030           83 :       gsi_next (&gsi);
   11031           83 :       scan3_gsi = gsi;
   11032           83 :       scan_stmt3 = gsi_stmt (gsi);
   11033           83 :       gcc_assert (scan_stmt3 && gimple_code (scan_stmt3) == GIMPLE_OMP_SCAN);
   11034              : 
   11035           83 :       memset (&wi, 0, sizeof (wi));
   11036           83 :       wi.val_only = true;
   11037           83 :       wi.info = (void *) &input4_gsi;
   11038           83 :       walk_gimple_seq_mod (&scan_body, omp_find_scan, NULL, &wi);
   11039           83 :       gcc_assert (!gsi_end_p (input4_gsi));
   11040              : 
   11041           83 :       input_stmt4 = gsi_stmt (input4_gsi);
   11042           83 :       gsi = input4_gsi;
   11043           83 :       gsi_next (&gsi);
   11044           83 :       scan4_gsi = gsi;
   11045           83 :       scan_stmt4 = gsi_stmt (gsi);
   11046           83 :       gcc_assert (scan_stmt4 && gimple_code (scan_stmt4) == GIMPLE_OMP_SCAN);
   11047              : 
   11048           83 :       input_simd_ctx = maybe_lookup_ctx (input_stmt3)->outer;
   11049           83 :       scan_simd_ctx = maybe_lookup_ctx (input_stmt4)->outer;
   11050              :     }
   11051              : 
   11052          173 :   tree num_threads = create_tmp_var (integer_type_node);
   11053          173 :   tree thread_num = create_tmp_var (integer_type_node);
   11054          173 :   tree nthreads_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
   11055          173 :   tree threadnum_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
   11056          173 :   gimple *g = gimple_build_call (nthreads_decl, 0);
   11057          173 :   gimple_call_set_lhs (g, num_threads);
   11058          173 :   gimple_seq_add_stmt (body_p, g);
   11059          173 :   g = gimple_build_call (threadnum_decl, 0);
   11060          173 :   gimple_call_set_lhs (g, thread_num);
   11061          173 :   gimple_seq_add_stmt (body_p, g);
   11062              : 
   11063          173 :   tree ivar = create_tmp_var (sizetype);
   11064          173 :   tree new_clauses1 = NULL_TREE, new_clauses2 = NULL_TREE;
   11065          173 :   tree *cp1 = &new_clauses1, *cp2 = &new_clauses2;
   11066          173 :   tree k = create_tmp_var (unsigned_type_node);
   11067          173 :   tree l = create_tmp_var (unsigned_type_node);
   11068              : 
   11069          173 :   gimple_seq clist = NULL, mdlist = NULL;
   11070          173 :   gimple_seq thr01_list = NULL, thrn1_list = NULL;
   11071          173 :   gimple_seq thr02_list = NULL, thrn2_list = NULL;
   11072          173 :   gimple_seq scan1_list = NULL, input2_list = NULL;
   11073          173 :   gimple_seq last_list = NULL, reduc_list = NULL;
   11074          674 :   for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
   11075          501 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   11076          501 :         && OMP_CLAUSE_REDUCTION_INSCAN (c))
   11077              :       {
   11078          205 :         location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   11079          205 :         tree var = OMP_CLAUSE_DECL (c);
   11080          205 :         tree new_var = lookup_decl (var, ctx);
   11081          205 :         tree var3 = NULL_TREE;
   11082          205 :         tree new_vard = new_var;
   11083          205 :         if (omp_privatize_by_reference (var))
   11084           32 :           new_var = build_simple_mem_ref_loc (clause_loc, new_var);
   11085          205 :         if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   11086              :           {
   11087           64 :             var3 = maybe_lookup_decl (new_vard, ctx);
   11088           64 :             if (var3 == new_vard)
   11089          173 :               var3 = NULL_TREE;
   11090              :           }
   11091              : 
   11092          205 :         tree ptype = build_pointer_type (TREE_TYPE (new_var));
   11093          205 :         tree rpriva = create_tmp_var (ptype);
   11094          205 :         tree nc = build_omp_clause (clause_loc, OMP_CLAUSE__SCANTEMP_);
   11095          205 :         OMP_CLAUSE_DECL (nc) = rpriva;
   11096          205 :         *cp1 = nc;
   11097          205 :         cp1 = &OMP_CLAUSE_CHAIN (nc);
   11098              : 
   11099          205 :         tree rprivb = create_tmp_var (ptype);
   11100          205 :         nc = build_omp_clause (clause_loc, OMP_CLAUSE__SCANTEMP_);
   11101          205 :         OMP_CLAUSE_DECL (nc) = rprivb;
   11102          205 :         OMP_CLAUSE__SCANTEMP__ALLOC (nc) = 1;
   11103          205 :         *cp1 = nc;
   11104          205 :         cp1 = &OMP_CLAUSE_CHAIN (nc);
   11105              : 
   11106          205 :         tree var2 = create_tmp_var_raw (TREE_TYPE (new_var));
   11107          205 :         if (new_vard != new_var)
   11108           32 :           TREE_ADDRESSABLE (var2) = 1;
   11109          205 :         gimple_add_tmp_var (var2);
   11110              : 
   11111          205 :         tree x = fold_convert_loc (clause_loc, sizetype, thread_num);
   11112          205 :         x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, x,
   11113          205 :                              TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
   11114          205 :         x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rpriva), rpriva, x);
   11115          205 :         tree rpriva_ref = build_simple_mem_ref_loc (clause_loc, x);
   11116              : 
   11117          205 :         x = fold_build2_loc (clause_loc, PLUS_EXPR, integer_type_node,
   11118              :                              thread_num, integer_minus_one_node);
   11119          205 :         x = fold_convert_loc (clause_loc, sizetype, x);
   11120          205 :         x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, x,
   11121          205 :                              TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
   11122          205 :         x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rpriva), rpriva, x);
   11123          205 :         tree rprivam1_ref = build_simple_mem_ref_loc (clause_loc, x);
   11124              : 
   11125          205 :         x = fold_convert_loc (clause_loc, sizetype, l);
   11126          205 :         x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, x,
   11127          205 :                              TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
   11128          205 :         x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rpriva), rpriva, x);
   11129          205 :         tree rprival_ref = build_simple_mem_ref_loc (clause_loc, x);
   11130              : 
   11131          205 :         x = fold_build2_loc (clause_loc, MINUS_EXPR, unsigned_type_node, l, k);
   11132          205 :         x = fold_convert_loc (clause_loc, sizetype, x);
   11133          205 :         x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, x,
   11134          205 :                              TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
   11135          205 :         x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rpriva), rpriva, x);
   11136          205 :         tree rprivalmk_ref = build_simple_mem_ref_loc (clause_loc, x);
   11137              : 
   11138          205 :         x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, ivar,
   11139          205 :                              TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
   11140          205 :         x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rprivb), rprivb, x);
   11141          205 :         tree rprivb_ref = build_simple_mem_ref_loc (clause_loc, x);
   11142              : 
   11143          205 :         tree var4 = is_for_simd ? new_var : var2;
   11144           99 :         tree var5 = NULL_TREE, var6 = NULL_TREE;
   11145           99 :         if (is_for_simd)
   11146              :           {
   11147           99 :             var5 = lookup_decl (var, input_simd_ctx);
   11148           99 :             var6 = lookup_decl (var, scan_simd_ctx);
   11149           99 :             if (new_vard != new_var)
   11150              :               {
   11151           16 :                 var5 = build_simple_mem_ref_loc (clause_loc, var5);
   11152           16 :                 var6 = build_simple_mem_ref_loc (clause_loc, var6);
   11153              :               }
   11154              :           }
   11155          205 :         if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   11156              :           {
   11157           64 :             tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
   11158           64 :             tree val = var2;
   11159              : 
   11160           64 :             x = lang_hooks.decls.omp_clause_default_ctor
   11161           64 :                     (c, var2, build_outer_var_ref (var, ctx));
   11162           64 :             if (x)
   11163           32 :               gimplify_and_add (x, &clist);
   11164              : 
   11165           64 :             x = build_outer_var_ref (var, ctx);
   11166           64 :             x = lang_hooks.decls.omp_clause_assign_op (c, unshare_expr (var4),
   11167              :                                                        x);
   11168           64 :             gimplify_and_add (x, &thr01_list);
   11169              : 
   11170           64 :             tree y = (DECL_HAS_VALUE_EXPR_P (new_vard)
   11171           64 :                       ? DECL_VALUE_EXPR (new_vard) : NULL_TREE);
   11172           64 :             if (var3)
   11173              :               {
   11174           32 :                 x = unshare_expr (var4);
   11175           32 :                 x = lang_hooks.decls.omp_clause_assign_op (c, x, var3);
   11176           32 :                 gimplify_and_add (x, &thrn1_list);
   11177           32 :                 x = unshare_expr (var4);
   11178           32 :                 x = lang_hooks.decls.omp_clause_assign_op (c, x, var3);
   11179           32 :                 gimplify_and_add (x, &thr02_list);
   11180              :               }
   11181           32 :             else if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
   11182              :               {
   11183              :                 /* Otherwise, assign to it the identity element.  */
   11184           32 :                 gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
   11185           32 :                 tseq = copy_gimple_seq_and_replace_locals (tseq);
   11186           32 :                 if (!is_for_simd)
   11187              :                   {
   11188           16 :                     if (new_vard != new_var)
   11189            4 :                       val = build_fold_addr_expr_loc (clause_loc, val);
   11190           16 :                     SET_DECL_VALUE_EXPR (new_vard, val);
   11191           16 :                     DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
   11192              :                   }
   11193           32 :                 SET_DECL_VALUE_EXPR (placeholder, error_mark_node);
   11194           32 :                 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
   11195           32 :                 lower_omp (&tseq, ctx);
   11196           32 :                 gimple_seq_add_seq (&thrn1_list, tseq);
   11197           32 :                 tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
   11198           32 :                 lower_omp (&tseq, ctx);
   11199           32 :                 gimple_seq_add_seq (&thr02_list, tseq);
   11200           32 :                 SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
   11201           32 :                 DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
   11202           32 :                 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
   11203           32 :                 if (y)
   11204            0 :                   SET_DECL_VALUE_EXPR (new_vard, y);
   11205              :                 else
   11206              :                   {
   11207           32 :                     DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
   11208           32 :                     SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
   11209              :                   }
   11210              :               }
   11211              : 
   11212           64 :             x = unshare_expr (var4);
   11213           64 :             x = lang_hooks.decls.omp_clause_assign_op (c, x, rprivam1_ref);
   11214           64 :             gimplify_and_add (x, &thrn2_list);
   11215              : 
   11216           64 :             if (is_for_simd)
   11217              :               {
   11218           32 :                 x = unshare_expr (rprivb_ref);
   11219           32 :                 x = lang_hooks.decls.omp_clause_assign_op (c, x, var5);
   11220           32 :                 gimplify_and_add (x, &scan1_list);
   11221              :               }
   11222              :             else
   11223              :               {
   11224           32 :                 if (ctx->scan_exclusive)
   11225              :                   {
   11226           16 :                     x = unshare_expr (rprivb_ref);
   11227           16 :                     x = lang_hooks.decls.omp_clause_assign_op (c, x, var2);
   11228           16 :                     gimplify_and_add (x, &scan1_list);
   11229              :                   }
   11230              : 
   11231           32 :                 gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
   11232           32 :                 tseq = copy_gimple_seq_and_replace_locals (tseq);
   11233           32 :                 SET_DECL_VALUE_EXPR (placeholder, var2);
   11234           32 :                 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
   11235           32 :                 lower_omp (&tseq, ctx);
   11236           32 :                 gimple_seq_add_seq (&scan1_list, tseq);
   11237              : 
   11238           32 :                 if (ctx->scan_inclusive)
   11239              :                   {
   11240           16 :                     x = unshare_expr (rprivb_ref);
   11241           16 :                     x = lang_hooks.decls.omp_clause_assign_op (c, x, var2);
   11242           16 :                     gimplify_and_add (x, &scan1_list);
   11243              :                   }
   11244              :               }
   11245              : 
   11246           64 :             x = unshare_expr (rpriva_ref);
   11247           64 :             x = lang_hooks.decls.omp_clause_assign_op (c, x,
   11248              :                                                        unshare_expr (var4));
   11249           64 :             gimplify_and_add (x, &mdlist);
   11250              : 
   11251           96 :             x = unshare_expr (is_for_simd ? var6 : new_var);
   11252           64 :             x = lang_hooks.decls.omp_clause_assign_op (c, x, var4);
   11253           64 :             gimplify_and_add (x, &input2_list);
   11254              : 
   11255           64 :             val = rprivb_ref;
   11256           64 :             if (new_vard != new_var)
   11257           24 :               val = build_fold_addr_expr_loc (clause_loc, val);
   11258              : 
   11259           64 :             gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
   11260           64 :             tseq = copy_gimple_seq_and_replace_locals (tseq);
   11261           64 :             SET_DECL_VALUE_EXPR (new_vard, val);
   11262           64 :             DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
   11263           64 :             if (is_for_simd)
   11264              :               {
   11265           32 :                 SET_DECL_VALUE_EXPR (placeholder, var6);
   11266           32 :                 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
   11267              :               }
   11268              :             else
   11269           32 :               DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
   11270           64 :             lower_omp (&tseq, ctx);
   11271           64 :             if (y)
   11272            0 :               SET_DECL_VALUE_EXPR (new_vard, y);
   11273              :             else
   11274              :               {
   11275           64 :                 DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
   11276           64 :                 SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
   11277              :               }
   11278           64 :             if (!is_for_simd)
   11279              :               {
   11280           32 :                 SET_DECL_VALUE_EXPR (placeholder, new_var);
   11281           32 :                 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
   11282           32 :                 lower_omp (&tseq, ctx);
   11283              :               }
   11284           64 :             gimple_seq_add_seq (&input2_list, tseq);
   11285              : 
   11286           64 :             x = build_outer_var_ref (var, ctx);
   11287           64 :             x = lang_hooks.decls.omp_clause_assign_op (c, x, rpriva_ref);
   11288           64 :             gimplify_and_add (x, &last_list);
   11289              : 
   11290           64 :             x = lang_hooks.decls.omp_clause_assign_op (c, var2, rprivalmk_ref);
   11291           64 :             gimplify_and_add (x, &reduc_list);
   11292           64 :             tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
   11293           64 :             tseq = copy_gimple_seq_and_replace_locals (tseq);
   11294           64 :             val = rprival_ref;
   11295           64 :             if (new_vard != new_var)
   11296           24 :               val = build_fold_addr_expr_loc (clause_loc, val);
   11297           64 :             SET_DECL_VALUE_EXPR (new_vard, val);
   11298           64 :             DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
   11299           64 :             SET_DECL_VALUE_EXPR (placeholder, var2);
   11300           64 :             lower_omp (&tseq, ctx);
   11301           64 :             OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
   11302           64 :             SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
   11303           64 :             DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
   11304           64 :             if (y)
   11305            0 :               SET_DECL_VALUE_EXPR (new_vard, y);
   11306              :             else
   11307              :               {
   11308           64 :                 DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
   11309           64 :                 SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
   11310              :               }
   11311           64 :             gimple_seq_add_seq (&reduc_list, tseq);
   11312           64 :             x = lang_hooks.decls.omp_clause_assign_op (c, rprival_ref, var2);
   11313           64 :             gimplify_and_add (x, &reduc_list);
   11314              : 
   11315           64 :             x = lang_hooks.decls.omp_clause_dtor (c, var2);
   11316           64 :             if (x)
   11317           32 :               gimplify_and_add (x, dlist);
   11318              :           }
   11319              :         else
   11320              :           {
   11321          141 :             x = build_outer_var_ref (var, ctx);
   11322          141 :             gimplify_assign (unshare_expr (var4), x, &thr01_list);
   11323              : 
   11324          141 :             x = omp_reduction_init (c, TREE_TYPE (new_var));
   11325          141 :             gimplify_assign (unshare_expr (var4), unshare_expr (x),
   11326              :                              &thrn1_list);
   11327          141 :             gimplify_assign (unshare_expr (var4), x, &thr02_list);
   11328              : 
   11329          141 :             gimplify_assign (unshare_expr (var4), rprivam1_ref, &thrn2_list);
   11330              : 
   11331          141 :             enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
   11332          141 :             if (code == MINUS_EXPR)
   11333            0 :               code = PLUS_EXPR;
   11334              : 
   11335          141 :             if (is_for_simd)
   11336           67 :               gimplify_assign (unshare_expr (rprivb_ref), var5, &scan1_list);
   11337              :             else
   11338              :               {
   11339           74 :                 if (ctx->scan_exclusive)
   11340           28 :                   gimplify_assign (unshare_expr (rprivb_ref), var2,
   11341              :                                    &scan1_list);
   11342           74 :                 x = build2 (code, TREE_TYPE (new_var), var2, new_var);
   11343           74 :                 gimplify_assign (var2, x, &scan1_list);
   11344           74 :                 if (ctx->scan_inclusive)
   11345           46 :                   gimplify_assign (unshare_expr (rprivb_ref), var2,
   11346              :                                    &scan1_list);
   11347              :               }
   11348              : 
   11349          141 :             gimplify_assign (unshare_expr (rpriva_ref), unshare_expr (var4),
   11350              :                              &mdlist);
   11351              : 
   11352          141 :             x = build2 (code, TREE_TYPE (new_var), var4, rprivb_ref);
   11353          215 :             gimplify_assign (is_for_simd ? var6 : new_var, x, &input2_list);
   11354              : 
   11355          141 :             gimplify_assign (build_outer_var_ref (var, ctx), rpriva_ref,
   11356              :                              &last_list);
   11357              : 
   11358          141 :             x = build2 (code, TREE_TYPE (new_var), rprivalmk_ref,
   11359              :                         unshare_expr (rprival_ref));
   11360          141 :             gimplify_assign (rprival_ref, x, &reduc_list);
   11361              :           }
   11362              :       }
   11363              : 
   11364          173 :   g = gimple_build_assign (ivar, PLUS_EXPR, ivar, size_one_node);
   11365          173 :   gimple_seq_add_stmt (&scan1_list, g);
   11366          173 :   g = gimple_build_assign (ivar, PLUS_EXPR, ivar, size_one_node);
   11367          263 :   gimple_seq_add_stmt (gimple_omp_body_ptr (is_for_simd
   11368              :                                             ? scan_stmt4 : scan_stmt2), g);
   11369              : 
   11370          173 :   tree controlb = create_tmp_var (boolean_type_node);
   11371          173 :   tree controlp = create_tmp_var (ptr_type_node);
   11372          173 :   tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SCANTEMP_);
   11373          173 :   OMP_CLAUSE_DECL (nc) = controlb;
   11374          173 :   OMP_CLAUSE__SCANTEMP__CONTROL (nc) = 1;
   11375          173 :   *cp1 = nc;
   11376          173 :   cp1 = &OMP_CLAUSE_CHAIN (nc);
   11377          173 :   nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SCANTEMP_);
   11378          173 :   OMP_CLAUSE_DECL (nc) = controlp;
   11379          173 :   OMP_CLAUSE__SCANTEMP__CONTROL (nc) = 1;
   11380          173 :   *cp1 = nc;
   11381          173 :   cp1 = &OMP_CLAUSE_CHAIN (nc);
   11382          173 :   nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SCANTEMP_);
   11383          173 :   OMP_CLAUSE_DECL (nc) = controlb;
   11384          173 :   OMP_CLAUSE__SCANTEMP__CONTROL (nc) = 1;
   11385          173 :   *cp2 = nc;
   11386          173 :   cp2 = &OMP_CLAUSE_CHAIN (nc);
   11387          173 :   nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SCANTEMP_);
   11388          173 :   OMP_CLAUSE_DECL (nc) = controlp;
   11389          173 :   OMP_CLAUSE__SCANTEMP__CONTROL (nc) = 1;
   11390          173 :   *cp2 = nc;
   11391          173 :   cp2 = &OMP_CLAUSE_CHAIN (nc);
   11392              : 
   11393          173 :   *cp1 = gimple_omp_for_clauses (stmt);
   11394          173 :   gimple_omp_for_set_clauses (stmt, new_clauses1);
   11395          173 :   *cp2 = gimple_omp_for_clauses (new_stmt);
   11396          173 :   gimple_omp_for_set_clauses (new_stmt, new_clauses2);
   11397              : 
   11398          173 :   if (is_for_simd)
   11399              :     {
   11400           83 :       gimple_seq_add_seq (gimple_omp_body_ptr (scan_stmt3), scan1_list);
   11401           83 :       gimple_seq_add_seq (gimple_omp_body_ptr (input_stmt4), input2_list);
   11402              : 
   11403           83 :       gsi_insert_seq_after (&input3_gsi, gimple_omp_body (input_stmt3),
   11404              :                             GSI_SAME_STMT);
   11405           83 :       gsi_remove (&input3_gsi, true);
   11406           83 :       gsi_insert_seq_after (&scan3_gsi, gimple_omp_body (scan_stmt3),
   11407              :                             GSI_SAME_STMT);
   11408           83 :       gsi_remove (&scan3_gsi, true);
   11409           83 :       gsi_insert_seq_after (&input4_gsi, gimple_omp_body (input_stmt4),
   11410              :                             GSI_SAME_STMT);
   11411           83 :       gsi_remove (&input4_gsi, true);
   11412           83 :       gsi_insert_seq_after (&scan4_gsi, gimple_omp_body (scan_stmt4),
   11413              :                             GSI_SAME_STMT);
   11414           83 :       gsi_remove (&scan4_gsi, true);
   11415              :     }
   11416              :   else
   11417              :     {
   11418           90 :       gimple_omp_set_body (scan_stmt1, scan1_list);
   11419           90 :       gimple_omp_set_body (input_stmt2, input2_list);
   11420              :     }
   11421              : 
   11422          173 :   gsi_insert_seq_after (&input1_gsi, gimple_omp_body (input_stmt1),
   11423              :                         GSI_SAME_STMT);
   11424          173 :   gsi_remove (&input1_gsi, true);
   11425          173 :   gsi_insert_seq_after (&scan1_gsi, gimple_omp_body (scan_stmt1),
   11426              :                         GSI_SAME_STMT);
   11427          173 :   gsi_remove (&scan1_gsi, true);
   11428          173 :   gsi_insert_seq_after (&input2_gsi, gimple_omp_body (input_stmt2),
   11429              :                         GSI_SAME_STMT);
   11430          173 :   gsi_remove (&input2_gsi, true);
   11431          173 :   gsi_insert_seq_after (&scan2_gsi, gimple_omp_body (scan_stmt2),
   11432              :                         GSI_SAME_STMT);
   11433          173 :   gsi_remove (&scan2_gsi, true);
   11434              : 
   11435          173 :   gimple_seq_add_seq (body_p, clist);
   11436              : 
   11437          173 :   tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
   11438          173 :   tree lab2 = create_artificial_label (UNKNOWN_LOCATION);
   11439          173 :   tree lab3 = create_artificial_label (UNKNOWN_LOCATION);
   11440          173 :   g = gimple_build_cond (EQ_EXPR, thread_num, integer_zero_node, lab1, lab2);
   11441          173 :   gimple_seq_add_stmt (body_p, g);
   11442          173 :   g = gimple_build_label (lab1);
   11443          173 :   gimple_seq_add_stmt (body_p, g);
   11444          173 :   gimple_seq_add_seq (body_p, thr01_list);
   11445          173 :   g = gimple_build_goto (lab3);
   11446          173 :   gimple_seq_add_stmt (body_p, g);
   11447          173 :   g = gimple_build_label (lab2);
   11448          173 :   gimple_seq_add_stmt (body_p, g);
   11449          173 :   gimple_seq_add_seq (body_p, thrn1_list);
   11450          173 :   g = gimple_build_label (lab3);
   11451          173 :   gimple_seq_add_stmt (body_p, g);
   11452              : 
   11453          173 :   g = gimple_build_assign (ivar, size_zero_node);
   11454          173 :   gimple_seq_add_stmt (body_p, g);
   11455              : 
   11456          173 :   gimple_seq_add_stmt (body_p, stmt);
   11457          173 :   gimple_seq_add_seq (body_p, body);
   11458          173 :   gimple_seq_add_stmt (body_p, gimple_build_omp_continue (fd->loop.v,
   11459              :                                                           fd->loop.v));
   11460              : 
   11461          173 :   g = gimple_build_omp_return (true);
   11462          173 :   gimple_seq_add_stmt (body_p, g);
   11463          173 :   gimple_seq_add_seq (body_p, mdlist);
   11464              : 
   11465          173 :   lab1 = create_artificial_label (UNKNOWN_LOCATION);
   11466          173 :   lab2 = create_artificial_label (UNKNOWN_LOCATION);
   11467          173 :   g = gimple_build_cond (GT_EXPR, num_threads, integer_one_node, lab1, lab2);
   11468          173 :   gimple_seq_add_stmt (body_p, g);
   11469          173 :   g = gimple_build_label (lab1);
   11470          173 :   gimple_seq_add_stmt (body_p, g);
   11471              : 
   11472          173 :   g = omp_build_barrier (NULL);
   11473          173 :   gimple_seq_add_stmt (body_p, g);
   11474              : 
   11475          173 :   tree down = create_tmp_var (unsigned_type_node);
   11476          173 :   g = gimple_build_assign (down, build_zero_cst (unsigned_type_node));
   11477          173 :   gimple_seq_add_stmt (body_p, g);
   11478              : 
   11479          173 :   g = gimple_build_assign (k, build_one_cst (unsigned_type_node));
   11480          173 :   gimple_seq_add_stmt (body_p, g);
   11481              : 
   11482          173 :   tree num_threadsu = create_tmp_var (unsigned_type_node);
   11483          173 :   g = gimple_build_assign (num_threadsu, NOP_EXPR, num_threads);
   11484          173 :   gimple_seq_add_stmt (body_p, g);
   11485              : 
   11486          173 :   tree thread_numu = create_tmp_var (unsigned_type_node);
   11487          173 :   g = gimple_build_assign (thread_numu, NOP_EXPR, thread_num);
   11488          173 :   gimple_seq_add_stmt (body_p, g);
   11489              : 
   11490          173 :   tree thread_nump1 = create_tmp_var (unsigned_type_node);
   11491          173 :   g = gimple_build_assign (thread_nump1, PLUS_EXPR, thread_numu,
   11492              :                            build_int_cst (unsigned_type_node, 1));
   11493          173 :   gimple_seq_add_stmt (body_p, g);
   11494              : 
   11495          173 :   lab3 = create_artificial_label (UNKNOWN_LOCATION);
   11496          173 :   g = gimple_build_label (lab3);
   11497          173 :   gimple_seq_add_stmt (body_p, g);
   11498              : 
   11499          173 :   tree twok = create_tmp_var (unsigned_type_node);
   11500          173 :   g = gimple_build_assign (twok, LSHIFT_EXPR, k, integer_one_node);
   11501          173 :   gimple_seq_add_stmt (body_p, g);
   11502              : 
   11503          173 :   tree lab4 = create_artificial_label (UNKNOWN_LOCATION);
   11504          173 :   tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
   11505          173 :   tree lab6 = create_artificial_label (UNKNOWN_LOCATION);
   11506          173 :   g = gimple_build_cond (GT_EXPR, twok, num_threadsu, lab4, lab5);
   11507          173 :   gimple_seq_add_stmt (body_p, g);
   11508          173 :   g = gimple_build_label (lab4);
   11509          173 :   gimple_seq_add_stmt (body_p, g);
   11510          173 :   g = gimple_build_assign (down, build_all_ones_cst (unsigned_type_node));
   11511          173 :   gimple_seq_add_stmt (body_p, g);
   11512          173 :   g = gimple_build_assign (k, RSHIFT_EXPR, k, integer_one_node);
   11513          173 :   gimple_seq_add_stmt (body_p, g);
   11514              : 
   11515          173 :   g = gimple_build_cond (EQ_EXPR, k, num_threadsu, lab6, lab5);
   11516          173 :   gimple_seq_add_stmt (body_p, g);
   11517          173 :   g = gimple_build_label (lab6);
   11518          173 :   gimple_seq_add_stmt (body_p, g);
   11519              : 
   11520          173 :   g = gimple_build_assign (k, RSHIFT_EXPR, k, integer_one_node);
   11521          173 :   gimple_seq_add_stmt (body_p, g);
   11522              : 
   11523          173 :   g = gimple_build_label (lab5);
   11524          173 :   gimple_seq_add_stmt (body_p, g);
   11525              : 
   11526          173 :   g = gimple_build_assign (twok, LSHIFT_EXPR, k, integer_one_node);
   11527          173 :   gimple_seq_add_stmt (body_p, g);
   11528              : 
   11529          173 :   tree cplx = create_tmp_var (build_complex_type (unsigned_type_node, false));
   11530          173 :   g = gimple_build_call_internal (IFN_MUL_OVERFLOW, 2, thread_nump1, twok);
   11531          173 :   gimple_call_set_lhs (g, cplx);
   11532          173 :   gimple_seq_add_stmt (body_p, g);
   11533          173 :   tree mul = create_tmp_var (unsigned_type_node);
   11534          173 :   g = gimple_build_assign (mul, REALPART_EXPR,
   11535              :                            build1 (REALPART_EXPR, unsigned_type_node, cplx));
   11536          173 :   gimple_seq_add_stmt (body_p, g);
   11537          173 :   tree ovf = create_tmp_var (unsigned_type_node);
   11538          173 :   g = gimple_build_assign (ovf, IMAGPART_EXPR,
   11539              :                            build1 (IMAGPART_EXPR, unsigned_type_node, cplx));
   11540          173 :   gimple_seq_add_stmt (body_p, g);
   11541              : 
   11542          173 :   tree lab7 = create_artificial_label (UNKNOWN_LOCATION);
   11543          173 :   tree lab8 = create_artificial_label (UNKNOWN_LOCATION);
   11544          173 :   g = gimple_build_cond (EQ_EXPR, ovf, build_zero_cst (unsigned_type_node),
   11545              :                          lab7, lab8);
   11546          173 :   gimple_seq_add_stmt (body_p, g);
   11547          173 :   g = gimple_build_label (lab7);
   11548          173 :   gimple_seq_add_stmt (body_p, g);
   11549              : 
   11550          173 :   tree andv = create_tmp_var (unsigned_type_node);
   11551          173 :   g = gimple_build_assign (andv, BIT_AND_EXPR, k, down);
   11552          173 :   gimple_seq_add_stmt (body_p, g);
   11553          173 :   tree andvm1 = create_tmp_var (unsigned_type_node);
   11554          173 :   g = gimple_build_assign (andvm1, PLUS_EXPR, andv,
   11555              :                            build_minus_one_cst (unsigned_type_node));
   11556          173 :   gimple_seq_add_stmt (body_p, g);
   11557              : 
   11558          173 :   g = gimple_build_assign (l, PLUS_EXPR, mul, andvm1);
   11559          173 :   gimple_seq_add_stmt (body_p, g);
   11560              : 
   11561          173 :   tree lab9 = create_artificial_label (UNKNOWN_LOCATION);
   11562          173 :   g = gimple_build_cond (LT_EXPR, l, num_threadsu, lab9, lab8);
   11563          173 :   gimple_seq_add_stmt (body_p, g);
   11564          173 :   g = gimple_build_label (lab9);
   11565          173 :   gimple_seq_add_stmt (body_p, g);
   11566          173 :   gimple_seq_add_seq (body_p, reduc_list);
   11567          173 :   g = gimple_build_label (lab8);
   11568          173 :   gimple_seq_add_stmt (body_p, g);
   11569              : 
   11570          173 :   tree lab10 = create_artificial_label (UNKNOWN_LOCATION);
   11571          173 :   tree lab11 = create_artificial_label (UNKNOWN_LOCATION);
   11572          173 :   tree lab12 = create_artificial_label (UNKNOWN_LOCATION);
   11573          173 :   g = gimple_build_cond (EQ_EXPR, down, build_zero_cst (unsigned_type_node),
   11574              :                          lab10, lab11);
   11575          173 :   gimple_seq_add_stmt (body_p, g);
   11576          173 :   g = gimple_build_label (lab10);
   11577          173 :   gimple_seq_add_stmt (body_p, g);
   11578          173 :   g = gimple_build_assign (k, LSHIFT_EXPR, k, integer_one_node);
   11579          173 :   gimple_seq_add_stmt (body_p, g);
   11580          173 :   g = gimple_build_goto (lab12);
   11581          173 :   gimple_seq_add_stmt (body_p, g);
   11582          173 :   g = gimple_build_label (lab11);
   11583          173 :   gimple_seq_add_stmt (body_p, g);
   11584          173 :   g = gimple_build_assign (k, RSHIFT_EXPR, k, integer_one_node);
   11585          173 :   gimple_seq_add_stmt (body_p, g);
   11586          173 :   g = gimple_build_label (lab12);
   11587          173 :   gimple_seq_add_stmt (body_p, g);
   11588              : 
   11589          173 :   g = omp_build_barrier (NULL);
   11590          173 :   gimple_seq_add_stmt (body_p, g);
   11591              : 
   11592          173 :   g = gimple_build_cond (NE_EXPR, k, build_zero_cst (unsigned_type_node),
   11593              :                          lab3, lab2);
   11594          173 :   gimple_seq_add_stmt (body_p, g);
   11595              : 
   11596          173 :   g = gimple_build_label (lab2);
   11597          173 :   gimple_seq_add_stmt (body_p, g);
   11598              : 
   11599          173 :   lab1 = create_artificial_label (UNKNOWN_LOCATION);
   11600          173 :   lab2 = create_artificial_label (UNKNOWN_LOCATION);
   11601          173 :   lab3 = create_artificial_label (UNKNOWN_LOCATION);
   11602          173 :   g = gimple_build_cond (EQ_EXPR, thread_num, integer_zero_node, lab1, lab2);
   11603          173 :   gimple_seq_add_stmt (body_p, g);
   11604          173 :   g = gimple_build_label (lab1);
   11605          173 :   gimple_seq_add_stmt (body_p, g);
   11606          173 :   gimple_seq_add_seq (body_p, thr02_list);
   11607          173 :   g = gimple_build_goto (lab3);
   11608          173 :   gimple_seq_add_stmt (body_p, g);
   11609          173 :   g = gimple_build_label (lab2);
   11610          173 :   gimple_seq_add_stmt (body_p, g);
   11611          173 :   gimple_seq_add_seq (body_p, thrn2_list);
   11612          173 :   g = gimple_build_label (lab3);
   11613          173 :   gimple_seq_add_stmt (body_p, g);
   11614              : 
   11615          173 :   g = gimple_build_assign (ivar, size_zero_node);
   11616          173 :   gimple_seq_add_stmt (body_p, g);
   11617          173 :   gimple_seq_add_stmt (body_p, new_stmt);
   11618          173 :   gimple_seq_add_seq (body_p, new_body);
   11619              : 
   11620          173 :   gimple_seq new_dlist = NULL;
   11621          173 :   lab1 = create_artificial_label (UNKNOWN_LOCATION);
   11622          173 :   lab2 = create_artificial_label (UNKNOWN_LOCATION);
   11623          173 :   tree num_threadsm1 = create_tmp_var (integer_type_node);
   11624          173 :   g = gimple_build_assign (num_threadsm1, PLUS_EXPR, num_threads,
   11625              :                            integer_minus_one_node);
   11626          173 :   gimple_seq_add_stmt (&new_dlist, g);
   11627          173 :   g = gimple_build_cond (EQ_EXPR, thread_num, num_threadsm1, lab1, lab2);
   11628          173 :   gimple_seq_add_stmt (&new_dlist, g);
   11629          173 :   g = gimple_build_label (lab1);
   11630          173 :   gimple_seq_add_stmt (&new_dlist, g);
   11631          173 :   gimple_seq_add_seq (&new_dlist, last_list);
   11632          173 :   g = gimple_build_label (lab2);
   11633          173 :   gimple_seq_add_stmt (&new_dlist, g);
   11634          173 :   gimple_seq_add_seq (&new_dlist, *dlist);
   11635          173 :   *dlist = new_dlist;
   11636          173 : }
   11637              : 
   11638              : /* Build an internal UNIQUE function with type IFN_UNIQUE_OACC_PRIVATE listing
   11639              :    the addresses of variables to be made private at the surrounding
   11640              :    parallelism level.  Such functions appear in the gimple code stream in two
   11641              :    forms, e.g. for a partitioned loop:
   11642              : 
   11643              :       .data_dep.6 = .UNIQUE (OACC_HEAD_MARK, .data_dep.6, 1, 68);
   11644              :       .data_dep.6 = .UNIQUE (OACC_PRIVATE, .data_dep.6, -1, &w);
   11645              :       .data_dep.6 = .UNIQUE (OACC_FORK, .data_dep.6, -1);
   11646              :       .data_dep.6 = .UNIQUE (OACC_HEAD_MARK, .data_dep.6);
   11647              : 
   11648              :    or alternatively, OACC_PRIVATE can appear at the top level of a parallel,
   11649              :    not as part of a HEAD_MARK sequence:
   11650              : 
   11651              :       .UNIQUE (OACC_PRIVATE, 0, 0, &w);
   11652              : 
   11653              :    For such stand-alone appearances, the 3rd argument is always 0, denoting
   11654              :    gang partitioning.  */
   11655              : 
   11656              : static gcall *
   11657        19728 : lower_oacc_private_marker (omp_context *ctx)
   11658              : {
   11659        19728 :   if (ctx->oacc_privatization_candidates.length () == 0)
   11660              :     return NULL;
   11661              : 
   11662          308 :   auto_vec<tree, 5> args;
   11663              : 
   11664          308 :   args.quick_push (build_int_cst (integer_type_node, IFN_UNIQUE_OACC_PRIVATE));
   11665          308 :   args.quick_push (integer_zero_node);
   11666          308 :   args.quick_push (integer_minus_one_node);
   11667              : 
   11668          308 :   int i;
   11669          308 :   tree decl;
   11670          696 :   FOR_EACH_VEC_ELT (ctx->oacc_privatization_candidates, i, decl)
   11671              :     {
   11672          388 :       gcc_checking_assert (TREE_ADDRESSABLE (decl));
   11673          388 :       tree addr = build_fold_addr_expr (decl);
   11674          388 :       args.safe_push (addr);
   11675              :     }
   11676              : 
   11677          308 :   return gimple_build_call_internal_vec (IFN_UNIQUE, args);
   11678          308 : }
   11679              : 
   11680              : /* Lower code for an OMP loop directive.  */
   11681              : 
   11682              : static void
   11683        46888 : lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   11684              : {
   11685        46888 :   tree *rhs_p, block;
   11686        46888 :   struct omp_for_data fd, *fdp = NULL;
   11687        46888 :   gomp_for *stmt = as_a <gomp_for *> (gsi_stmt (*gsi_p));
   11688        46888 :   gbind *new_stmt;
   11689        46888 :   gimple_seq omp_for_body, body, dlist, tred_ilist = NULL, tred_dlist = NULL;
   11690        46888 :   gimple_seq cnt_list = NULL, clist = NULL;
   11691        46888 :   gimple_seq oacc_head = NULL, oacc_tail = NULL;
   11692        46888 :   size_t i;
   11693              : 
   11694        46888 :   push_gimplify_context ();
   11695              : 
   11696        46888 :   if (is_gimple_omp_oacc (ctx->stmt))
   11697        11325 :     oacc_privatization_scan_clause_chain (ctx, gimple_omp_for_clauses (stmt));
   11698              : 
   11699        46888 :   lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
   11700              : 
   11701        46888 :   block = make_node (BLOCK);
   11702        46888 :   new_stmt = gimple_build_bind (NULL, NULL, block);
   11703              :   /* Replace at gsi right away, so that 'stmt' is no member
   11704              :      of a sequence anymore as we're going to add to a different
   11705              :      one below.  */
   11706        46888 :   gsi_replace (gsi_p, new_stmt, true);
   11707              : 
   11708              :   /* Move declaration of temporaries in the loop body before we make
   11709              :      it go away.  */
   11710        46888 :   omp_for_body = gimple_omp_body (stmt);
   11711        46888 :   if (!gimple_seq_empty_p (omp_for_body)
   11712        46888 :       && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
   11713              :     {
   11714        19607 :       gbind *inner_bind
   11715        19607 :         = as_a <gbind *> (gimple_seq_first_stmt (omp_for_body));
   11716        19607 :       tree vars = gimple_bind_vars (inner_bind);
   11717        19607 :       if (is_gimple_omp_oacc (ctx->stmt))
   11718         5305 :         oacc_privatization_scan_decl_chain (ctx, vars);
   11719        19607 :       gimple_bind_append_vars (new_stmt, vars);
   11720              :       /* bind_vars/BLOCK_VARS are being moved to new_stmt/block, don't
   11721              :          keep them on the inner_bind and it's block.  */
   11722        19607 :       gimple_bind_set_vars (inner_bind, NULL_TREE);
   11723        19607 :       if (gimple_bind_block (inner_bind))
   11724        17051 :         BLOCK_VARS (gimple_bind_block (inner_bind)) = NULL_TREE;
   11725              :     }
   11726              : 
   11727        46888 :   if (gimple_omp_for_combined_into_p (stmt))
   11728              :     {
   11729        14598 :       omp_extract_for_data (stmt, &fd, NULL);
   11730        14598 :       fdp = &fd;
   11731              : 
   11732              :       /* We need two temporaries with fd.loop.v type (istart/iend)
   11733              :          and then (fd.collapse - 1) temporaries with the same
   11734              :          type for count2 ... countN-1 vars if not constant.  */
   11735        14598 :       size_t count = 2;
   11736        14598 :       tree type = fd.iter_type;
   11737        14598 :       if (fd.collapse > 1
   11738         4867 :           && TREE_CODE (fd.loop.n2) != INTEGER_CST)
   11739         2692 :         count += fd.collapse - 1;
   11740        14598 :       size_t count2 = 0;
   11741        14598 :       tree type2 = NULL_TREE;
   11742        14598 :       bool taskreg_for
   11743        14598 :         = (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR
   11744        14598 :            || gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_TASKLOOP);
   11745        14598 :       tree outerc = NULL, *pc = gimple_omp_for_clauses_ptr (stmt);
   11746        14598 :       tree simtc = NULL;
   11747        14598 :       tree clauses = *pc;
   11748        14598 :       if (fd.collapse > 1
   11749         4867 :           && fd.non_rect
   11750          137 :           && fd.last_nonrect == fd.first_nonrect + 1
   11751           89 :           && TREE_CODE (fd.loop.n2) != INTEGER_CST)
   11752           64 :         if (tree v = gimple_omp_for_index (stmt, fd.last_nonrect))
   11753           64 :           if (!TYPE_UNSIGNED (TREE_TYPE (v)))
   11754              :             {
   11755           60 :               v = gimple_omp_for_index (stmt, fd.first_nonrect);
   11756           60 :               type2 = TREE_TYPE (v);
   11757           60 :               count++;
   11758           60 :               count2 = 3;
   11759              :             }
   11760        14598 :       if (taskreg_for)
   11761         7594 :         outerc
   11762         7594 :           = omp_find_clause (gimple_omp_taskreg_clauses (ctx->outer->stmt),
   11763              :                              OMP_CLAUSE__LOOPTEMP_);
   11764        14598 :       if (ctx->simt_stmt)
   11765            0 :         simtc = omp_find_clause (gimple_omp_for_clauses (ctx->simt_stmt),
   11766              :                                  OMP_CLAUSE__LOOPTEMP_);
   11767        49203 :       for (i = 0; i < count + count2; i++)
   11768              :         {
   11769        34605 :           tree temp;
   11770        34605 :           if (taskreg_for)
   11771              :             {
   11772        18069 :               gcc_assert (outerc);
   11773        18069 :               temp = lookup_decl (OMP_CLAUSE_DECL (outerc), ctx->outer);
   11774        18069 :               outerc = omp_find_clause (OMP_CLAUSE_CHAIN (outerc),
   11775              :                                         OMP_CLAUSE__LOOPTEMP_);
   11776              :             }
   11777              :           else
   11778              :             {
   11779              :               /* If there are 2 adjacent SIMD stmts, one with _simt_
   11780              :                  clause, another without, make sure they have the same
   11781              :                  decls in _looptemp_ clauses, because the outer stmt
   11782              :                  they are combined into will look up just one inner_stmt.  */
   11783        16536 :               if (ctx->simt_stmt)
   11784            0 :                 temp = OMP_CLAUSE_DECL (simtc);
   11785              :               else
   11786        32928 :                 temp = create_tmp_var (i >= count ? type2 : type);
   11787        16536 :               insert_decl_map (&ctx->outer->cb, temp, temp);
   11788              :             }
   11789        34605 :           *pc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_);
   11790        34605 :           OMP_CLAUSE_DECL (*pc) = temp;
   11791        34605 :           pc = &OMP_CLAUSE_CHAIN (*pc);
   11792        34605 :           if (ctx->simt_stmt)
   11793            0 :             simtc = omp_find_clause (OMP_CLAUSE_CHAIN (simtc),
   11794              :                                      OMP_CLAUSE__LOOPTEMP_);
   11795              :         }
   11796        14598 :       *pc = clauses;
   11797              :     }
   11798              : 
   11799              :   /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR.  */
   11800        46888 :   dlist = NULL;
   11801        46888 :   body = NULL;
   11802        46888 :   tree rclauses
   11803        46888 :     = omp_task_reductions_find_first (gimple_omp_for_clauses (stmt), OMP_FOR,
   11804              :                                       OMP_CLAUSE_REDUCTION);
   11805        46888 :   tree rtmp = NULL_TREE;
   11806        46888 :   if (rclauses)
   11807              :     {
   11808          227 :       tree type = build_pointer_type (pointer_sized_int_node);
   11809          227 :       tree temp = create_tmp_var (type);
   11810          227 :       tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
   11811          227 :       OMP_CLAUSE_DECL (c) = temp;
   11812          227 :       OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (stmt);
   11813          227 :       gimple_omp_for_set_clauses (stmt, c);
   11814          227 :       lower_omp_task_reductions (ctx, OMP_FOR,
   11815              :                                  gimple_omp_for_clauses (stmt),
   11816              :                                  &tred_ilist, &tred_dlist);
   11817          227 :       rclauses = c;
   11818          227 :       rtmp = make_ssa_name (type);
   11819          227 :       gimple_seq_add_stmt (&body, gimple_build_assign (rtmp, temp));
   11820              :     }
   11821              : 
   11822        46888 :   lower_lastprivate_conditional_clauses (gimple_omp_for_clauses_ptr (stmt),
   11823              :                                          ctx);
   11824              : 
   11825        46888 :   lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx,
   11826              :                            fdp);
   11827        93549 :   gimple_seq_add_seq (rclauses ? &tred_ilist : &body,
   11828              :                       gimple_omp_for_pre_body (stmt));
   11829              : 
   11830        46888 :   lower_omp (gimple_omp_body_ptr (stmt), ctx);
   11831              : 
   11832        46888 :   gcall *private_marker = NULL;
   11833        46888 :   if (is_gimple_omp_oacc (ctx->stmt)
   11834        46888 :       && !gimple_seq_empty_p (omp_for_body))
   11835        10333 :     private_marker = lower_oacc_private_marker (ctx);
   11836              : 
   11837              :   /* Lower the header expressions.  At this point, we can assume that
   11838              :      the header is of the form:
   11839              : 
   11840              :         #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
   11841              : 
   11842              :      We just need to make sure that VAL1, VAL2 and VAL3 are lowered
   11843              :      using the .omp_data_s mapping, if needed.  */
   11844       115060 :   for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
   11845              :     {
   11846        68172 :       rhs_p = gimple_omp_for_initial_ptr (stmt, i);
   11847        68172 :       if (TREE_CODE (*rhs_p) == TREE_VEC)
   11848              :         {
   11849          639 :           if (!is_gimple_min_invariant (TREE_VEC_ELT (*rhs_p, 1)))
   11850          149 :             TREE_VEC_ELT (*rhs_p, 1)
   11851          298 :               = get_formal_tmp_var (TREE_VEC_ELT (*rhs_p, 1), &cnt_list);
   11852          639 :           if (!is_gimple_min_invariant (TREE_VEC_ELT (*rhs_p, 2)))
   11853          161 :             TREE_VEC_ELT (*rhs_p, 2)
   11854          322 :               = get_formal_tmp_var (TREE_VEC_ELT (*rhs_p, 2), &cnt_list);
   11855              :         }
   11856        67533 :       else if (!is_gimple_min_invariant (*rhs_p))
   11857        11465 :         *rhs_p = get_formal_tmp_var (*rhs_p, &cnt_list);
   11858        56068 :       else if (TREE_CODE (*rhs_p) == ADDR_EXPR)
   11859         4713 :         recompute_tree_invariant_for_addr_expr (*rhs_p);
   11860              : 
   11861        68172 :       rhs_p = gimple_omp_for_final_ptr (stmt, i);
   11862        68172 :       if (TREE_CODE (*rhs_p) == TREE_VEC)
   11863              :         {
   11864          519 :           if (!is_gimple_min_invariant (TREE_VEC_ELT (*rhs_p, 1)))
   11865          142 :             TREE_VEC_ELT (*rhs_p, 1)
   11866          284 :               = get_formal_tmp_var (TREE_VEC_ELT (*rhs_p, 1), &cnt_list);
   11867          519 :           if (!is_gimple_min_invariant (TREE_VEC_ELT (*rhs_p, 2)))
   11868          157 :             TREE_VEC_ELT (*rhs_p, 2)
   11869          314 :               = get_formal_tmp_var (TREE_VEC_ELT (*rhs_p, 2), &cnt_list);
   11870              :         }
   11871        67653 :       else if (!is_gimple_min_invariant (*rhs_p))
   11872        16787 :         *rhs_p = get_formal_tmp_var (*rhs_p, &cnt_list);
   11873        50866 :       else if (TREE_CODE (*rhs_p) == ADDR_EXPR)
   11874         4630 :         recompute_tree_invariant_for_addr_expr (*rhs_p);
   11875              : 
   11876        68172 :       rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
   11877        68172 :       if (!is_gimple_min_invariant (*rhs_p))
   11878         6318 :         *rhs_p = get_formal_tmp_var (*rhs_p, &cnt_list);
   11879              :     }
   11880        46888 :   if (rclauses)
   11881          227 :     gimple_seq_add_seq (&tred_ilist, cnt_list);
   11882              :   else
   11883        46661 :     gimple_seq_add_seq (&body, cnt_list);
   11884              : 
   11885              :   /* Once lowered, extract the bounds and clauses.  */
   11886        46888 :   omp_extract_for_data (stmt, &fd, NULL);
   11887              : 
   11888        46888 :   if (is_gimple_omp_oacc (ctx->stmt)
   11889        46888 :       && !ctx_in_oacc_kernels_region (ctx))
   11890         9665 :     lower_oacc_head_tail (gimple_location (stmt),
   11891              :                           gimple_omp_for_clauses (stmt), private_marker,
   11892              :                           &oacc_head, &oacc_tail, ctx);
   11893              : 
   11894              :   /* Add OpenACC partitioning and reduction markers just before the loop.  */
   11895        46888 :   if (oacc_head)
   11896         9665 :     gimple_seq_add_seq (&body, oacc_head);
   11897              : 
   11898        46888 :   lower_omp_for_lastprivate (&fd, &body, &dlist, &clist, ctx);
   11899              : 
   11900        46888 :   if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR)
   11901        85796 :     for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
   11902        70226 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   11903        70226 :           && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   11904              :         {
   11905          227 :           OMP_CLAUSE_DECL (c) = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
   11906          227 :           if (DECL_P (OMP_CLAUSE_LINEAR_STEP (c)))
   11907           42 :             OMP_CLAUSE_LINEAR_STEP (c)
   11908           84 :               = maybe_lookup_decl_in_outer_ctx (OMP_CLAUSE_LINEAR_STEP (c),
   11909              :                                                 ctx);
   11910              :         }
   11911              : 
   11912        46522 :   if ((ctx->scan_inclusive || ctx->scan_exclusive)
   11913        47156 :       && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR)
   11914          173 :     lower_omp_for_scan (&body, &dlist, stmt, &fd, ctx);
   11915              :   else
   11916              :     {
   11917        46715 :       gimple_seq_add_stmt (&body, stmt);
   11918        46715 :       gimple_seq_add_seq (&body, gimple_omp_body (stmt));
   11919              :     }
   11920              : 
   11921        46888 :   gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
   11922              :                                                          fd.loop.v));
   11923              : 
   11924              :   /* After the loop, add exit clauses.  */
   11925        46888 :   lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, &clist, ctx);
   11926              : 
   11927        46888 :   if (clist)
   11928              :     {
   11929          179 :       tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
   11930          179 :       gcall *g = gimple_build_call (fndecl, 0);
   11931          179 :       gimple_seq_add_stmt (&body, g);
   11932          179 :       gimple_seq_add_seq (&body, clist);
   11933          179 :       fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
   11934          179 :       g = gimple_build_call (fndecl, 0);
   11935          179 :       gimple_seq_add_stmt (&body, g);
   11936              :     }
   11937              : 
   11938        46888 :   if (ctx->cancellable)
   11939           84 :     gimple_seq_add_stmt (&body, gimple_build_label (ctx->cancel_label));
   11940              : 
   11941        46888 :   gimple_seq_add_seq (&body, dlist);
   11942              : 
   11943        46888 :   if (rclauses)
   11944              :     {
   11945          227 :       gimple_seq_add_seq (&tred_ilist, body);
   11946          227 :       body = tred_ilist;
   11947              :     }
   11948              : 
   11949        46888 :   body = maybe_catch_exception (body);
   11950              : 
   11951              :   /* Region exit marker goes at the end of the loop body.  */
   11952        46888 :   gimple *g = gimple_build_omp_return (fd.have_nowait);
   11953        46888 :   gimple_seq_add_stmt (&body, g);
   11954              : 
   11955        46888 :   gimple_seq_add_seq (&body, tred_dlist);
   11956              : 
   11957        46888 :   maybe_add_implicit_barrier_cancel (ctx, g, &body);
   11958              : 
   11959        46888 :   if (rclauses)
   11960          227 :     OMP_CLAUSE_DECL (rclauses) = rtmp;
   11961              : 
   11962              :   /* Add OpenACC joining and reduction markers just after the loop.  */
   11963        46888 :   if (oacc_tail)
   11964         9665 :     gimple_seq_add_seq (&body, oacc_tail);
   11965              : 
   11966        46888 :   pop_gimplify_context (new_stmt);
   11967              : 
   11968        46888 :   gimple_bind_append_vars (new_stmt, ctx->block_vars);
   11969        46888 :   maybe_remove_omp_member_access_dummy_vars (new_stmt);
   11970        46888 :   BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
   11971        46888 :   if (BLOCK_VARS (block))
   11972        46245 :     TREE_USED (block) = 1;
   11973              : 
   11974        46888 :   gimple_bind_set_body (new_stmt, body);
   11975        46888 :   gimple_omp_set_body (stmt, NULL);
   11976        46888 :   gimple_omp_for_set_pre_body (stmt, NULL);
   11977        46888 : }
   11978              : 
   11979              : /* Callback for walk_stmts.  Check if the current statement only contains
   11980              :    GIMPLE_OMP_FOR or GIMPLE_OMP_SECTIONS.  */
   11981              : 
   11982              : static tree
   11983       213107 : check_combined_parallel (gimple_stmt_iterator *gsi_p,
   11984              :                          bool *handled_ops_p,
   11985              :                          struct walk_stmt_info *wi)
   11986              : {
   11987       213107 :   int *info = (int *) wi->info;
   11988       213107 :   gimple *stmt = gsi_stmt (*gsi_p);
   11989              : 
   11990       213107 :   *handled_ops_p = true;
   11991       213107 :   switch (gimple_code (stmt))
   11992              :     {
   11993        11594 :     WALK_SUBSTMTS;
   11994              : 
   11995              :     case GIMPLE_DEBUG:
   11996              :       break;
   11997         1901 :     case GIMPLE_OMP_FOR:
   11998         1901 :     case GIMPLE_OMP_SECTIONS:
   11999         1901 :       *info = *info == 0 ? 1 : -1;
   12000         1901 :       break;
   12001       199573 :     default:
   12002       199573 :       *info = -1;
   12003       199573 :       break;
   12004              :     }
   12005       213107 :   return NULL;
   12006              : }
   12007              : 
   12008              : struct omp_taskcopy_context
   12009              : {
   12010              :   /* This field must be at the beginning, as we do "inheritance": Some
   12011              :      callback functions for tree-inline.cc (e.g., omp_copy_decl)
   12012              :      receive a copy_body_data pointer that is up-casted to an
   12013              :      omp_context pointer.  */
   12014              :   copy_body_data cb;
   12015              :   omp_context *ctx;
   12016              : };
   12017              : 
   12018              : static tree
   12019          366 : task_copyfn_copy_decl (tree var, copy_body_data *cb)
   12020              : {
   12021          366 :   struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
   12022              : 
   12023          366 :   if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
   12024          158 :     return create_tmp_var (TREE_TYPE (var));
   12025              : 
   12026              :   return var;
   12027              : }
   12028              : 
   12029              : static tree
   12030           50 : task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
   12031              : {
   12032           50 :   tree name, new_fields = NULL, type, f;
   12033              : 
   12034           50 :   type = lang_hooks.types.make_type (RECORD_TYPE);
   12035           50 :   name = DECL_NAME (TYPE_NAME (orig_type));
   12036           50 :   name = build_decl (gimple_location (tcctx->ctx->stmt),
   12037              :                      TYPE_DECL, name, type);
   12038           50 :   TYPE_NAME (type) = name;
   12039              : 
   12040         1140 :   for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
   12041              :     {
   12042         1090 :       tree new_f = copy_node (f);
   12043         1090 :       DECL_CONTEXT (new_f) = type;
   12044         1090 :       TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
   12045         1090 :       TREE_CHAIN (new_f) = new_fields;
   12046         1090 :       walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
   12047         1090 :       walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
   12048         1090 :       walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
   12049              :                  &tcctx->cb, NULL);
   12050         1090 :       new_fields = new_f;
   12051         1090 :       tcctx->cb.decl_map->put (f, new_f);
   12052              :     }
   12053           50 :   TYPE_FIELDS (type) = nreverse (new_fields);
   12054           50 :   layout_type (type);
   12055           50 :   return type;
   12056              : }
   12057              : 
   12058              : /* Create task copyfn.  */
   12059              : 
   12060              : static void
   12061          504 : create_task_copyfn (gomp_task *task_stmt, omp_context *ctx)
   12062              : {
   12063          504 :   struct function *child_cfun;
   12064          504 :   tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
   12065          504 :   tree record_type, srecord_type, bind, list;
   12066          504 :   bool record_needs_remap = false, srecord_needs_remap = false;
   12067          504 :   splay_tree_node n;
   12068          504 :   struct omp_taskcopy_context tcctx;
   12069          504 :   location_t loc = gimple_location (task_stmt);
   12070          504 :   size_t looptempno = 0;
   12071              : 
   12072          504 :   child_fn = gimple_omp_task_copy_fn (task_stmt);
   12073          504 :   task_cpyfns.safe_push (task_stmt);
   12074          504 :   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
   12075          504 :   gcc_assert (child_cfun->cfg == NULL);
   12076          504 :   DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
   12077              : 
   12078              :   /* Reset DECL_CONTEXT on function arguments.  */
   12079         1512 :   for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
   12080         1008 :     DECL_CONTEXT (t) = child_fn;
   12081              : 
   12082              :   /* Populate the function.  */
   12083          504 :   push_gimplify_context ();
   12084          504 :   push_cfun (child_cfun);
   12085              : 
   12086          504 :   bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
   12087          504 :   TREE_SIDE_EFFECTS (bind) = 1;
   12088          504 :   list = NULL;
   12089          504 :   DECL_SAVED_TREE (child_fn) = bind;
   12090          504 :   DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
   12091              : 
   12092              :   /* Remap src and dst argument types if needed.  */
   12093          504 :   record_type = ctx->record_type;
   12094          504 :   srecord_type = ctx->srecord_type;
   12095         3100 :   for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
   12096         2621 :     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
   12097              :       {
   12098              :         record_needs_remap = true;
   12099              :         break;
   12100              :       }
   12101         2839 :   for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
   12102         2360 :     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
   12103              :       {
   12104              :         srecord_needs_remap = true;
   12105              :         break;
   12106              :       }
   12107              : 
   12108          504 :   if (record_needs_remap || srecord_needs_remap)
   12109              :     {
   12110           25 :       memset (&tcctx, '\0', sizeof (tcctx));
   12111           25 :       tcctx.cb.src_fn = ctx->cb.src_fn;
   12112           25 :       tcctx.cb.dst_fn = child_fn;
   12113           25 :       tcctx.cb.src_node = cgraph_node::get (tcctx.cb.src_fn);
   12114           25 :       gcc_checking_assert (tcctx.cb.src_node);
   12115           25 :       tcctx.cb.dst_node = tcctx.cb.src_node;
   12116           25 :       tcctx.cb.src_cfun = ctx->cb.src_cfun;
   12117           25 :       tcctx.cb.copy_decl = task_copyfn_copy_decl;
   12118           25 :       tcctx.cb.eh_lp_nr = 0;
   12119           25 :       tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
   12120           25 :       tcctx.cb.decl_map = new hash_map<tree, tree>;
   12121           25 :       tcctx.ctx = ctx;
   12122              : 
   12123           25 :       if (record_needs_remap)
   12124           25 :         record_type = task_copyfn_remap_type (&tcctx, record_type);
   12125           25 :       if (srecord_needs_remap)
   12126           25 :         srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
   12127              :     }
   12128              :   else
   12129          479 :     tcctx.cb.decl_map = NULL;
   12130              : 
   12131          504 :   arg = DECL_ARGUMENTS (child_fn);
   12132          504 :   TREE_TYPE (arg) = build_pointer_type (record_type);
   12133          504 :   sarg = DECL_CHAIN (arg);
   12134          504 :   TREE_TYPE (sarg) = build_pointer_type (srecord_type);
   12135              : 
   12136              :   /* First pass: initialize temporaries used in record_type and srecord_type
   12137              :      sizes and field offsets.  */
   12138          504 :   if (tcctx.cb.decl_map)
   12139          631 :     for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   12140          606 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   12141              :         {
   12142          497 :           tree *p;
   12143              : 
   12144          497 :           decl = OMP_CLAUSE_DECL (c);
   12145          497 :           p = tcctx.cb.decl_map->get (decl);
   12146          497 :           if (p == NULL)
   12147          339 :             continue;
   12148          158 :           n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
   12149          158 :           sf = (tree) n->value;
   12150          158 :           sf = *tcctx.cb.decl_map->get (sf);
   12151          158 :           src = build_simple_mem_ref_loc (loc, sarg);
   12152          158 :           src = omp_build_component_ref (src, sf);
   12153          158 :           t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
   12154          158 :           append_to_statement_list (t, &list);
   12155              :         }
   12156              : 
   12157              :   /* Second pass: copy shared var pointers and copy construct non-VLA
   12158              :      firstprivate vars.  */
   12159         5848 :   for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   12160         5344 :     switch (OMP_CLAUSE_CODE (c))
   12161              :       {
   12162          581 :         splay_tree_key key;
   12163          581 :       case OMP_CLAUSE_SHARED:
   12164          581 :         decl = OMP_CLAUSE_DECL (c);
   12165          581 :         key = (splay_tree_key) decl;
   12166          581 :         if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
   12167          273 :           key = (splay_tree_key) &DECL_UID (decl);
   12168          581 :         n = splay_tree_lookup (ctx->field_map, key);
   12169          581 :         if (n == NULL)
   12170              :           break;
   12171          147 :         f = (tree) n->value;
   12172          147 :         if (tcctx.cb.decl_map)
   12173           12 :           f = *tcctx.cb.decl_map->get (f);
   12174          147 :         n = splay_tree_lookup (ctx->sfield_map, key);
   12175          147 :         sf = (tree) n->value;
   12176          147 :         if (tcctx.cb.decl_map)
   12177           12 :           sf = *tcctx.cb.decl_map->get (sf);
   12178          147 :         src = build_simple_mem_ref_loc (loc, sarg);
   12179          147 :         src = omp_build_component_ref (src, sf);
   12180          147 :         dst = build_simple_mem_ref_loc (loc, arg);
   12181          147 :         dst = omp_build_component_ref (dst, f);
   12182          147 :         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
   12183          147 :         append_to_statement_list (t, &list);
   12184          147 :         break;
   12185          460 :       case OMP_CLAUSE_REDUCTION:
   12186          460 :       case OMP_CLAUSE_IN_REDUCTION:
   12187          460 :         decl = OMP_CLAUSE_DECL (c);
   12188          460 :         if (TREE_CODE (decl) == MEM_REF)
   12189              :           {
   12190          160 :             decl = TREE_OPERAND (decl, 0);
   12191          160 :             if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
   12192           38 :               decl = TREE_OPERAND (decl, 0);
   12193          160 :             if (TREE_CODE (decl) == INDIRECT_REF
   12194          128 :                 || TREE_CODE (decl) == ADDR_EXPR)
   12195           95 :               decl = TREE_OPERAND (decl, 0);
   12196              :           }
   12197          460 :         key = (splay_tree_key) decl;
   12198          460 :         n = splay_tree_lookup (ctx->field_map, key);
   12199          460 :         if (n == NULL)
   12200              :           break;
   12201          101 :         f = (tree) n->value;
   12202          101 :         if (tcctx.cb.decl_map)
   12203           20 :           f = *tcctx.cb.decl_map->get (f);
   12204          101 :         n = splay_tree_lookup (ctx->sfield_map, key);
   12205          101 :         sf = (tree) n->value;
   12206          101 :         if (tcctx.cb.decl_map)
   12207           20 :           sf = *tcctx.cb.decl_map->get (sf);
   12208          101 :         src = build_simple_mem_ref_loc (loc, sarg);
   12209          101 :         src = omp_build_component_ref (src, sf);
   12210          101 :         if (decl != OMP_CLAUSE_DECL (c)
   12211           95 :             && TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   12212          173 :             && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
   12213           32 :           src = build_simple_mem_ref_loc (loc, src);
   12214          101 :         dst = build_simple_mem_ref_loc (loc, arg);
   12215          101 :         dst = omp_build_component_ref (dst, f);
   12216          101 :         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
   12217          101 :         append_to_statement_list (t, &list);
   12218          101 :         break;
   12219          754 :       case OMP_CLAUSE__LOOPTEMP_:
   12220              :         /* Fields for first two _looptemp_ clauses are initialized by
   12221              :            GOMP_taskloop*, the rest are handled like firstprivate.  */
   12222          754 :         if (looptempno < 2)
   12223              :           {
   12224          748 :             looptempno++;
   12225          748 :             break;
   12226              :           }
   12227              :         /* FALLTHRU */
   12228         1731 :       case OMP_CLAUSE__REDUCTEMP_:
   12229         1731 :       case OMP_CLAUSE_FIRSTPRIVATE:
   12230         1731 :         decl = OMP_CLAUSE_DECL (c);
   12231         1731 :         if (is_variable_sized (decl))
   12232              :           break;
   12233         1717 :         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
   12234         1717 :         if (n == NULL)
   12235              :           break;
   12236         1717 :         f = (tree) n->value;
   12237         1717 :         if (tcctx.cb.decl_map)
   12238          490 :           f = *tcctx.cb.decl_map->get (f);
   12239         1717 :         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
   12240         1717 :         if (n != NULL)
   12241              :           {
   12242         1467 :             sf = (tree) n->value;
   12243         1467 :             if (tcctx.cb.decl_map)
   12244          490 :               sf = *tcctx.cb.decl_map->get (sf);
   12245         1467 :             src = build_simple_mem_ref_loc (loc, sarg);
   12246         1467 :             src = omp_build_component_ref (src, sf);
   12247         1467 :             if (use_pointer_for_field (decl, NULL)
   12248         1467 :                 || omp_privatize_by_reference (decl))
   12249          317 :               src = build_simple_mem_ref_loc (loc, src);
   12250              :           }
   12251              :         else
   12252              :           src = decl;
   12253         1717 :         dst = build_simple_mem_ref_loc (loc, arg);
   12254         1717 :         dst = omp_build_component_ref (dst, f);
   12255         1717 :         if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
   12256          192 :           t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
   12257              :         else
   12258              :           {
   12259         1525 :             if (ctx->allocate_map)
   12260           84 :               if (tree *allocatorp = ctx->allocate_map->get (decl))
   12261              :                 {
   12262           50 :                   tree allocator = *allocatorp;
   12263           50 :                   HOST_WIDE_INT ialign = 0;
   12264           50 :                   if (TREE_CODE (allocator) == TREE_LIST)
   12265              :                     {
   12266            4 :                       ialign = tree_to_uhwi (TREE_VALUE (allocator));
   12267            4 :                       allocator = TREE_PURPOSE (allocator);
   12268              :                     }
   12269           50 :                   if (TREE_CODE (allocator) != INTEGER_CST)
   12270              :                     {
   12271           22 :                       n = splay_tree_lookup (ctx->sfield_map,
   12272              :                                              (splay_tree_key) allocator);
   12273           22 :                       allocator = (tree) n->value;
   12274           22 :                       if (tcctx.cb.decl_map)
   12275            0 :                         allocator = *tcctx.cb.decl_map->get (allocator);
   12276           22 :                       tree a = build_simple_mem_ref_loc (loc, sarg);
   12277           22 :                       allocator = omp_build_component_ref (a, allocator);
   12278              :                     }
   12279           50 :                   allocator = fold_convert (pointer_sized_int_node, allocator);
   12280           50 :                   tree a = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
   12281           50 :                   tree align = build_int_cst (size_type_node,
   12282           50 :                                               MAX (ialign,
   12283              :                                                    DECL_ALIGN_UNIT (decl)));
   12284           50 :                   tree sz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (dst)));
   12285           50 :                   tree ptr = build_call_expr_loc (loc, a, 3, align, sz,
   12286              :                                                   allocator);
   12287           50 :                   ptr = fold_convert (TREE_TYPE (dst), ptr);
   12288           50 :                   t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, ptr);
   12289           50 :                   append_to_statement_list (t, &list);
   12290           50 :                   dst = build_simple_mem_ref_loc (loc, dst);
   12291              :                 }
   12292         1525 :             t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
   12293              :           }
   12294         1717 :         append_to_statement_list (t, &list);
   12295         1717 :         break;
   12296          489 :       case OMP_CLAUSE_PRIVATE:
   12297          489 :         if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
   12298              :           break;
   12299           12 :         decl = OMP_CLAUSE_DECL (c);
   12300           12 :         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
   12301           12 :         f = (tree) n->value;
   12302           12 :         if (tcctx.cb.decl_map)
   12303            0 :           f = *tcctx.cb.decl_map->get (f);
   12304           12 :         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
   12305           12 :         if (n != NULL)
   12306              :           {
   12307           12 :             sf = (tree) n->value;
   12308           12 :             if (tcctx.cb.decl_map)
   12309            0 :               sf = *tcctx.cb.decl_map->get (sf);
   12310           12 :             src = build_simple_mem_ref_loc (loc, sarg);
   12311           12 :             src = omp_build_component_ref (src, sf);
   12312           12 :             if (use_pointer_for_field (decl, NULL))
   12313           12 :               src = build_simple_mem_ref_loc (loc, src);
   12314              :           }
   12315              :         else
   12316              :           src = decl;
   12317           12 :         dst = build_simple_mem_ref_loc (loc, arg);
   12318           12 :         dst = omp_build_component_ref (dst, f);
   12319           12 :         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
   12320           12 :         append_to_statement_list (t, &list);
   12321           12 :         break;
   12322              :       default:
   12323              :         break;
   12324              :       }
   12325              : 
   12326              :   /* Last pass: handle VLA firstprivates.  */
   12327          504 :   if (tcctx.cb.decl_map)
   12328          631 :     for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   12329          606 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   12330              :         {
   12331          497 :           tree ind, ptr, df;
   12332              : 
   12333          497 :           decl = OMP_CLAUSE_DECL (c);
   12334          497 :           if (!is_variable_sized (decl))
   12335          483 :             continue;
   12336           14 :           n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
   12337           14 :           if (n == NULL)
   12338            0 :             continue;
   12339           14 :           f = (tree) n->value;
   12340           14 :           f = *tcctx.cb.decl_map->get (f);
   12341           14 :           gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
   12342           14 :           ind = DECL_VALUE_EXPR (decl);
   12343           14 :           gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
   12344           14 :           gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
   12345           42 :           n = splay_tree_lookup (ctx->sfield_map,
   12346           14 :                                  (splay_tree_key) TREE_OPERAND (ind, 0));
   12347           14 :           sf = (tree) n->value;
   12348           14 :           sf = *tcctx.cb.decl_map->get (sf);
   12349           14 :           src = build_simple_mem_ref_loc (loc, sarg);
   12350           14 :           src = omp_build_component_ref (src, sf);
   12351           14 :           src = build_simple_mem_ref_loc (loc, src);
   12352           14 :           dst = build_simple_mem_ref_loc (loc, arg);
   12353           14 :           dst = omp_build_component_ref (dst, f);
   12354           14 :           t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
   12355           14 :           append_to_statement_list (t, &list);
   12356           42 :           n = splay_tree_lookup (ctx->field_map,
   12357           14 :                                  (splay_tree_key) TREE_OPERAND (ind, 0));
   12358           14 :           df = (tree) n->value;
   12359           14 :           df = *tcctx.cb.decl_map->get (df);
   12360           14 :           ptr = build_simple_mem_ref_loc (loc, arg);
   12361           14 :           ptr = omp_build_component_ref (ptr, df);
   12362           14 :           t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
   12363              :                       build_fold_addr_expr_loc (loc, dst));
   12364           14 :           append_to_statement_list (t, &list);
   12365              :         }
   12366              : 
   12367          504 :   t = build1 (RETURN_EXPR, void_type_node, NULL);
   12368          504 :   append_to_statement_list (t, &list);
   12369              : 
   12370          504 :   if (tcctx.cb.decl_map)
   12371           25 :     delete tcctx.cb.decl_map;
   12372          504 :   pop_gimplify_context (NULL);
   12373          504 :   BIND_EXPR_BODY (bind) = list;
   12374          504 :   pop_cfun ();
   12375          504 : }
   12376              : 
   12377              : static void
   12378         1551 : lower_depend_clauses (tree *pclauses, gimple_seq *iseq, gimple_seq *oseq)
   12379              : {
   12380         1551 :   tree c, clauses;
   12381         1551 :   gimple *g;
   12382         1551 :   size_t cnt[5] = { 0, 0, 0, 0, 0 }, idx = 2, i;
   12383              : 
   12384         1551 :   clauses = omp_find_clause (*pclauses, OMP_CLAUSE_DEPEND);
   12385         1551 :   gcc_assert (clauses);
   12386         6311 :   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   12387         4884 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   12388         1711 :       switch (OMP_CLAUSE_DEPEND_KIND (c))
   12389              :         {
   12390          124 :         case OMP_CLAUSE_DEPEND_LAST:
   12391              :           /* Lowering already done at gimplification.  */
   12392          124 :           return;
   12393          481 :         case OMP_CLAUSE_DEPEND_IN:
   12394          481 :           cnt[2]++;
   12395          481 :           break;
   12396          968 :         case OMP_CLAUSE_DEPEND_OUT:
   12397          968 :         case OMP_CLAUSE_DEPEND_INOUT:
   12398          968 :           cnt[0]++;
   12399          968 :           break;
   12400           30 :         case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
   12401           30 :           cnt[1]++;
   12402           30 :           break;
   12403           76 :         case OMP_CLAUSE_DEPEND_DEPOBJ:
   12404           76 :           cnt[3]++;
   12405           76 :           break;
   12406           32 :         case OMP_CLAUSE_DEPEND_INOUTSET:
   12407           32 :           cnt[4]++;
   12408           32 :           break;
   12409            0 :         default:
   12410            0 :           gcc_unreachable ();
   12411              :         }
   12412         1427 :   if (cnt[1] || cnt[3] || cnt[4])
   12413          135 :     idx = 5;
   12414         1427 :   size_t total = cnt[0] + cnt[1] + cnt[2] + cnt[3] + cnt[4];
   12415         1427 :   size_t inoutidx = total + idx;
   12416         1427 :   tree type = build_array_type_nelts (ptr_type_node, total + idx + 2 * cnt[4]);
   12417         1427 :   tree array = create_tmp_var (type);
   12418         1427 :   TREE_ADDRESSABLE (array) = 1;
   12419         1427 :   tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
   12420              :                    NULL_TREE);
   12421         1427 :   if (idx == 5)
   12422              :     {
   12423          135 :       g = gimple_build_assign (r, build_int_cst (ptr_type_node, 0));
   12424          135 :       gimple_seq_add_stmt (iseq, g);
   12425          135 :       r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
   12426              :                   NULL_TREE);
   12427              :     }
   12428         1427 :   g = gimple_build_assign (r, build_int_cst (ptr_type_node, total));
   12429         1427 :   gimple_seq_add_stmt (iseq, g);
   12430         7135 :   for (i = 0; i < (idx == 5 ? 3 : 1); i++)
   12431              :     {
   12432         1697 :       r = build4 (ARRAY_REF, ptr_type_node, array,
   12433         1697 :                   size_int (i + 1 + (idx == 5)), NULL_TREE, NULL_TREE);
   12434         1697 :       g = gimple_build_assign (r, build_int_cst (ptr_type_node, cnt[i]));
   12435         1697 :       gimple_seq_add_stmt (iseq, g);
   12436              :     }
   12437         8562 :   for (i = 0; i < 5; i++)
   12438              :     {
   12439         7135 :       if (cnt[i] == 0)
   12440         5652 :         continue;
   12441         6561 :       for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   12442         5078 :         if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
   12443         3352 :           continue;
   12444              :         else
   12445              :           {
   12446         1726 :             switch (OMP_CLAUSE_DEPEND_KIND (c))
   12447              :               {
   12448          547 :               case OMP_CLAUSE_DEPEND_IN:
   12449          547 :                 if (i != 2)
   12450          139 :                   continue;
   12451              :                 break;
   12452         1024 :               case OMP_CLAUSE_DEPEND_OUT:
   12453         1024 :               case OMP_CLAUSE_DEPEND_INOUT:
   12454         1024 :                 if (i != 0)
   12455           56 :                   continue;
   12456              :                 break;
   12457           44 :               case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
   12458           44 :                 if (i != 1)
   12459           14 :                   continue;
   12460              :                 break;
   12461           79 :               case OMP_CLAUSE_DEPEND_DEPOBJ:
   12462           79 :                 if (i != 3)
   12463            3 :                   continue;
   12464              :                 break;
   12465           32 :               case OMP_CLAUSE_DEPEND_INOUTSET:
   12466           32 :                 if (i != 4)
   12467            0 :                    continue;
   12468              :                 break;
   12469            0 :               default:
   12470            0 :                 gcc_unreachable ();
   12471              :               }
   12472         1587 :             tree t = OMP_CLAUSE_DECL (c);
   12473         1587 :             if (i == 4)
   12474              :               {
   12475           32 :                 t = build4 (ARRAY_REF, ptr_type_node, array,
   12476           32 :                             size_int (inoutidx), NULL_TREE, NULL_TREE);
   12477           32 :                 t = build_fold_addr_expr (t);
   12478           32 :                 inoutidx += 2;
   12479              :               }
   12480         1587 :             t = fold_convert (ptr_type_node, t);
   12481         1587 :             gimplify_expr (&t, iseq, NULL, is_gimple_val, fb_rvalue);
   12482         1587 :             r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
   12483              :                         NULL_TREE, NULL_TREE);
   12484         1587 :             g = gimple_build_assign (r, t);
   12485         1587 :             gimple_seq_add_stmt (iseq, g);
   12486              :           }
   12487              :     }
   12488         1427 :   if (cnt[4])
   12489           81 :     for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   12490           49 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
   12491           49 :           && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_INOUTSET)
   12492              :         {
   12493           32 :           tree t = OMP_CLAUSE_DECL (c);
   12494           32 :           t = fold_convert (ptr_type_node, t);
   12495           32 :           gimplify_expr (&t, iseq, NULL, is_gimple_val, fb_rvalue);
   12496           32 :           r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
   12497              :                       NULL_TREE, NULL_TREE);
   12498           32 :           g = gimple_build_assign (r, t);
   12499           32 :           gimple_seq_add_stmt (iseq, g);
   12500           32 :           t = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
   12501           32 :           r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
   12502              :                       NULL_TREE, NULL_TREE);
   12503           32 :           g = gimple_build_assign (r, t);
   12504           32 :           gimple_seq_add_stmt (iseq, g);
   12505              :         }
   12506              : 
   12507         1427 :   c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
   12508         1427 :   OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
   12509         1427 :   OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
   12510         1427 :   OMP_CLAUSE_CHAIN (c) = *pclauses;
   12511         1427 :   *pclauses = c;
   12512         1427 :   tree clobber = build_clobber (type);
   12513         1427 :   g = gimple_build_assign (array, clobber);
   12514         1427 :   gimple_seq_add_stmt (oseq, g);
   12515              : }
   12516              : 
   12517              : /* Lower the OpenMP parallel or task directive in the current statement
   12518              :    in GSI_P.  CTX holds context information for the directive.  */
   12519              : 
   12520              : static void
   12521        22460 : lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   12522              : {
   12523        22460 :   tree clauses;
   12524        22460 :   tree child_fn, t;
   12525        22460 :   gimple *stmt = gsi_stmt (*gsi_p);
   12526        22460 :   gbind *par_bind, *bind, *dep_bind = NULL;
   12527        22460 :   gimple_seq par_body;
   12528        22460 :   location_t loc = gimple_location (stmt);
   12529              : 
   12530        22460 :   clauses = gimple_omp_taskreg_clauses (stmt);
   12531        22460 :   if (gimple_code (stmt) == GIMPLE_OMP_TASK
   12532        22460 :       && gimple_omp_task_taskwait_p (stmt))
   12533              :     {
   12534           83 :       par_bind = NULL;
   12535           83 :       par_body = NULL;
   12536              :     }
   12537              :   else
   12538              :     {
   12539        22377 :       par_bind
   12540        22377 :         = as_a <gbind *> (gimple_seq_first_stmt (gimple_omp_body (stmt)));
   12541        22377 :       par_body = gimple_bind_body (par_bind);
   12542              :     }
   12543        22460 :   child_fn = ctx->cb.dst_fn;
   12544        22460 :   if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
   12545        22460 :       && !gimple_omp_parallel_combined_p (stmt))
   12546              :     {
   12547         4194 :       struct walk_stmt_info wi;
   12548         4194 :       int ws_num = 0;
   12549              : 
   12550         4194 :       memset (&wi, 0, sizeof (wi));
   12551         4194 :       wi.info = &ws_num;
   12552         4194 :       wi.val_only = true;
   12553         4194 :       walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
   12554         4194 :       if (ws_num == 1)
   12555          377 :         gimple_omp_parallel_set_combined_p (stmt, true);
   12556              :     }
   12557        22460 :   gimple_seq dep_ilist = NULL;
   12558        22460 :   gimple_seq dep_olist = NULL;
   12559        22460 :   if (gimple_code (stmt) == GIMPLE_OMP_TASK
   12560        22460 :       && omp_find_clause (clauses, OMP_CLAUSE_DEPEND))
   12561              :     {
   12562         1187 :       push_gimplify_context ();
   12563         1187 :       dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
   12564         1187 :       lower_depend_clauses (gimple_omp_task_clauses_ptr (stmt),
   12565              :                             &dep_ilist, &dep_olist);
   12566              :     }
   12567              : 
   12568        22460 :   if (gimple_code (stmt) == GIMPLE_OMP_TASK
   12569        22460 :       && gimple_omp_task_taskwait_p (stmt))
   12570              :     {
   12571           83 :       if (dep_bind)
   12572              :         {
   12573           83 :           gsi_replace (gsi_p, dep_bind, true);
   12574           83 :           gimple_bind_add_seq (dep_bind, dep_ilist);
   12575           83 :           gimple_bind_add_stmt (dep_bind, stmt);
   12576           83 :           gimple_bind_add_seq (dep_bind, dep_olist);
   12577           83 :           pop_gimplify_context (dep_bind);
   12578              :         }
   12579           83 :       return;
   12580              :     }
   12581              : 
   12582        22377 :   if (ctx->srecord_type)
   12583          504 :     create_task_copyfn (as_a <gomp_task *> (stmt), ctx);
   12584              : 
   12585        22377 :   gimple_seq tskred_ilist = NULL;
   12586        22377 :   gimple_seq tskred_olist = NULL;
   12587        22377 :   if ((is_task_ctx (ctx)
   12588         3777 :        && gimple_omp_task_taskloop_p (ctx->stmt)
   12589         1330 :        && omp_find_clause (gimple_omp_task_clauses (ctx->stmt),
   12590              :                            OMP_CLAUSE_REDUCTION))
   12591        25657 :       || (is_parallel_ctx (ctx)
   12592        16104 :           && omp_find_clause (gimple_omp_parallel_clauses (stmt),
   12593              :                               OMP_CLAUSE__REDUCTEMP_)))
   12594              :     {
   12595          557 :       if (dep_bind == NULL)
   12596              :         {
   12597          557 :           push_gimplify_context ();
   12598          557 :           dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
   12599              :         }
   12600          617 :       lower_omp_task_reductions (ctx, is_task_ctx (ctx) ? OMP_TASKLOOP
   12601              :                                                         : OMP_PARALLEL,
   12602          557 :                                  gimple_omp_taskreg_clauses (ctx->stmt),
   12603              :                                  &tskred_ilist, &tskred_olist);
   12604              :     }
   12605              : 
   12606        22377 :   push_gimplify_context ();
   12607              : 
   12608        22377 :   gimple_seq par_olist = NULL;
   12609        22377 :   gimple_seq par_ilist = NULL;
   12610        22377 :   gimple_seq par_rlist = NULL;
   12611        22377 :   lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx, NULL);
   12612        22373 :   lower_omp (&par_body, ctx);
   12613        22373 :   if (gimple_code (stmt) != GIMPLE_OMP_TASK)
   12614        18596 :     lower_reduction_clauses (clauses, &par_rlist, NULL, ctx);
   12615              : 
   12616              :   /* Declare all the variables created by mapping and the variables
   12617              :      declared in the scope of the parallel body.  */
   12618        22373 :   record_vars_into (ctx->block_vars, child_fn);
   12619        22373 :   maybe_remove_omp_member_access_dummy_vars (par_bind);
   12620        22373 :   record_vars_into (gimple_bind_vars (par_bind), child_fn);
   12621              : 
   12622        22373 :   if (ctx->record_type)
   12623              :     {
   12624        17922 :       ctx->sender_decl
   12625        35340 :         = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
   12626              :                           : ctx->record_type, ".omp_data_o");
   12627        17922 :       DECL_NAMELESS (ctx->sender_decl) = 1;
   12628        17922 :       TREE_ADDRESSABLE (ctx->sender_decl) = 1;
   12629        17922 :       gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
   12630              :     }
   12631              : 
   12632        22373 :   gimple_seq olist = NULL;
   12633        22373 :   gimple_seq ilist = NULL;
   12634        22373 :   lower_send_clauses (clauses, &ilist, &olist, ctx);
   12635        22373 :   lower_send_shared_vars (&ilist, &olist, ctx);
   12636              : 
   12637        22373 :   if (ctx->record_type)
   12638              :     {
   12639        17922 :       tree clobber = build_clobber (TREE_TYPE (ctx->sender_decl));
   12640        17922 :       gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
   12641              :                                                         clobber));
   12642              :     }
   12643              : 
   12644              :   /* Once all the expansions are done, sequence all the different
   12645              :      fragments inside gimple_omp_body.  */
   12646              : 
   12647        22373 :   gimple_seq new_body = NULL;
   12648              : 
   12649        22373 :   if (ctx->record_type)
   12650              :     {
   12651        17922 :       t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
   12652              :       /* fixup_child_record_type might have changed receiver_decl's type.  */
   12653        17922 :       t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
   12654        17922 :       gimple_seq_add_stmt (&new_body,
   12655        17922 :                            gimple_build_assign (ctx->receiver_decl, t));
   12656              :     }
   12657              : 
   12658        22373 :   gimple_seq_add_seq (&new_body, par_ilist);
   12659        22373 :   gimple_seq_add_seq (&new_body, par_body);
   12660        22373 :   gimple_seq_add_seq (&new_body, par_rlist);
   12661        22373 :   if (ctx->cancellable)
   12662          135 :     gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
   12663        22373 :   gimple_seq_add_seq (&new_body, par_olist);
   12664        22373 :   new_body = maybe_catch_exception (new_body);
   12665        22373 :   if (gimple_code (stmt) == GIMPLE_OMP_TASK)
   12666         3777 :     gimple_seq_add_stmt (&new_body,
   12667         3777 :                          gimple_build_omp_continue (integer_zero_node,
   12668              :                                                     integer_zero_node));
   12669        22373 :   gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
   12670        22373 :   gimple_omp_set_body (stmt, new_body);
   12671              : 
   12672        22373 :   if (dep_bind && gimple_bind_block (par_bind) == NULL_TREE)
   12673          497 :     bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
   12674              :   else
   12675        21876 :     bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
   12676        43085 :   gsi_replace (gsi_p, dep_bind ? dep_bind : bind, true);
   12677        22373 :   gimple_bind_add_seq (bind, ilist);
   12678        22373 :   gimple_bind_add_stmt (bind, stmt);
   12679        22373 :   gimple_bind_add_seq (bind, olist);
   12680              : 
   12681        22373 :   pop_gimplify_context (NULL);
   12682              : 
   12683        22373 :   if (dep_bind)
   12684              :     {
   12685         1661 :       gimple_bind_add_seq (dep_bind, dep_ilist);
   12686         1661 :       gimple_bind_add_seq (dep_bind, tskred_ilist);
   12687         1661 :       gimple_bind_add_stmt (dep_bind, bind);
   12688         1661 :       gimple_bind_add_seq (dep_bind, tskred_olist);
   12689         1661 :       gimple_bind_add_seq (dep_bind, dep_olist);
   12690         1661 :       pop_gimplify_context (dep_bind);
   12691              :     }
   12692              : }
   12693              : 
   12694              :  /* Set EXPR as the hostaddr expression that should result from the clause C
   12695              :     in the target statement STMT.  Returns the tree that should be
   12696              :     passed as the hostaddr (a pointer to the array containing the expanded
   12697              :     hostaddrs and sizes of the clause).  */
   12698              : 
   12699              : static tree
   12700        37187 : lower_omp_map_iterator_expr (tree expr, tree c, gomp_target *stmt)
   12701              : {
   12702        37187 :   if (!OMP_CLAUSE_HAS_ITERATORS (c))
   12703              :     return expr;
   12704              : 
   12705          100 :   tree iterator = OMP_CLAUSE_ITERATORS (c);
   12706          100 :   tree elems = TREE_VEC_ELT (iterator, 7);
   12707          100 :   tree index = TREE_VEC_ELT (iterator, 8);
   12708          100 :   gimple_seq *loop_body_p = enter_omp_iterator_loop_context (c, stmt);
   12709              : 
   12710              :    /* IN LOOP BODY:  */
   12711              :    /* elems[idx] = <expr>;  */
   12712          100 :   tree lhs = build4 (ARRAY_REF, ptr_type_node, elems, index,
   12713              :                      NULL_TREE, NULL_TREE);
   12714          100 :   tree mod_expr = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   12715              :                               void_type_node, lhs, expr);
   12716          100 :   gimplify_and_add (mod_expr, loop_body_p);
   12717          100 :   exit_omp_iterator_loop_context (c);
   12718              : 
   12719          100 :   return build_fold_addr_expr_with_type (elems, ptr_type_node);
   12720              : }
   12721              : 
   12722              : /* Set SIZE as the size expression that should result from the clause C
   12723              :    in the target statement STMT.  Returns the tree that should be
   12724              :    passed as the clause size (a size_int with the value SIZE_MAX, indicating
   12725              :    that the clause uses an iterator).  */
   12726              : 
   12727              : static tree
   12728        79866 : lower_omp_map_iterator_size (tree size, tree c, gomp_target *stmt)
   12729              : {
   12730        79866 :   if (!OMP_CLAUSE_HAS_ITERATORS (c))
   12731              :     return size;
   12732              : 
   12733          104 :   tree iterator = OMP_CLAUSE_ITERATORS (c);
   12734          104 :   tree elems = TREE_VEC_ELT (iterator, 7);
   12735          104 :   tree index = TREE_VEC_ELT (iterator, 8);
   12736          104 :   gimple_seq *loop_body_p = enter_omp_iterator_loop_context (c, stmt);
   12737              : 
   12738              :   /* IN LOOP BODY:  */
   12739              :   /* elems[idx+1] = <size>;  */
   12740          104 :   tree lhs = build4 (ARRAY_REF, ptr_type_node, elems,
   12741              :                      size_binop (PLUS_EXPR, index, size_int (1)),
   12742              :                      NULL_TREE, NULL_TREE);
   12743          104 :   tree mod_expr = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   12744              :                               void_type_node, lhs, size);
   12745          104 :   gimplify_and_add (mod_expr, loop_body_p);
   12746          104 :   exit_omp_iterator_loop_context (c);
   12747              : 
   12748          104 :   return size_int (SIZE_MAX);
   12749              : }
   12750              : 
   12751              : /* Lower the GIMPLE_OMP_TARGET in the current statement
   12752              :    in GSI_P.  CTX holds context information for the directive.  */
   12753              : 
   12754              : static void
   12755        36984 : lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   12756              : {
   12757        36984 :   tree clauses;
   12758        36984 :   tree child_fn, t, c;
   12759        36984 :   gomp_target *stmt = as_a <gomp_target *> (gsi_stmt (*gsi_p));
   12760        36984 :   gbind *tgt_bind, *bind, *dep_bind = NULL;
   12761        36984 :   gimple_seq tgt_body, olist, ilist, fplist, new_body;
   12762        36984 :   location_t loc = gimple_location (stmt);
   12763        36984 :   bool offloaded, data_region;
   12764        36984 :   unsigned int map_cnt = 0;
   12765        36984 :   tree in_reduction_clauses = NULL_TREE;
   12766              : 
   12767        36984 :   tree deep_map_cnt = NULL_TREE;
   12768        36984 :   tree deep_map_data = NULL_TREE;
   12769        36984 :   tree deep_map_offset_data = NULL_TREE;
   12770        36984 :   tree deep_map_offset = NULL_TREE;
   12771              : 
   12772        36984 :   offloaded = is_gimple_omp_offloaded (stmt);
   12773        36984 :   switch (gimple_omp_target_kind (stmt))
   12774              :     {
   12775        11653 :     case GF_OMP_TARGET_KIND_REGION:
   12776        11653 :       tree *p, *q;
   12777        11653 :       q = &in_reduction_clauses;
   12778        78469 :       for (p = gimple_omp_target_clauses_ptr (stmt); *p; )
   12779        66816 :         if (OMP_CLAUSE_CODE (*p) == OMP_CLAUSE_IN_REDUCTION)
   12780              :           {
   12781          422 :             *q = *p;
   12782          422 :             q = &OMP_CLAUSE_CHAIN (*q);
   12783          422 :             *p = OMP_CLAUSE_CHAIN (*p);
   12784              :           }
   12785              :         else
   12786        66394 :           p = &OMP_CLAUSE_CHAIN (*p);
   12787        11653 :       *q = NULL_TREE;
   12788        11653 :       *p = in_reduction_clauses;
   12789              :       /* FALLTHRU */
   12790              :     case GF_OMP_TARGET_KIND_UPDATE:
   12791              :     case GF_OMP_TARGET_KIND_ENTER_DATA:
   12792              :     case GF_OMP_TARGET_KIND_EXIT_DATA:
   12793              :     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
   12794              :     case GF_OMP_TARGET_KIND_OACC_KERNELS:
   12795              :     case GF_OMP_TARGET_KIND_OACC_SERIAL:
   12796              :     case GF_OMP_TARGET_KIND_OACC_UPDATE:
   12797              :     case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
   12798              :     case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
   12799              :     case GF_OMP_TARGET_KIND_OACC_DECLARE:
   12800              :     case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
   12801              :     case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
   12802              :       data_region = false;
   12803              :       break;
   12804              :     case GF_OMP_TARGET_KIND_DATA:
   12805              :     case GF_OMP_TARGET_KIND_OACC_DATA:
   12806              :     case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
   12807              :     case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
   12808              :       data_region = true;
   12809              :       break;
   12810            0 :     default:
   12811            0 :       gcc_unreachable ();
   12812              :     }
   12813              : 
   12814              :   /* Ensure that requires map is written via output_offload_tables, even if only
   12815              :      'target (enter/exit) data' is used in the translation unit.  */
   12816        36984 :   if (ENABLE_OFFLOADING && (omp_requires_mask & OMP_REQUIRES_TARGET_USED))
   12817              :     g->have_offload = true;
   12818              : 
   12819        36984 :   clauses = gimple_omp_target_clauses (stmt);
   12820              : 
   12821        36984 :   gimple_seq dep_ilist = NULL;
   12822        36984 :   gimple_seq dep_olist = NULL;
   12823        36984 :   bool has_depend = omp_find_clause (clauses, OMP_CLAUSE_DEPEND) != NULL_TREE;
   12824        36984 :   if (has_depend || in_reduction_clauses)
   12825              :     {
   12826          392 :       push_gimplify_context ();
   12827          392 :       dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
   12828          392 :       if (has_depend)
   12829          329 :         lower_depend_clauses (gimple_omp_target_clauses_ptr (stmt),
   12830              :                               &dep_ilist, &dep_olist);
   12831          392 :       if (in_reduction_clauses)
   12832          314 :         lower_rec_input_clauses (in_reduction_clauses, &dep_ilist, &dep_olist,
   12833              :                                  ctx, NULL);
   12834              :     }
   12835              : 
   12836        36984 :   tgt_bind = NULL;
   12837        36984 :   tgt_body = NULL;
   12838        36984 :   if (offloaded)
   12839              :     {
   12840        21048 :       tgt_bind = gimple_seq_first_stmt_as_a_bind (gimple_omp_body (stmt));
   12841        21048 :       tgt_body = gimple_bind_body (tgt_bind);
   12842              :     }
   12843        15936 :   else if (data_region)
   12844         4020 :     tgt_body = gimple_omp_body (stmt);
   12845        36984 :   child_fn = ctx->cb.dst_fn;
   12846              : 
   12847        36984 :   push_gimplify_context ();
   12848        36984 :   fplist = NULL;
   12849              : 
   12850        36984 :   ilist = NULL;
   12851        36984 :   olist = NULL;
   12852              : 
   12853        36984 :   gimple_seq alloc_dlist = NULL;
   12854        36984 :   hash_map<tree, tree> alloc_map;
   12855        73968 :   hash_map<tree, gimple_seq> alloc_seq_map;
   12856              : 
   12857       175430 :   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
   12858       138446 :     switch (OMP_CLAUSE_CODE (c))
   12859              :       {
   12860              :         tree var, x, new_var, allocator, allocate_ptr, size;
   12861              :         gimple_seq alloc_seq;
   12862              :         bool by_ref;
   12863              : 
   12864              :       default:
   12865        92152 :         break;
   12866        77605 :       case OMP_CLAUSE_MAP:
   12867              : #if CHECKING_P
   12868              :         /* First check what we're prepared to handle in the following.  */
   12869        77605 :         switch (OMP_CLAUSE_MAP_KIND (c))
   12870              :           {
   12871              :           case GOMP_MAP_ALLOC:
   12872              :           case GOMP_MAP_TO:
   12873              :           case GOMP_MAP_FROM:
   12874              :           case GOMP_MAP_TOFROM:
   12875              :           case GOMP_MAP_POINTER:
   12876              :           case GOMP_MAP_TO_PSET:
   12877              :           case GOMP_MAP_DELETE:
   12878              :           case GOMP_MAP_RELEASE:
   12879              :           case GOMP_MAP_ALWAYS_TO:
   12880              :           case GOMP_MAP_ALWAYS_FROM:
   12881              :           case GOMP_MAP_ALWAYS_TOFROM:
   12882              :           case GOMP_MAP_FORCE_PRESENT:
   12883              :           case GOMP_MAP_ALWAYS_PRESENT_FROM:
   12884              :           case GOMP_MAP_ALWAYS_PRESENT_TO:
   12885              :           case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   12886              : 
   12887              :           case GOMP_MAP_FIRSTPRIVATE_POINTER:
   12888              :           case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   12889              :           case GOMP_MAP_STRUCT:
   12890              :           case GOMP_MAP_STRUCT_UNORD:
   12891              :           case GOMP_MAP_ALWAYS_POINTER:
   12892              :           case GOMP_MAP_ATTACH:
   12893              :           case GOMP_MAP_DETACH:
   12894              :           case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   12895              :           case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   12896              :             break;
   12897         2587 :           case GOMP_MAP_IF_PRESENT:
   12898         2587 :           case GOMP_MAP_FORCE_ALLOC:
   12899         2587 :           case GOMP_MAP_FORCE_TO:
   12900         2587 :           case GOMP_MAP_FORCE_FROM:
   12901         2587 :           case GOMP_MAP_FORCE_TOFROM:
   12902         2587 :           case GOMP_MAP_FORCE_DEVICEPTR:
   12903         2587 :           case GOMP_MAP_DEVICE_RESIDENT:
   12904         2587 :           case GOMP_MAP_LINK:
   12905         2587 :           case GOMP_MAP_FORCE_DETACH:
   12906         2587 :             gcc_assert (is_gimple_omp_oacc (stmt));
   12907              :             break;
   12908            0 :           default:
   12909            0 :             gcc_unreachable ();
   12910              :           }
   12911              : #endif
   12912              :           /* FALLTHRU */
   12913        89161 :       case OMP_CLAUSE_TO:
   12914        89161 :       case OMP_CLAUSE_FROM:
   12915        89161 :       oacc_firstprivate:
   12916        89161 :         var = OMP_CLAUSE_DECL (c);
   12917        89161 :         {
   12918        89161 :           tree extra = lang_hooks.decls.omp_deep_mapping_cnt (stmt, c, &ilist);
   12919        89161 :           if (extra != NULL_TREE && deep_map_cnt != NULL_TREE)
   12920           59 :             deep_map_cnt = fold_build2_loc (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
   12921              :                                             size_type_node, deep_map_cnt,
   12922              :                                             extra);
   12923        89102 :           else if (extra != NULL_TREE)
   12924              :             deep_map_cnt = extra;
   12925              :         }
   12926              : 
   12927        89017 :         if (deep_map_cnt
   12928        89383 :             && OMP_CLAUSE_HAS_ITERATORS (c))
   12929            0 :           sorry ("iterators used together with deep mapping are not "
   12930              :                  "supported yet");
   12931              : 
   12932        89161 :         if (!DECL_P (var))
   12933              :           {
   12934        36762 :             if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
   12935        36762 :                 || (!OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
   12936        35169 :                     && (OMP_CLAUSE_MAP_KIND (c)
   12937              :                         != GOMP_MAP_FIRSTPRIVATE_POINTER)))
   12938        36762 :               map_cnt++;
   12939        46294 :             continue;
   12940              :           }
   12941              : 
   12942        52399 :         if (DECL_SIZE (var)
   12943        52399 :             && !poly_int_tree_p (DECL_SIZE (var)))
   12944              :           {
   12945          717 :             tree var2 = DECL_VALUE_EXPR (var);
   12946          717 :             gcc_assert (TREE_CODE (var2) == INDIRECT_REF);
   12947          717 :             var2 = TREE_OPERAND (var2, 0);
   12948          717 :             gcc_assert (DECL_P (var2));
   12949              :             var = var2;
   12950              :           }
   12951              : 
   12952        52399 :         if (offloaded
   12953        36546 :             && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   12954        85049 :             && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   12955        29415 :                 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   12956              :           {
   12957         3664 :             if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
   12958              :               {
   12959          415 :                 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx))
   12960          415 :                     && varpool_node::get_create (var)->offloadable)
   12961            2 :                   continue;
   12962              : 
   12963          413 :                 tree type = build_pointer_type (TREE_TYPE (var));
   12964          413 :                 tree new_var = lookup_decl (var, ctx);
   12965          413 :                 x = create_tmp_var_raw (type, get_name (new_var));
   12966          413 :                 gimple_add_tmp_var (x);
   12967          413 :                 x = build_simple_mem_ref (x);
   12968          413 :                 SET_DECL_VALUE_EXPR (new_var, x);
   12969          413 :                 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   12970              :               }
   12971         3662 :             continue;
   12972         3662 :           }
   12973              : 
   12974        48735 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   12975        38772 :             && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   12976        38565 :                 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
   12977        48996 :             && is_omp_target (stmt))
   12978              :           {
   12979          237 :             gcc_assert (maybe_lookup_field (c, ctx));
   12980          237 :             map_cnt++;
   12981          237 :             continue;
   12982              :           }
   12983              : 
   12984        48498 :         if (!maybe_lookup_field (c, ctx))
   12985         5631 :           continue;
   12986              : 
   12987              :         /* Don't remap compute constructs' reduction variables, because the
   12988              :            intermediate result must be local to each gang.  */
   12989        70575 :         if (offloaded && !(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   12990        23812 :                            && is_gimple_omp_oacc (ctx->stmt)
   12991        13572 :                            && OMP_CLAUSE_MAP_IN_REDUCTION (c)))
   12992              :           {
   12993        26928 :             x = build_receiver_ref (c, true, ctx);
   12994        26928 :             tree new_var = lookup_decl (var, ctx);
   12995              : 
   12996        26928 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   12997        23032 :                 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
   12998         3013 :                 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
   12999        29941 :                 && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
   13000          425 :               x = build_simple_mem_ref (x);
   13001        26928 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   13002              :               {
   13003         3896 :                 gcc_assert (is_gimple_omp_oacc (ctx->stmt));
   13004         3896 :                 if (omp_privatize_by_reference (new_var)
   13005         3896 :                     && (TREE_CODE (TREE_TYPE (new_var)) != POINTER_TYPE
   13006           44 :                         || DECL_BY_REFERENCE (var)))
   13007              :                   {
   13008              :                     /* Create a local object to hold the instance
   13009              :                        value.  */
   13010          455 :                     tree type = TREE_TYPE (TREE_TYPE (new_var));
   13011          455 :                     const char *id = IDENTIFIER_POINTER (DECL_NAME (new_var));
   13012          455 :                     tree inst = create_tmp_var (type, id);
   13013          455 :                     gimplify_assign (inst, fold_indirect_ref (x), &fplist);
   13014          455 :                     x = build_fold_addr_expr (inst);
   13015              :                   }
   13016         3896 :                 gimplify_assign (new_var, x, &fplist);
   13017              :               }
   13018        23032 :             else if (DECL_P (new_var))
   13019              :               {
   13020        23032 :                 SET_DECL_VALUE_EXPR (new_var, x);
   13021        23032 :                 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   13022              :               }
   13023              :             else
   13024            0 :               gcc_unreachable ();
   13025              :           }
   13026        42867 :         map_cnt++;
   13027        42867 :         break;
   13028              : 
   13029        15163 :       case OMP_CLAUSE_FIRSTPRIVATE:
   13030        15163 :       omp_firstprivate_recv:
   13031        15163 :         gcc_checking_assert (offloaded);
   13032        15163 :         if (is_gimple_omp_oacc (ctx->stmt))
   13033              :           {
   13034              :             /* No 'firstprivate' clauses on OpenACC 'kernels'.  */
   13035         3896 :             gcc_checking_assert (!is_oacc_kernels (ctx));
   13036              :             /* Likewise, on OpenACC 'kernels' decomposed parts.  */
   13037         3896 :             gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));
   13038              : 
   13039         3896 :             goto oacc_firstprivate;
   13040              :           }
   13041        11267 :         map_cnt++;
   13042        11267 :         var = OMP_CLAUSE_DECL (c);
   13043        11267 :         new_var = lookup_decl (var, ctx);
   13044        11267 :         allocator = NULL_TREE;
   13045        11267 :         allocate_ptr = NULL_TREE;
   13046        11267 :         size = TREE_TYPE (var);
   13047        11267 :         by_ref = omp_privatize_by_reference (var);
   13048        11267 :         if (by_ref)
   13049          809 :           size = TREE_TYPE (size);
   13050        11267 :         size = TYPE_SIZE_UNIT (size);
   13051        11267 :         if (is_variable_sized (var, by_ref))
   13052           23 :           size = lookup_decl (size, ctx);
   13053        11267 :         alloc_seq = NULL;
   13054        11267 :         if (lower_private_allocate (var, new_var, allocator, allocate_ptr,
   13055              :                                     &alloc_seq, ctx, by_ref, size))
   13056              :           {
   13057           63 :             alloc_map.put (new_var, allocate_ptr);
   13058           63 :             alloc_seq_map.put (new_var, alloc_seq);
   13059              :           }
   13060        11267 :         if (!by_ref && !is_gimple_reg_type (TREE_TYPE (var)))
   13061              :           {
   13062          125 :             if (is_variable_sized (var))
   13063              :               {
   13064            6 :                 tree pvar = DECL_VALUE_EXPR (var);
   13065            6 :                 gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
   13066            6 :                 pvar = TREE_OPERAND (pvar, 0);
   13067            6 :                 gcc_assert (DECL_P (pvar));
   13068            6 :                 tree new_pvar = lookup_decl (pvar, ctx);
   13069            6 :                 x = build_fold_indirect_ref (new_pvar);
   13070            6 :                 TREE_THIS_NOTRAP (x) = 1;
   13071              :               }
   13072          119 :             else if (allocate_ptr)
   13073           19 :               x = build_fold_indirect_ref (allocate_ptr);
   13074              :             else
   13075          100 :               x = build_receiver_ref (var, true, ctx);
   13076          125 :             SET_DECL_VALUE_EXPR (new_var, x);
   13077          125 :             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   13078              :           }
   13079              :           /* Fortran array descriptors: firstprivate of data + attach.  */
   13080        11267 :           if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR
   13081        11267 :               && lang_hooks.decls.omp_array_data (var, true))
   13082           19 :             map_cnt += 2;
   13083              : 
   13084        11413 :       do_dtor:
   13085        11413 :         if (allocator)
   13086              :           {
   13087          118 :             if (!is_gimple_val (allocator))
   13088              :               {
   13089            0 :                 tree avar = create_tmp_var (TREE_TYPE (allocator));
   13090            0 :                 gimplify_assign (avar, allocator, &alloc_dlist);
   13091            0 :                 allocator = avar;
   13092              :               }
   13093          118 :             if (!is_gimple_val (allocate_ptr))
   13094              :               {
   13095            0 :                 tree apvar = create_tmp_var (TREE_TYPE (allocate_ptr));
   13096            0 :                 gimplify_assign (apvar, allocate_ptr, &alloc_dlist);
   13097            0 :                 allocate_ptr = apvar;
   13098              :               }
   13099          118 :             tree f = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
   13100          118 :             gimple *g = gimple_build_call (f, 2, allocate_ptr, allocator);
   13101          118 :             gimple_seq_add_stmt (&alloc_dlist, g);
   13102              :           }
   13103              :         break;
   13104              : 
   13105          226 :       case OMP_CLAUSE_PRIVATE:
   13106          226 :         gcc_checking_assert (offloaded);
   13107          226 :         if (is_gimple_omp_oacc (ctx->stmt))
   13108              :           {
   13109              :             /* No 'private' clauses on OpenACC 'kernels'.  */
   13110           80 :             gcc_checking_assert (!is_oacc_kernels (ctx));
   13111              :             /* Likewise, on OpenACC 'kernels' decomposed parts.  */
   13112           80 :             gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));
   13113              : 
   13114              :             break;
   13115              :           }
   13116          146 :         var = OMP_CLAUSE_DECL (c);
   13117          146 :         new_var = lookup_decl (var, ctx);
   13118          146 :         allocator = NULL_TREE;
   13119          146 :         allocate_ptr = NULL_TREE;
   13120          146 :         alloc_seq = NULL;
   13121          146 :         size = TREE_TYPE (var);
   13122          146 :         by_ref = omp_privatize_by_reference (var);
   13123          146 :         if (by_ref)
   13124           22 :           size = TREE_TYPE (size);
   13125          146 :         size = TYPE_SIZE_UNIT (size);
   13126          146 :         if (is_variable_sized (var, by_ref))
   13127           21 :           size = lookup_decl (size, ctx);
   13128          146 :         lower_private_allocate (var, new_var, allocator, allocate_ptr,
   13129              :                                 &alloc_seq, ctx, by_ref, size);
   13130          146 :         if (allocate_ptr)
   13131              :           {
   13132           55 :             alloc_map.put (new_var, allocate_ptr);
   13133           55 :             alloc_seq_map.put (new_var, alloc_seq);
   13134              :           }
   13135          146 :         if (!allocate_ptr && is_variable_sized (var))
   13136              :           {
   13137            1 :             tree new_var = lookup_decl (var, ctx);
   13138            1 :             tree pvar = DECL_VALUE_EXPR (var);
   13139            1 :             gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
   13140            1 :             pvar = TREE_OPERAND (pvar, 0);
   13141            1 :             gcc_assert (DECL_P (pvar));
   13142            1 :             tree new_pvar = lookup_decl (pvar, ctx);
   13143            1 :             x = build_fold_indirect_ref (new_pvar);
   13144            1 :             TREE_THIS_NOTRAP (x) = 1;
   13145            1 :             SET_DECL_VALUE_EXPR (new_var, x);
   13146            1 :             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   13147              :           }
   13148          146 :         goto do_dtor;
   13149              : 
   13150         2430 :       case OMP_CLAUSE_USE_DEVICE_PTR:
   13151         2430 :       case OMP_CLAUSE_USE_DEVICE_ADDR:
   13152         2430 :       case OMP_CLAUSE_HAS_DEVICE_ADDR:
   13153         2430 :       case OMP_CLAUSE_IS_DEVICE_PTR:
   13154         2430 :         var = OMP_CLAUSE_DECL (c);
   13155         2430 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
   13156              :           {
   13157          252 :             while (TREE_CODE (var) == INDIRECT_REF
   13158          252 :                    || TREE_CODE (var) == ARRAY_REF)
   13159           17 :               var = TREE_OPERAND (var, 0);
   13160          235 :             if (lang_hooks.decls.omp_array_data (var, true))
   13161           19 :               goto omp_firstprivate_recv;
   13162              :           }
   13163         2411 :         map_cnt++;
   13164         2411 :         if (is_variable_sized (var))
   13165              :           {
   13166           12 :             tree new_var = lookup_decl (var, ctx);
   13167           12 :             tree pvar = DECL_VALUE_EXPR (var);
   13168           12 :             gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
   13169           12 :             pvar = TREE_OPERAND (pvar, 0);
   13170           12 :             gcc_assert (DECL_P (pvar));
   13171           12 :             tree new_pvar = lookup_decl (pvar, ctx);
   13172           12 :             x = build_fold_indirect_ref (new_pvar);
   13173           12 :             TREE_THIS_NOTRAP (x) = 1;
   13174           12 :             SET_DECL_VALUE_EXPR (new_var, x);
   13175           12 :             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   13176              :           }
   13177         2399 :         else if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
   13178          542 :                    || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
   13179         2071 :                   && !omp_privatize_by_reference (var)
   13180          703 :                   && !omp_is_allocatable_or_ptr (var)
   13181          564 :                   && !lang_hooks.decls.omp_array_data (var, true))
   13182         4433 :                  || TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
   13183              :           {
   13184          389 :             tree new_var = lookup_decl (var, ctx);
   13185          389 :             tree type = build_pointer_type (TREE_TYPE (var));
   13186          389 :             x = create_tmp_var_raw (type, get_name (new_var));
   13187          389 :             gimple_add_tmp_var (x);
   13188          389 :             x = build_simple_mem_ref (x);
   13189          389 :             SET_DECL_VALUE_EXPR (new_var, x);
   13190          389 :             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   13191              :           }
   13192              :         else
   13193              :           {
   13194         2010 :             tree new_var = lookup_decl (var, ctx);
   13195         2010 :             x = create_tmp_var_raw (TREE_TYPE (new_var), get_name (new_var));
   13196         2010 :             gimple_add_tmp_var (x);
   13197         2010 :             SET_DECL_VALUE_EXPR (new_var, x);
   13198         2010 :             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   13199              :           }
   13200              :         break;
   13201           10 :         case OMP_CLAUSE_DEVICE_TYPE:
   13202              :           /* FIXME: Ensure that 'nohost' also has not implied before that
   13203              :              'g->have_offload = true' or an implicit declare target.  */
   13204           10 :           if (OMP_CLAUSE_DEVICE_TYPE_KIND (c) != OMP_CLAUSE_DEVICE_TYPE_ANY)
   13205            5 :             sorry_at (OMP_CLAUSE_LOCATION (c),
   13206              :                       "only the %<device_type(any)%> is supported");
   13207              :           break;
   13208              :       }
   13209              : 
   13210        36984 :   if (offloaded)
   13211              :     {
   13212        21048 :       target_nesting_level++;
   13213        21048 :       lower_omp (&tgt_body, ctx);
   13214        21048 :       target_nesting_level--;
   13215              :     }
   13216        15936 :   else if (data_region)
   13217         4020 :     lower_omp (&tgt_body, ctx);
   13218              : 
   13219        36984 :   if (offloaded)
   13220              :     {
   13221              :       /* Declare all the variables created by mapping and the variables
   13222              :          declared in the scope of the target body.  */
   13223        21048 :       record_vars_into (ctx->block_vars, child_fn);
   13224        21048 :       maybe_remove_omp_member_access_dummy_vars (tgt_bind);
   13225        21048 :       record_vars_into (gimple_bind_vars (tgt_bind), child_fn);
   13226              :     }
   13227              : 
   13228        36984 :   if (ctx->record_type)
   13229              :     {
   13230        32117 :       if (deep_map_cnt && TREE_CODE (deep_map_cnt) == INTEGER_CST)
   13231              :         /* map_cnt = map_cnt + tree_to_hwi (deep_map_cnt); */
   13232              :         /* deep_map_cnt = NULL_TREE; */
   13233            0 :         gcc_unreachable ();
   13234          144 :       else if (deep_map_cnt)
   13235              :         {
   13236          144 :           gcc_assert (flexible_array_type_p (ctx->record_type));
   13237          144 :           tree n = create_tmp_var_raw (size_type_node, "nn_map");
   13238          144 :           gimple_add_tmp_var (n);
   13239          144 :           gimplify_assign (n, deep_map_cnt, &ilist);
   13240          144 :           deep_map_cnt = n;
   13241              :         }
   13242          144 :       ctx->sender_decl
   13243        32117 :         = create_tmp_var (deep_map_cnt ? build_pointer_type (ctx->record_type)
   13244              :                                        : ctx->record_type, ".omp_data_arr");
   13245        32117 :       DECL_NAMELESS (ctx->sender_decl) = 1;
   13246        32117 :       TREE_ADDRESSABLE (ctx->sender_decl) = 1;
   13247        64090 :       t = make_tree_vec (deep_map_cnt ? 4 : 3);
   13248        32117 :       TREE_VEC_ELT (t, 0) = ctx->sender_decl;
   13249        32117 :       TREE_VEC_ELT (t, 1)
   13250        64234 :         = create_tmp_var (deep_map_cnt
   13251          144 :                           ? build_pointer_type (size_type_node)
   13252        31973 :                           : build_array_type_nelts (size_type_node, map_cnt),
   13253              :                           ".omp_data_sizes");
   13254        32117 :       DECL_NAMELESS (TREE_VEC_ELT (t, 1)) = 1;
   13255        32117 :       TREE_ADDRESSABLE (TREE_VEC_ELT (t, 1)) = 1;
   13256        32117 :       TREE_STATIC (TREE_VEC_ELT (t, 1)) = 1;
   13257        32117 :       tree tkind_type = short_unsigned_type_node;
   13258        32117 :       int talign_shift = 8;
   13259        32117 :       TREE_VEC_ELT (t, 2)
   13260        64234 :         = create_tmp_var (deep_map_cnt
   13261          144 :                           ? build_pointer_type (tkind_type)
   13262        31973 :                           : build_array_type_nelts (tkind_type, map_cnt),
   13263              :                           ".omp_data_kinds");
   13264        32117 :       DECL_NAMELESS (TREE_VEC_ELT (t, 2)) = 1;
   13265        32117 :       TREE_ADDRESSABLE (TREE_VEC_ELT (t, 2)) = 1;
   13266        32117 :       TREE_STATIC (TREE_VEC_ELT (t, 2)) = 1;
   13267        32117 :       gimple_omp_target_set_data_arg (stmt, t);
   13268              : 
   13269        32117 :       if (deep_map_cnt)
   13270              :         {
   13271          144 :           tree tmp, size;
   13272          144 :           size = create_tmp_var (size_type_node, NULL);
   13273          144 :           DECL_NAMELESS (size) = 1;
   13274          144 :           gimplify_assign (size,
   13275              :                            fold_build2_loc (UNKNOWN_LOCATION, PLUS_EXPR,
   13276              :                                             size_type_node, deep_map_cnt,
   13277              :                                             build_int_cst (size_type_node,
   13278          144 :                                                            map_cnt)), &ilist);
   13279          144 :           TREE_VEC_ELT (t, 3) = size;
   13280              : 
   13281          144 :           tree call = builtin_decl_explicit (BUILT_IN_MALLOC);
   13282          144 :           size = fold_build2_loc (UNKNOWN_LOCATION, MULT_EXPR,
   13283              :                                   size_type_node, deep_map_cnt,
   13284          144 :                                   TYPE_SIZE_UNIT (ptr_type_node));
   13285          144 :           size = fold_build2_loc (UNKNOWN_LOCATION, PLUS_EXPR,
   13286              :                                   size_type_node, size,
   13287          144 :                                   TYPE_SIZE_UNIT (ctx->record_type));
   13288          144 :           tmp = build_call_expr_loc (input_location, call, 1, size);
   13289          144 :           gimplify_assign (ctx->sender_decl, tmp, &ilist);
   13290              : 
   13291          144 :           size = fold_build2_loc (UNKNOWN_LOCATION, MULT_EXPR,
   13292          144 :                                   size_type_node, TREE_VEC_ELT (t, 3),
   13293          144 :                                   TYPE_SIZE_UNIT (size_type_node));
   13294          144 :           tmp = build_call_expr_loc (input_location, call, 1, size);
   13295          144 :           gimplify_assign (TREE_VEC_ELT (t, 1), tmp, &ilist);
   13296              : 
   13297          144 :           size = fold_build2_loc (UNKNOWN_LOCATION, MULT_EXPR,
   13298          144 :                                   size_type_node, TREE_VEC_ELT (t, 3),
   13299          144 :                                   TYPE_SIZE_UNIT (tkind_type));
   13300          144 :           tmp = build_call_expr_loc (input_location, call, 1, size);
   13301          144 :           gimplify_assign (TREE_VEC_ELT (t, 2), tmp, &ilist);
   13302          144 :           tree field = TYPE_FIELDS (TREE_TYPE (TREE_TYPE (ctx->sender_decl)));
   13303          595 :           for ( ; DECL_CHAIN (field) != NULL_TREE; field = DECL_CHAIN (field))
   13304              :             ;
   13305          144 :           gcc_assert (TREE_CODE (TREE_TYPE (field)));
   13306          144 :           tmp = build_fold_indirect_ref (ctx->sender_decl);
   13307          144 :           deep_map_data = omp_build_component_ref (tmp, field);
   13308          144 :           deep_map_offset_data = create_tmp_var_raw (size_type_node,
   13309              :                                                      "map_offset_data");
   13310          144 :           deep_map_offset = create_tmp_var_raw (size_type_node, "map_offset");
   13311          144 :           gimple_add_tmp_var (deep_map_offset_data);
   13312          144 :           gimple_add_tmp_var (deep_map_offset);
   13313          144 :           gimplify_assign (deep_map_offset_data, build_int_cst (size_type_node,
   13314              :                                                                 0), &ilist);
   13315          144 :           gimplify_assign (deep_map_offset, build_int_cst (size_type_node,
   13316          144 :                                                            map_cnt), &ilist);
   13317              :         }
   13318              : 
   13319        32117 :       vec<constructor_elt, va_gc> *vsize;
   13320        32117 :       vec<constructor_elt, va_gc> *vkind;
   13321        32117 :       vec_alloc (vsize, map_cnt);
   13322        32117 :       vec_alloc (vkind, map_cnt);
   13323        32117 :       unsigned int map_idx = 0;
   13324              : 
   13325       161228 :       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
   13326       129111 :         switch (OMP_CLAUSE_CODE (c))
   13327              :           {
   13328              :             tree ovar, nc, s, purpose, var, x, type;
   13329              :             unsigned int talign;
   13330              : 
   13331              :           default:
   13332       125147 :             break;
   13333              : 
   13334        87662 :           case OMP_CLAUSE_MAP:
   13335        87662 :           case OMP_CLAUSE_TO:
   13336        87662 :           case OMP_CLAUSE_FROM:
   13337        87662 :           oacc_firstprivate_map:
   13338        87662 :             nc = c;
   13339        87662 :             ovar = OMP_CLAUSE_DECL (c);
   13340        87662 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13341        87662 :                 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   13342        72703 :                     || (OMP_CLAUSE_MAP_KIND (c)
   13343              :                         == GOMP_MAP_FIRSTPRIVATE_REFERENCE)))
   13344              :               break;
   13345        83830 :             if (deep_map_cnt)
   13346              :               {
   13347          428 :                 unsigned HOST_WIDE_INT tkind2;
   13348          428 :                 switch (OMP_CLAUSE_CODE (c))
   13349              :                   {
   13350          424 :                   case OMP_CLAUSE_MAP:
   13351          424 :                     tkind2 = OMP_CLAUSE_MAP_KIND (c);
   13352          424 :                     if (OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (c)
   13353          424 :                         && (((tkind2 & GOMP_MAP_FLAG_SPECIAL_BITS)
   13354              :                              & ~GOMP_MAP_IMPLICIT)
   13355              :                             == 0))
   13356              :                       {
   13357              :                         /* If this is an implicit map, and the GOMP_MAP_IMPLICIT
   13358              :                            bits are not interfered by other special bit
   13359              :                            encodings, then turn the GOMP_IMPLICIT_BIT flag on
   13360              :                            for the runtime to see.  */
   13361          120 :                         tkind2 |= GOMP_MAP_IMPLICIT;
   13362              :                       }
   13363              :                     break;
   13364              :                   case OMP_CLAUSE_FIRSTPRIVATE: tkind2 = GOMP_MAP_TO; break;
   13365              :                   case OMP_CLAUSE_TO: tkind2 = GOMP_MAP_TO; break;
   13366            2 :                   case OMP_CLAUSE_FROM: tkind2 = GOMP_MAP_FROM; break;
   13367            0 :                   default: gcc_unreachable ();
   13368              :                   }
   13369          428 :                 lang_hooks.decls.omp_deep_mapping (stmt, c, tkind2,
   13370              :                                                    deep_map_data,
   13371          428 :                                                    TREE_VEC_ELT (t, 1),
   13372          428 :                                                    TREE_VEC_ELT (t, 2),
   13373              :                                                    deep_map_offset_data,
   13374              :                                                    deep_map_offset, &ilist);
   13375              :               }
   13376        83830 :             if (!DECL_P (ovar))
   13377              :               {
   13378        36762 :                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13379        36762 :                     && OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
   13380              :                   {
   13381            0 :                     nc = OMP_CLAUSE_CHAIN (c);
   13382            0 :                     gcc_checking_assert (OMP_CLAUSE_DECL (nc)
   13383              :                                          == get_base_address (ovar));
   13384            0 :                     ovar = OMP_CLAUSE_DECL (nc);
   13385              :                   }
   13386              :                 else
   13387              :                   {
   13388        36762 :                     tree x = build_sender_ref (c, ctx);
   13389        36762 :                     tree v = ovar;
   13390        36762 :                     if (in_reduction_clauses
   13391          163 :                         && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13392        36925 :                         && OMP_CLAUSE_MAP_IN_REDUCTION (c))
   13393              :                       {
   13394          104 :                         v = unshare_expr (v);
   13395          104 :                         tree *p = &v;
   13396          104 :                         while (handled_component_p (*p)
   13397              :                                || TREE_CODE (*p) == INDIRECT_REF
   13398              :                                || TREE_CODE (*p) == ADDR_EXPR
   13399              :                                || TREE_CODE (*p) == MEM_REF
   13400          256 :                                || TREE_CODE (*p) == NON_LVALUE_EXPR)
   13401          152 :                           p = &TREE_OPERAND (*p, 0);
   13402          104 :                         tree d = *p;
   13403          104 :                         if (is_variable_sized (d))
   13404              :                           {
   13405           16 :                             gcc_assert (DECL_HAS_VALUE_EXPR_P (d));
   13406           16 :                             d = DECL_VALUE_EXPR (d);
   13407           16 :                             gcc_assert (TREE_CODE (d) == INDIRECT_REF);
   13408           16 :                             d = TREE_OPERAND (d, 0);
   13409           16 :                             gcc_assert (DECL_P (d));
   13410              :                           }
   13411          104 :                         splay_tree_key key
   13412          104 :                           = (splay_tree_key) &DECL_CONTEXT (d);
   13413          104 :                         tree nd = (tree) splay_tree_lookup (ctx->field_map,
   13414          104 :                                                             key)->value;
   13415          104 :                         if (d == *p)
   13416           88 :                           *p = nd;
   13417              :                         else
   13418           16 :                           *p = build_fold_indirect_ref (nd);
   13419              :                       }
   13420        36762 :                     v = build_fold_addr_expr_with_type (v, ptr_type_node);
   13421        36762 :                     v = lower_omp_map_iterator_expr (v, c, stmt);
   13422        36762 :                     gimplify_assign (x, v, &ilist);
   13423        36762 :                     nc = NULL_TREE;
   13424              :                   }
   13425              :               }
   13426              :             else
   13427              :               {
   13428        47068 :                 if (DECL_SIZE (ovar)
   13429        47068 :                     && !poly_int_tree_p (DECL_SIZE (ovar)))
   13430              :                   {
   13431            7 :                     tree ovar2 = DECL_VALUE_EXPR (ovar);
   13432            7 :                     gcc_assert (TREE_CODE (ovar2) == INDIRECT_REF);
   13433            7 :                     ovar2 = TREE_OPERAND (ovar2, 0);
   13434            7 :                     gcc_assert (DECL_P (ovar2));
   13435              :                     ovar = ovar2;
   13436              :                   }
   13437        47068 :                 if (!maybe_lookup_field (c, ctx)
   13438        51032 :                     && !(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13439         3964 :                          && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   13440         3964 :                              || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)))
   13441         3964 :                   continue;
   13442              :               }
   13443              : 
   13444        79866 :             talign = TYPE_ALIGN_UNIT (TREE_TYPE (ovar));
   13445        79866 :             if (DECL_P (ovar) && DECL_ALIGN_UNIT (ovar) > talign)
   13446         6409 :               talign = DECL_ALIGN_UNIT (ovar);
   13447              : 
   13448        79866 :             var = NULL_TREE;
   13449        79866 :             if (nc)
   13450              :               {
   13451        43104 :                 if (in_reduction_clauses
   13452          897 :                     && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13453        44001 :                     && OMP_CLAUSE_MAP_IN_REDUCTION (c))
   13454              :                   {
   13455          268 :                     tree d = ovar;
   13456          268 :                     if (is_variable_sized (d))
   13457              :                       {
   13458            0 :                         gcc_assert (DECL_HAS_VALUE_EXPR_P (d));
   13459            0 :                         d = DECL_VALUE_EXPR (d);
   13460            0 :                         gcc_assert (TREE_CODE (d) == INDIRECT_REF);
   13461            0 :                         d = TREE_OPERAND (d, 0);
   13462            0 :                         gcc_assert (DECL_P (d));
   13463              :                       }
   13464          268 :                     splay_tree_key key
   13465          268 :                       = (splay_tree_key) &DECL_CONTEXT (d);
   13466          268 :                     tree nd = (tree) splay_tree_lookup (ctx->field_map,
   13467          268 :                                                         key)->value;
   13468          268 :                     if (d == ovar)
   13469              :                       var = nd;
   13470              :                     else
   13471            0 :                       var = build_fold_indirect_ref (nd);
   13472              :                   }
   13473              :                 else
   13474        42836 :                   var = lookup_decl_in_outer_ctx (ovar, ctx);
   13475              :               }
   13476        43104 :             if (nc
   13477        43104 :                 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13478        33141 :                 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   13479        32934 :                     || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
   13480          261 :                 && is_omp_target (stmt))
   13481              :               {
   13482          237 :                 x = build_sender_ref (c, ctx);
   13483          237 :                 gimplify_assign (x, build_fold_addr_expr (var), &ilist);
   13484              :               }
   13485        79629 :             else if (nc)
   13486              :               {
   13487        42867 :                 x = build_sender_ref (nc, ctx);
   13488              : 
   13489        42867 :                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13490        32904 :                     && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
   13491         5183 :                     && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
   13492        48050 :                     && TREE_CODE (TREE_TYPE (ovar)) == ARRAY_TYPE)
   13493              :                   {
   13494          425 :                     gcc_assert (offloaded);
   13495          425 :                     tree avar = build_fold_addr_expr (var);
   13496          425 :                     if (!OMP_CLAUSE_ITERATORS (c))
   13497              :                       {
   13498          425 :                         tree tmp = create_tmp_var (TREE_TYPE (TREE_TYPE (x)));
   13499          425 :                         mark_addressable (tmp);
   13500          425 :                         gimplify_assign (tmp, avar, &ilist);
   13501          425 :                         avar = tmp;
   13502              :                       }
   13503          425 :                     talign = TYPE_ALIGN_UNIT (TREE_TYPE (TREE_TYPE (x)));
   13504          425 :                     avar = build_fold_addr_expr (avar);
   13505          425 :                     avar = lower_omp_map_iterator_expr (avar, c, stmt);
   13506          425 :                     gimplify_assign (x, avar, &ilist);
   13507              :                   }
   13508        42442 :                 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   13509              :                   {
   13510         3896 :                     gcc_assert (is_gimple_omp_oacc (ctx->stmt));
   13511         3896 :                     if (!omp_privatize_by_reference (var))
   13512              :                       {
   13513         3441 :                         if (is_gimple_reg (var)
   13514         3441 :                             && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   13515         2578 :                           suppress_warning (var);
   13516         3441 :                         var = build_fold_addr_expr (var);
   13517              :                       }
   13518              :                     else
   13519          455 :                       talign = TYPE_ALIGN_UNIT (TREE_TYPE (TREE_TYPE (ovar)));
   13520         3896 :                     gimplify_assign (x, var, &ilist);
   13521              :                   }
   13522        38546 :                 else if (is_gimple_reg (var))
   13523              :                   {
   13524         5283 :                     gcc_assert (offloaded);
   13525         5283 :                     tree avar = create_tmp_var (TREE_TYPE (var));
   13526         5283 :                     mark_addressable (avar);
   13527         5283 :                     enum gomp_map_kind map_kind = OMP_CLAUSE_MAP_KIND (c);
   13528         5283 :                     if (GOMP_MAP_COPY_TO_P (map_kind)
   13529              :                         || map_kind == GOMP_MAP_POINTER
   13530          475 :                         || map_kind == GOMP_MAP_TO_PSET
   13531            2 :                         || map_kind == GOMP_MAP_FORCE_DEVICEPTR)
   13532              :                       {
   13533              :                         /* If we need to initialize a temporary
   13534              :                            with VAR because it is not addressable, and
   13535              :                            the variable hasn't been initialized yet, then
   13536              :                            we'll get a warning for the store to avar.
   13537              :                            Don't warn in that case, the mapping might
   13538              :                            be implicit.  */
   13539         5281 :                         suppress_warning (var, OPT_Wuninitialized);
   13540         5281 :                         gimplify_assign (avar, var, &ilist);
   13541              :                       }
   13542         5283 :                     avar = build_fold_addr_expr (avar);
   13543         5283 :                     gimplify_assign (x, avar, &ilist);
   13544         5283 :                     if ((GOMP_MAP_COPY_FROM_P (map_kind)
   13545         1486 :                          || map_kind == GOMP_MAP_FORCE_DEVICEPTR)
   13546         9080 :                         && !TYPE_READONLY (TREE_TYPE (var)))
   13547              :                       {
   13548         3797 :                         x = unshare_expr (x);
   13549         3797 :                         x = build_simple_mem_ref (x);
   13550         3797 :                         gimplify_assign (var, x, &olist);
   13551              :                       }
   13552              :                   }
   13553              :                 else
   13554              :                   {
   13555              :                     /* While MAP is handled explicitly by the FE,
   13556              :                        for 'target update', only the identified is passed.  */
   13557        33263 :                     if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM
   13558        28139 :                          || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO)
   13559        34206 :                         && (omp_is_allocatable_or_ptr (var)
   13560          120 :                             && omp_check_optional_argument (var, false)))
   13561            0 :                       var = build_fold_indirect_ref (var);
   13562        33263 :                     else if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FROM
   13563        28139 :                               && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TO)
   13564        34206 :                              || (!omp_is_allocatable_or_ptr (var)
   13565         5947 :                                  && !omp_check_optional_argument (var, false)))
   13566        33143 :                       var = build_fold_addr_expr (var);
   13567        33263 :                     gimplify_assign (x, var, &ilist);
   13568              :                   }
   13569              :               }
   13570        79866 :             s = NULL_TREE;
   13571        79866 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   13572              :               {
   13573         3896 :                 gcc_checking_assert (is_gimple_omp_oacc (ctx->stmt));
   13574         3896 :                 s = TREE_TYPE (ovar);
   13575         3896 :                 if (TREE_CODE (s) == REFERENCE_TYPE
   13576         3896 :                     || omp_check_optional_argument (ovar, false))
   13577          449 :                   s = TREE_TYPE (s);
   13578         3896 :                 s = TYPE_SIZE_UNIT (s);
   13579              :               }
   13580              :             else
   13581        75970 :               s = OMP_CLAUSE_SIZE (c);
   13582        79866 :             if (s == NULL_TREE)
   13583          123 :               s = TYPE_SIZE_UNIT (TREE_TYPE (ovar));
   13584        79866 :             s = fold_convert (size_type_node, s);
   13585        79866 :             s = lower_omp_map_iterator_size (s, c, stmt);
   13586        79866 :             purpose = size_int (map_idx++);
   13587        79866 :             CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
   13588        79866 :             if (TREE_CODE (s) != INTEGER_CST)
   13589        16152 :               TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;
   13590              : 
   13591        79866 :             unsigned HOST_WIDE_INT tkind, tkind_zero;
   13592        79866 :             switch (OMP_CLAUSE_CODE (c))
   13593              :               {
   13594        68310 :               case OMP_CLAUSE_MAP:
   13595        68310 :                 tkind = OMP_CLAUSE_MAP_KIND (c);
   13596        68310 :                 tkind_zero = tkind;
   13597        68310 :                 if (OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c))
   13598         5276 :                   switch (tkind)
   13599              :                     {
   13600              :                     case GOMP_MAP_ALLOC:
   13601              :                     case GOMP_MAP_IF_PRESENT:
   13602              :                     case GOMP_MAP_TO:
   13603              :                     case GOMP_MAP_FROM:
   13604              :                     case GOMP_MAP_TOFROM:
   13605              :                     case GOMP_MAP_ALWAYS_TO:
   13606              :                     case GOMP_MAP_ALWAYS_FROM:
   13607              :                     case GOMP_MAP_ALWAYS_TOFROM:
   13608              :                     case GOMP_MAP_ALWAYS_PRESENT_TO:
   13609              :                     case GOMP_MAP_ALWAYS_PRESENT_FROM:
   13610              :                     case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   13611              :                     case GOMP_MAP_RELEASE:
   13612              :                     case GOMP_MAP_FORCE_TO:
   13613              :                     case GOMP_MAP_FORCE_FROM:
   13614              :                     case GOMP_MAP_FORCE_TOFROM:
   13615              :                     case GOMP_MAP_FORCE_PRESENT:
   13616        68310 :                       tkind_zero = GOMP_MAP_ZERO_LEN_ARRAY_SECTION;
   13617              :                       break;
   13618           21 :                     case GOMP_MAP_DELETE:
   13619           21 :                       tkind_zero = GOMP_MAP_DELETE_ZERO_LEN_ARRAY_SECTION;
   13620              :                     default:
   13621              :                       break;
   13622              :                     }
   13623        68310 :                 if (tkind_zero != tkind)
   13624              :                   {
   13625         5276 :                     if (integer_zerop (s))
   13626              :                       tkind = tkind_zero;
   13627         4550 :                     else if (integer_nonzerop (s))
   13628        68310 :                       tkind_zero = tkind;
   13629              :                   }
   13630        68310 :                 if (tkind_zero == tkind
   13631        66849 :                     && OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (c)
   13632        68310 :                     && (((tkind & GOMP_MAP_FLAG_SPECIAL_BITS)
   13633         5219 :                          & ~GOMP_MAP_IMPLICIT)
   13634              :                         == 0))
   13635              :                   {
   13636              :                     /* If this is an implicit map, and the GOMP_MAP_IMPLICIT
   13637              :                        bits are not interfered by other special bit encodings,
   13638              :                        then turn the GOMP_IMPLICIT_BIT flag on for the runtime
   13639              :                        to see.  */
   13640         5176 :                     tkind |= GOMP_MAP_IMPLICIT;
   13641         5176 :                     tkind_zero = tkind;
   13642              :                   }
   13643              :                 break;
   13644         3896 :               case OMP_CLAUSE_FIRSTPRIVATE:
   13645         3896 :                 gcc_checking_assert (is_gimple_omp_oacc (ctx->stmt));
   13646              :                 tkind = GOMP_MAP_TO;
   13647              :                 tkind_zero = tkind;
   13648              :                 break;
   13649         1639 :               case OMP_CLAUSE_TO:
   13650         1639 :                 tkind
   13651         1639 :                   = (OMP_CLAUSE_MOTION_PRESENT (c)
   13652         1639 :                      ? GOMP_MAP_ALWAYS_PRESENT_TO : GOMP_MAP_TO);
   13653              :                 tkind_zero = tkind;
   13654              :                 break;
   13655         6021 :               case OMP_CLAUSE_FROM:
   13656         6021 :                 tkind
   13657         6021 :                   = (OMP_CLAUSE_MOTION_PRESENT (c)
   13658         6021 :                      ? GOMP_MAP_ALWAYS_PRESENT_FROM : GOMP_MAP_FROM);
   13659              :                 tkind_zero = tkind;
   13660              :                 break;
   13661            0 :               default:
   13662            0 :                 gcc_unreachable ();
   13663              :               }
   13664        68310 :             gcc_checking_assert (tkind
   13665              :                                  < (HOST_WIDE_INT_C (1U) << talign_shift));
   13666        79866 :             gcc_checking_assert (tkind_zero
   13667              :                                  < (HOST_WIDE_INT_C (1U) << talign_shift));
   13668        79866 :             talign = ceil_log2 (talign);
   13669        79866 :             tkind |= talign << talign_shift;
   13670        79866 :             tkind_zero |= talign << talign_shift;
   13671        79866 :             gcc_checking_assert (tkind
   13672              :                                  <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
   13673        79866 :             gcc_checking_assert (tkind_zero
   13674              :                                  <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
   13675        79866 :             if (tkind == tkind_zero)
   13676        78405 :               x = build_int_cstu (tkind_type, tkind);
   13677              :             else
   13678              :               {
   13679         1461 :                 TREE_STATIC (TREE_VEC_ELT (t, 2)) = 0;
   13680         1461 :                 x = build3 (COND_EXPR, tkind_type,
   13681              :                             fold_build2 (EQ_EXPR, boolean_type_node,
   13682              :                                          unshare_expr (s), size_zero_node),
   13683         1461 :                             build_int_cstu (tkind_type, tkind_zero),
   13684         1461 :                             build_int_cstu (tkind_type, tkind));
   13685              :               }
   13686        79866 :             CONSTRUCTOR_APPEND_ELT (vkind, purpose, x);
   13687        79866 :             if (nc && nc != c)
   13688            0 :               c = nc;
   13689              :             break;
   13690              : 
   13691        15163 :           case OMP_CLAUSE_FIRSTPRIVATE:
   13692        15163 :           omp_has_device_addr_descr:
   13693        15163 :             if (is_gimple_omp_oacc (ctx->stmt))
   13694         3896 :               goto oacc_firstprivate_map;
   13695        11267 :             ovar = OMP_CLAUSE_DECL (c);
   13696        11267 :             if (omp_privatize_by_reference (ovar))
   13697          809 :               talign = TYPE_ALIGN_UNIT (TREE_TYPE (TREE_TYPE (ovar)));
   13698              :             else
   13699        10458 :               talign = DECL_ALIGN_UNIT (ovar);
   13700        11267 :             var = lookup_decl_in_outer_ctx (ovar, ctx);
   13701        11267 :             x = build_sender_ref (ovar, ctx);
   13702        11267 :             tkind = GOMP_MAP_FIRSTPRIVATE;
   13703        11267 :             type = TREE_TYPE (ovar);
   13704        11267 :             if (omp_privatize_by_reference (ovar))
   13705          809 :               type = TREE_TYPE (type);
   13706        11267 :             if ((INTEGRAL_TYPE_P (type)
   13707        10895 :                  && TYPE_PRECISION (type) <= POINTER_SIZE)
   13708        11277 :                 || TREE_CODE (type) == POINTER_TYPE)
   13709              :               {
   13710        11040 :                 tkind = GOMP_MAP_FIRSTPRIVATE_INT;
   13711        11040 :                 tree t = var;
   13712        11040 :                 if (omp_privatize_by_reference (var))
   13713          766 :                   t = build_simple_mem_ref (var);
   13714        10274 :                 else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   13715         9210 :                   suppress_warning (var);
   13716        11040 :                 if (TREE_CODE (type) != POINTER_TYPE)
   13717        10885 :                   t = fold_convert (pointer_sized_int_node, t);
   13718        11040 :                 t = fold_convert (TREE_TYPE (x), t);
   13719        11040 :                 gimplify_assign (x, t, &ilist);
   13720              :               }
   13721          227 :             else if (omp_privatize_by_reference (var))
   13722           43 :               gimplify_assign (x, var, &ilist);
   13723          184 :             else if (is_gimple_reg (var))
   13724              :               {
   13725           47 :                 tree avar = create_tmp_var (TREE_TYPE (var));
   13726           47 :                 mark_addressable (avar);
   13727           47 :                 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   13728           40 :                   suppress_warning (var);
   13729           47 :                 gimplify_assign (avar, var, &ilist);
   13730           47 :                 avar = build_fold_addr_expr (avar);
   13731           47 :                 gimplify_assign (x, avar, &ilist);
   13732              :               }
   13733              :             else
   13734              :               {
   13735          137 :                 var = build_fold_addr_expr (var);
   13736          137 :                 gimplify_assign (x, var, &ilist);
   13737              :               }
   13738          227 :             if (tkind == GOMP_MAP_FIRSTPRIVATE_INT)
   13739        11040 :               s = size_int (0);
   13740          227 :             else if (omp_privatize_by_reference (ovar))
   13741           43 :               s = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ovar)));
   13742              :             else
   13743          184 :               s = TYPE_SIZE_UNIT (TREE_TYPE (ovar));
   13744        11267 :             s = fold_convert (size_type_node, s);
   13745        11267 :             purpose = size_int (map_idx++);
   13746        11267 :             CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
   13747        11267 :             if (TREE_CODE (s) != INTEGER_CST)
   13748           23 :               TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;
   13749              : 
   13750        11267 :             gcc_checking_assert (tkind
   13751              :                                  < (HOST_WIDE_INT_C (1U) << talign_shift));
   13752        11267 :             talign = ceil_log2 (talign);
   13753        11267 :             tkind |= talign << talign_shift;
   13754        11267 :             gcc_checking_assert (tkind
   13755              :                                  <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
   13756        11267 :             CONSTRUCTOR_APPEND_ELT (vkind, purpose,
   13757              :                                     build_int_cstu (tkind_type, tkind));
   13758              :             /* Fortran array descriptors: firstprivate of data + attach.  */
   13759        11267 :             if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR
   13760        11267 :                 && lang_hooks.decls.omp_array_data (ovar, true))
   13761              :               {
   13762           19 :                 tree not_null_lb, null_lb, after_lb;
   13763           19 :                 tree var1, var2, size1, size2;
   13764           19 :                 tree present = omp_check_optional_argument (ovar, true);
   13765           19 :                 if (present)
   13766              :                   {
   13767            1 :                     location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   13768            1 :                     not_null_lb = create_artificial_label (clause_loc);
   13769            1 :                     null_lb = create_artificial_label (clause_loc);
   13770            1 :                     after_lb = create_artificial_label (clause_loc);
   13771            1 :                     gimple_seq seq = NULL;
   13772            1 :                     present = force_gimple_operand (present, &seq, true,
   13773              :                                                     NULL_TREE);
   13774            1 :                     gimple_seq_add_seq (&ilist, seq);
   13775            1 :                     gimple_seq_add_stmt (&ilist,
   13776            1 :                       gimple_build_cond_from_tree (present,
   13777              :                                                    not_null_lb, null_lb));
   13778            1 :                     gimple_seq_add_stmt (&ilist,
   13779            1 :                                          gimple_build_label (not_null_lb));
   13780              :                   }
   13781           19 :                 var1 = lang_hooks.decls.omp_array_data (var, false);
   13782           19 :                 size1 = lang_hooks.decls.omp_array_size (var, &ilist);
   13783           19 :                 var2 = build_fold_addr_expr (x);
   13784           19 :                 if (!POINTER_TYPE_P (TREE_TYPE (var)))
   13785            0 :                   var = build_fold_addr_expr (var);
   13786           19 :                 size2 = fold_build2 (POINTER_DIFF_EXPR, ssizetype,
   13787              :                                    build_fold_addr_expr (var1), var);
   13788           19 :                 size2 = fold_convert (sizetype, size2);
   13789           19 :                 if (present)
   13790              :                   {
   13791            1 :                     tree tmp = create_tmp_var (TREE_TYPE (var1));
   13792            1 :                     gimplify_assign (tmp, var1, &ilist);
   13793            1 :                     var1 = tmp;
   13794            1 :                     tmp = create_tmp_var (TREE_TYPE (var2));
   13795            1 :                     gimplify_assign (tmp, var2, &ilist);
   13796            1 :                     var2 = tmp;
   13797            1 :                     tmp = create_tmp_var (TREE_TYPE (size1));
   13798            1 :                     gimplify_assign (tmp, size1, &ilist);
   13799            1 :                     size1 = tmp;
   13800            1 :                     tmp = create_tmp_var (TREE_TYPE (size2));
   13801            1 :                     gimplify_assign (tmp, size2, &ilist);
   13802            1 :                     size2 = tmp;
   13803            1 :                     gimple_seq_add_stmt (&ilist, gimple_build_goto (after_lb));
   13804            1 :                     gimple_seq_add_stmt (&ilist, gimple_build_label (null_lb));
   13805            1 :                     gimplify_assign (var1, null_pointer_node, &ilist);
   13806            1 :                     gimplify_assign (var2, null_pointer_node, &ilist);
   13807            1 :                     gimplify_assign (size1, size_zero_node, &ilist);
   13808            1 :                     gimplify_assign (size2, size_zero_node, &ilist);
   13809            1 :                     gimple_seq_add_stmt (&ilist, gimple_build_label (after_lb));
   13810              :                   }
   13811           19 :                 x = build_sender_ref ((splay_tree_key) &DECL_NAME (ovar), ctx);
   13812           19 :                 gimplify_assign (x, var1, &ilist);
   13813           19 :                 tkind = GOMP_MAP_FIRSTPRIVATE;
   13814           19 :                 talign = DECL_ALIGN_UNIT (ovar);
   13815           19 :                 talign = ceil_log2 (talign);
   13816           19 :                 tkind |= talign << talign_shift;
   13817           19 :                 gcc_checking_assert (tkind
   13818              :                                      <= tree_to_uhwi (
   13819              :                                           TYPE_MAX_VALUE (tkind_type)));
   13820           19 :                 purpose = size_int (map_idx++);
   13821           19 :                 CONSTRUCTOR_APPEND_ELT (vsize, purpose, size1);
   13822           19 :                 if (TREE_CODE (size1) != INTEGER_CST)
   13823           19 :                   TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;
   13824           19 :                 CONSTRUCTOR_APPEND_ELT (vkind, purpose,
   13825              :                                         build_int_cstu (tkind_type, tkind));
   13826           19 :                 x = build_sender_ref ((splay_tree_key) &DECL_UID (ovar), ctx);
   13827           19 :                 gimplify_assign (x, var2, &ilist);
   13828           19 :                 tkind = GOMP_MAP_ATTACH;
   13829           19 :                 purpose = size_int (map_idx++);
   13830           19 :                 CONSTRUCTOR_APPEND_ELT (vsize, purpose, size2);
   13831           19 :                 CONSTRUCTOR_APPEND_ELT (vkind, purpose,
   13832              :                                         build_int_cstu (tkind_type, tkind));
   13833              :               }
   13834              :             break;
   13835              : 
   13836         2430 :           case OMP_CLAUSE_USE_DEVICE_PTR:
   13837         2430 :           case OMP_CLAUSE_USE_DEVICE_ADDR:
   13838         2430 :           case OMP_CLAUSE_HAS_DEVICE_ADDR:
   13839         2430 :           case OMP_CLAUSE_IS_DEVICE_PTR:
   13840         2430 :             ovar = OMP_CLAUSE_DECL (c);
   13841         2430 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
   13842              :               {
   13843          235 :                 if (lang_hooks.decls.omp_array_data (ovar, true))
   13844           19 :                   goto omp_has_device_addr_descr;
   13845          233 :                 while (TREE_CODE (ovar) == INDIRECT_REF
   13846          233 :                        || TREE_CODE (ovar) == ARRAY_REF)
   13847           17 :                   ovar = TREE_OPERAND (ovar, 0);
   13848              :               }
   13849         2411 :             var = lookup_decl_in_outer_ctx (ovar, ctx);
   13850              : 
   13851         2411 :             if (lang_hooks.decls.omp_array_data (ovar, true))
   13852              :               {
   13853          601 :                 tkind = ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IS_DEVICE_PTR
   13854          601 :                           && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR)
   13855          601 :                          ? GOMP_MAP_USE_DEVICE_PTR : GOMP_MAP_FIRSTPRIVATE_INT);
   13856          601 :                 x = build_sender_ref ((splay_tree_key) &DECL_NAME (ovar), ctx);
   13857              :               }
   13858         1810 :             else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IS_DEVICE_PTR
   13859         1810 :                      && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR)
   13860              :               {
   13861         1453 :                 tkind = GOMP_MAP_USE_DEVICE_PTR;
   13862         1453 :                 x = build_sender_ref ((splay_tree_key) &DECL_UID (ovar), ctx);
   13863              :               }
   13864              :             else
   13865              :               {
   13866          357 :                 tkind = GOMP_MAP_FIRSTPRIVATE_INT;
   13867          357 :                 x = build_sender_ref (ovar, ctx);
   13868              :               }
   13869              : 
   13870         2411 :             if (is_gimple_omp_oacc (ctx->stmt))
   13871              :               {
   13872          147 :                 gcc_assert (tkind == GOMP_MAP_USE_DEVICE_PTR);
   13873              : 
   13874          147 :                 if (OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c))
   13875           57 :                   tkind = GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT;
   13876              :               }
   13877              : 
   13878         2411 :             type = TREE_TYPE (ovar);
   13879         2411 :             if (lang_hooks.decls.omp_array_data (ovar, true))
   13880          601 :               var = lang_hooks.decls.omp_array_data (var, false);
   13881         1810 :             else if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
   13882          542 :                       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
   13883         1484 :                       && !omp_privatize_by_reference (ovar)
   13884          512 :                       && !omp_is_allocatable_or_ptr (ovar))
   13885         3247 :                      || TREE_CODE (type) == ARRAY_TYPE)
   13886          401 :               var = build_fold_addr_expr (var);
   13887              :             else
   13888              :               {
   13889         1409 :                 if (omp_privatize_by_reference (ovar)
   13890          370 :                     || omp_check_optional_argument (ovar, false)
   13891         1779 :                     || omp_is_allocatable_or_ptr (ovar))
   13892              :                   {
   13893         1212 :                     type = TREE_TYPE (type);
   13894         1212 :                     if (POINTER_TYPE_P (type)
   13895         1212 :                         && TREE_CODE (type) != ARRAY_TYPE
   13896         1571 :                         && ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_USE_DEVICE_ADDR
   13897           36 :                             && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR
   13898           28 :                             && !omp_is_allocatable_or_ptr (ovar))
   13899          337 :                            || (omp_privatize_by_reference (ovar)
   13900          337 :                                && omp_is_allocatable_or_ptr (ovar))))
   13901          357 :                       var = build_simple_mem_ref (var);
   13902         1212 :                     var = fold_convert (TREE_TYPE (x), var);
   13903              :                   }
   13904              :               }
   13905         2411 :             tree present;
   13906         2411 :             present = omp_check_optional_argument (ovar, true);
   13907         2411 :             if (present)
   13908              :               {
   13909          878 :                 tree null_label = create_artificial_label (UNKNOWN_LOCATION);
   13910          878 :                 tree notnull_label = create_artificial_label (UNKNOWN_LOCATION);
   13911          878 :                 tree opt_arg_label = create_artificial_label (UNKNOWN_LOCATION);
   13912          878 :                 tree new_x = unshare_expr (x);
   13913          878 :                 gimplify_expr (&present, &ilist, NULL, is_gimple_val,
   13914              :                                fb_rvalue);
   13915          878 :                 gcond *cond = gimple_build_cond_from_tree (present,
   13916              :                                                            notnull_label,
   13917              :                                                            null_label);
   13918          878 :                 gimple_seq_add_stmt (&ilist, cond);
   13919          878 :                 gimple_seq_add_stmt (&ilist, gimple_build_label (null_label));
   13920          878 :                 gimplify_assign (new_x, null_pointer_node, &ilist);
   13921          878 :                 gimple_seq_add_stmt (&ilist, gimple_build_goto (opt_arg_label));
   13922          878 :                 gimple_seq_add_stmt (&ilist,
   13923          878 :                                      gimple_build_label (notnull_label));
   13924          878 :                 gimplify_assign (x, var, &ilist);
   13925          878 :                 gimple_seq_add_stmt (&ilist,
   13926          878 :                                      gimple_build_label (opt_arg_label));
   13927              :               }
   13928              :             else
   13929         1533 :               gimplify_assign (x, var, &ilist);
   13930         2411 :             s = size_int (0);
   13931         2411 :             purpose = size_int (map_idx++);
   13932         2411 :             CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
   13933         2411 :             gcc_checking_assert (tkind
   13934              :                                  < (HOST_WIDE_INT_C (1U) << talign_shift));
   13935         2411 :             gcc_checking_assert (tkind
   13936              :                                  <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
   13937         2411 :             CONSTRUCTOR_APPEND_ELT (vkind, purpose,
   13938              :                                     build_int_cstu (tkind_type, tkind));
   13939         2411 :             break;
   13940              :           }
   13941              : 
   13942        32117 :       gcc_assert (map_idx == map_cnt);
   13943              : 
   13944        32117 :       if (!deep_map_cnt)
   13945              :         {
   13946        31973 :           DECL_INITIAL (TREE_VEC_ELT (t, 1))
   13947        31973 :             = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 1)), vsize);
   13948        31973 :           DECL_INITIAL (TREE_VEC_ELT (t, 2))
   13949        63946 :             = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 2)), vkind);
   13950              :         }
   13951        96351 :       for (int i = 1; i <= 2; i++)
   13952        64234 :         if (deep_map_cnt || !TREE_STATIC (TREE_VEC_ELT (t, i)))
   13953              :           {
   13954         9643 :             tree tmp = TREE_VEC_ELT (t, i);
   13955         9643 :             if (deep_map_cnt)
   13956              :               {
   13957          288 :                 const char *prefix = (i == 1 ? ".omp_data_sizes0"
   13958              :                                              : ".omp_data_kinds0");
   13959          144 :                 tree type = (i == 1) ? size_type_node : tkind_type;
   13960          288 :                 type = build_array_type_nelts (type, map_cnt);
   13961          288 :                 tree var = create_tmp_var (type, prefix);
   13962          288 :                 DECL_NAMELESS (var) = 1;
   13963          288 :                 TREE_ADDRESSABLE (var) = 1;
   13964          288 :                 TREE_STATIC (var) = TREE_STATIC (tmp);
   13965          288 :                 DECL_INITIAL (var) = build_constructor (type, i == 1
   13966              :                                                               ? vsize : vkind);
   13967          288 :                 tmp = var;
   13968          288 :                 TREE_STATIC (TREE_VEC_ELT (t, i)) = 0;
   13969              :               }
   13970              : 
   13971         9643 :             gimple_seq initlist = NULL;
   13972         9643 :             force_gimple_operand (build1 (DECL_EXPR, void_type_node, tmp),
   13973              :                                   &initlist, true, NULL_TREE);
   13974         9643 :             gimple_seq_add_seq (&ilist, initlist);
   13975              : 
   13976         9643 :             if (deep_map_cnt)
   13977              :               {
   13978          288 :                 tree tmp2;
   13979          288 :                 tree call = builtin_decl_explicit (BUILT_IN_MEMCPY);
   13980          288 :                 tmp2 = TYPE_SIZE_UNIT (TREE_TYPE (tmp));
   13981          576 :                 call = build_call_expr_loc (input_location, call, 3,
   13982          288 :                                             TREE_VEC_ELT (t, i),
   13983              :                                             build_fold_addr_expr (tmp), tmp2);
   13984          288 :                 gimplify_and_add (call, &ilist);
   13985              :               }
   13986              : 
   13987         9643 :             if (!TREE_STATIC (tmp))
   13988              :               {
   13989         9425 :                 tree clobber = build_clobber (TREE_TYPE (tmp));
   13990         9425 :                 gimple_seq_add_stmt (&olist,
   13991         9425 :                                      gimple_build_assign (tmp, clobber));
   13992              :               }
   13993         9643 :             if (deep_map_cnt)
   13994              :               {
   13995          288 :                 tmp = TREE_VEC_ELT (t, i);
   13996          288 :                 tree call = builtin_decl_explicit (BUILT_IN_FREE);
   13997          288 :                 call = build_call_expr_loc (input_location, call, 1, tmp);
   13998          288 :                 gimplify_and_add (call, &olist);
   13999          288 :                 tree clobber = build_clobber (TREE_TYPE (tmp));
   14000          288 :                 gimple_seq_add_stmt (&olist,
   14001          288 :                                      gimple_build_assign (tmp, clobber));
   14002              :               }
   14003              :           }
   14004        54591 :         else if (omp_maybe_offloaded_ctx (ctx->outer))
   14005              :           {
   14006         3296 :             tree id = get_identifier ("omp declare target");
   14007         3296 :             tree decl = TREE_VEC_ELT (t, i);
   14008         3296 :             DECL_ATTRIBUTES (decl)
   14009         3296 :               = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
   14010         3296 :             varpool_node *node = varpool_node::get (decl);
   14011         3296 :             if (node)
   14012              :               {
   14013            0 :                 node->offloadable = 1;
   14014            0 :                 if (ENABLE_OFFLOADING)
   14015              :                   {
   14016              :                     g->have_offload = true;
   14017              :                     vec_safe_push (offload_vars, t);
   14018              :                   }
   14019              :               }
   14020              :           }
   14021              : 
   14022        32117 :       if (deep_map_cnt)
   14023              :         {
   14024          144 :           tree call = builtin_decl_explicit (BUILT_IN_FREE);
   14025          144 :           call = build_call_expr_loc (input_location, call, 1,
   14026          144 :                                       TREE_VEC_ELT (t, 0));
   14027          144 :           gimplify_and_add (call, &olist);
   14028              : 
   14029          144 :           gimplify_expr (&TREE_VEC_ELT (t, 1), &ilist, NULL, is_gimple_val,
   14030              :                          fb_rvalue);
   14031              :         }
   14032              : 
   14033        32117 :       tree clobber = build_clobber (TREE_TYPE (ctx->sender_decl));
   14034        32117 :       gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
   14035              :                                                         clobber));
   14036              :     }
   14037              : 
   14038              :   /* Once all the expansions are done, sequence all the different
   14039              :      fragments inside gimple_omp_body.  */
   14040              : 
   14041        36984 :   new_body = NULL;
   14042              : 
   14043        36984 :   if (offloaded
   14044        21048 :       && ctx->record_type)
   14045              :     {
   14046        16418 :       t = ctx->sender_decl;
   14047        16418 :       if (!deep_map_cnt)
   14048        16311 :         t = build_fold_addr_expr_loc (loc, t);
   14049              :       /* fixup_child_record_type might have changed receiver_decl's type.  */
   14050        16418 :       t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
   14051        16418 :       if (!AGGREGATE_TYPE_P (TREE_TYPE (ctx->sender_decl)))
   14052          107 :         gimplify_assign (ctx->receiver_decl, t, &new_body);
   14053              :       else
   14054        16311 :         gimple_seq_add_stmt (&new_body,
   14055        16311 :                              gimple_build_assign (ctx->receiver_decl, t));
   14056              :     }
   14057        36984 :   gimple_seq_add_seq (&new_body, fplist);
   14058              : 
   14059        36984 :   if (offloaded || data_region)
   14060              :     {
   14061       140186 :       tree prev = NULL_TREE;
   14062              :       bool by_ref;
   14063       140186 :       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
   14064       115118 :         switch (OMP_CLAUSE_CODE (c))
   14065              :           {
   14066              :             tree var, x, new_var, *allocate_ptr;
   14067              :           default:
   14068              :             break;
   14069        15163 :           case OMP_CLAUSE_FIRSTPRIVATE:
   14070        15163 :           omp_firstprivatize_data_region:
   14071        15163 :             if (is_gimple_omp_oacc (ctx->stmt))
   14072              :               break;
   14073        11267 :             var = OMP_CLAUSE_DECL (c);
   14074        11267 :             new_var = lookup_decl (var, ctx);
   14075        11267 :             allocate_ptr = alloc_map.get (new_var);
   14076        11267 :             by_ref = omp_privatize_by_reference (var);
   14077        11267 :             if (allocate_ptr)
   14078              :               {
   14079           63 :                 if (is_variable_sized (var, by_ref))
   14080              :                   /* Handle this in the next pass when the size is
   14081              :                      available.  */
   14082              :                   break;
   14083              : 
   14084           48 :                 gimple_seq *allocate_seq = alloc_seq_map.get (new_var);
   14085           48 :                 gcc_assert (allocate_seq);
   14086           48 :                 gimple_seq_add_seq (&new_body, *allocate_seq);
   14087              : 
   14088           48 :                 if (by_ref)
   14089              :                   {
   14090            4 :                     x = fold_convert (TREE_TYPE (new_var), *allocate_ptr);
   14091            4 :                     gimplify_assign (new_var, x, &new_body);
   14092            4 :                     new_var = build_fold_indirect_ref (new_var);
   14093              :                   }
   14094              :                 else
   14095           44 :                   new_var = build_simple_mem_ref (*allocate_ptr);
   14096              :               }
   14097        11252 :             if (by_ref || is_gimple_reg_type (TREE_TYPE (var)))
   14098              :               {
   14099        11129 :                 tree type;
   14100        11129 :                 type = TREE_TYPE (var);
   14101        11129 :                 if (by_ref)
   14102          796 :                   type = TREE_TYPE (type);
   14103        11129 :                 if ((INTEGRAL_TYPE_P (type)
   14104        10895 :                      && TYPE_PRECISION (type) <= POINTER_SIZE)
   14105        11139 :                     || TREE_CODE (type) == POINTER_TYPE)
   14106              :                   {
   14107        11040 :                     x = build_receiver_ref (var, false, ctx);
   14108        11040 :                     if (TREE_CODE (type) != POINTER_TYPE)
   14109        10885 :                       x = fold_convert (pointer_sized_int_node, x);
   14110        11040 :                     x = fold_convert (type, x);
   14111        11040 :                     gimplify_expr (&x, &new_body, NULL, is_gimple_val,
   14112              :                                    fb_rvalue);
   14113        11040 :                     if (by_ref && !allocate_ptr)
   14114              :                       {
   14115          765 :                         tree v = create_tmp_var_raw (type, get_name (var));
   14116          765 :                         gimple_add_tmp_var (v);
   14117          765 :                         TREE_ADDRESSABLE (v) = 1;
   14118          765 :                         gimple_seq_add_stmt (&new_body,
   14119          765 :                                              gimple_build_assign (v, x));
   14120          765 :                         x = build_fold_addr_expr (v);
   14121              :                       }
   14122        11040 :                     gimplify_assign (new_var, x, &new_body);
   14123              :                   }
   14124              :                 else
   14125              :                   {
   14126           89 :                     x = build_receiver_ref (var, allocate_ptr || !by_ref, ctx);
   14127           89 :                     gimplify_expr (&x, &new_body, NULL, is_gimple_val,
   14128              :                                    fb_rvalue);
   14129           89 :                     gimplify_assign (new_var, x, &new_body);
   14130              :                   }
   14131              :               }
   14132          123 :             else if (is_variable_sized (var))
   14133              :               {
   14134            4 :                 tree pvar = DECL_VALUE_EXPR (var);
   14135            4 :                 gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
   14136            4 :                 pvar = TREE_OPERAND (pvar, 0);
   14137            4 :                 gcc_assert (DECL_P (pvar));
   14138            4 :                 tree new_var = lookup_decl (pvar, ctx);
   14139            4 :                 x = build_receiver_ref (var, false, ctx);
   14140            4 :                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
   14141            4 :                 gimple_seq_add_stmt (&new_body,
   14142            4 :                                      gimple_build_assign (new_var, x));
   14143              :               }
   14144          119 :             else if (allocate_ptr)
   14145              :               {
   14146           19 :                 x = build_receiver_ref (var, true, ctx);
   14147           19 :                 new_var = unshare_expr (new_var);
   14148           19 :                 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
   14149           19 :                 gimplify_and_add (x, &new_body);
   14150              :               }
   14151              :             break;
   14152          226 :           case OMP_CLAUSE_PRIVATE:
   14153          226 :             if (is_gimple_omp_oacc (ctx->stmt))
   14154              :               break;
   14155          146 :             var = OMP_CLAUSE_DECL (c);
   14156          146 :             new_var = lookup_decl (var, ctx);
   14157          146 :             allocate_ptr = alloc_map.get (new_var);
   14158          146 :             by_ref = omp_privatize_by_reference (var);
   14159          146 :             if (allocate_ptr)
   14160              :               {
   14161           55 :                 if (is_variable_sized (var, by_ref))
   14162              :                   /* Handle this in the next pass when the size is
   14163              :                      available.  */
   14164              :                   break;
   14165              : 
   14166           43 :                 gimple_seq *allocate_seq = alloc_seq_map.get (new_var);
   14167           43 :                 gcc_assert (allocate_seq);
   14168           43 :                 gimple_seq_add_seq (&new_body, *allocate_seq);
   14169              : 
   14170           43 :                 if (!by_ref)
   14171           42 :                   new_var = build_simple_mem_ref (*allocate_ptr);
   14172              :               }
   14173          133 :             if (by_ref)
   14174              :               {
   14175           12 :                 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   14176           12 :                 if (!allocate_ptr)
   14177              :                   {
   14178           11 :                     x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
   14179           11 :                     if (TREE_CONSTANT (x))
   14180              :                       {
   14181            3 :                         x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
   14182              :                                                 get_name (var));
   14183            3 :                         gimple_add_tmp_var (x);
   14184            3 :                         TREE_ADDRESSABLE (x) = 1;
   14185            3 :                         x = build_fold_addr_expr_loc (clause_loc, x);
   14186              :                       }
   14187              :                     else
   14188              :                       break;
   14189              : 
   14190            3 :                     x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
   14191            3 :                     gimplify_expr (&x, &new_body, NULL, is_gimple_val,
   14192              :                                    fb_rvalue);
   14193              :                   }
   14194              :                 else
   14195            1 :                   x = *allocate_ptr;
   14196              : 
   14197            4 :                 gimple_seq_add_stmt (&new_body,
   14198            4 :                                      gimple_build_assign (new_var, x));
   14199              :               }
   14200              :             break;
   14201         2430 :           case OMP_CLAUSE_USE_DEVICE_PTR:
   14202         2430 :           case OMP_CLAUSE_USE_DEVICE_ADDR:
   14203         2430 :           case OMP_CLAUSE_HAS_DEVICE_ADDR:
   14204         2430 :           case OMP_CLAUSE_IS_DEVICE_PTR:
   14205         2430 :             gimple_seq assign_body;
   14206         2430 :             bool is_array_data;
   14207         2430 :             bool do_optional_check;
   14208         2430 :             assign_body = NULL;
   14209         2430 :             do_optional_check = false;
   14210         2430 :             var = OMP_CLAUSE_DECL (c);
   14211         2430 :             is_array_data = lang_hooks.decls.omp_array_data (var, true) != NULL;
   14212         2430 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR && is_array_data)
   14213           19 :               goto omp_firstprivatize_data_region;
   14214              : 
   14215         2411 :             if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IS_DEVICE_PTR
   14216         2411 :                 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR)
   14217         4108 :               x = build_sender_ref (is_array_data
   14218          601 :                                     ? (splay_tree_key) &DECL_NAME (var)
   14219         1453 :                                     : (splay_tree_key) &DECL_UID (var), ctx);
   14220              :             else
   14221              :               {
   14222          357 :                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
   14223              :                   {
   14224          233 :                     while (TREE_CODE (var) == INDIRECT_REF
   14225          233 :                            || TREE_CODE (var) == ARRAY_REF)
   14226           17 :                       var = TREE_OPERAND (var, 0);
   14227              :                   }
   14228          357 :                 x = build_receiver_ref (var, false, ctx);
   14229              :               }
   14230              : 
   14231         2411 :             if (is_array_data)
   14232              :               {
   14233          601 :                 bool is_ref = omp_privatize_by_reference (var);
   14234          601 :                 do_optional_check = true;
   14235              :                 /* First, we copy the descriptor data from the host; then
   14236              :                    we update its data to point to the target address.  */
   14237          601 :                 new_var = lookup_decl (var, ctx);
   14238          601 :                 new_var = DECL_VALUE_EXPR (new_var);
   14239          601 :                 tree v = new_var;
   14240          601 :                 tree v2 = var;
   14241          601 :                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
   14242          601 :                     || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR)
   14243          601 :                   v2 = maybe_lookup_decl_in_outer_ctx (var, ctx);
   14244              : 
   14245          601 :                 if (is_ref)
   14246              :                   {
   14247          396 :                     v2 = build_fold_indirect_ref (v2);
   14248          396 :                     v = create_tmp_var_raw (TREE_TYPE (v2), get_name (var));
   14249          396 :                     gimple_add_tmp_var (v);
   14250          396 :                     TREE_ADDRESSABLE (v) = 1;
   14251          396 :                     gimplify_assign (v, v2, &assign_body);
   14252          396 :                     tree rhs = build_fold_addr_expr (v);
   14253          396 :                     gimple_seq_add_stmt (&assign_body,
   14254          396 :                                          gimple_build_assign (new_var, rhs));
   14255              :                   }
   14256              :                 else
   14257          205 :                   gimplify_assign (new_var, v2, &assign_body);
   14258              : 
   14259          601 :                 v2 = lang_hooks.decls.omp_array_data (unshare_expr (v), false);
   14260          601 :                 gcc_assert (v2);
   14261          601 :                 gimplify_expr (&x, &assign_body, NULL, is_gimple_val, fb_rvalue);
   14262         1202 :                 gimple_seq_add_stmt (&assign_body,
   14263          601 :                                      gimple_build_assign (v2, x));
   14264              :               }
   14265         1810 :             else if (is_variable_sized (var))
   14266              :               {
   14267           12 :                 tree pvar = DECL_VALUE_EXPR (var);
   14268           12 :                 gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
   14269           12 :                 pvar = TREE_OPERAND (pvar, 0);
   14270           12 :                 gcc_assert (DECL_P (pvar));
   14271           12 :                 new_var = lookup_decl (pvar, ctx);
   14272           12 :                 gimplify_expr (&x, &assign_body, NULL, is_gimple_val, fb_rvalue);
   14273           24 :                 gimple_seq_add_stmt (&assign_body,
   14274           12 :                                      gimple_build_assign (new_var, x));
   14275              :               }
   14276         1798 :             else if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
   14277          536 :                       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
   14278         1476 :                       && !omp_privatize_by_reference (var)
   14279          504 :                       && !omp_is_allocatable_or_ptr (var))
   14280         3231 :                      || TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
   14281              :               {
   14282          389 :                 new_var = lookup_decl (var, ctx);
   14283          389 :                 new_var = DECL_VALUE_EXPR (new_var);
   14284          389 :                 gcc_assert (TREE_CODE (new_var) == MEM_REF);
   14285          389 :                 new_var = TREE_OPERAND (new_var, 0);
   14286          389 :                 gcc_assert (DECL_P (new_var));
   14287          389 :                 gimplify_expr (&x, &assign_body, NULL, is_gimple_val, fb_rvalue);
   14288          778 :                 gimple_seq_add_stmt (&assign_body,
   14289          389 :                                      gimple_build_assign (new_var, x));
   14290              :               }
   14291              :             else
   14292              :               {
   14293         1409 :                 tree type = TREE_TYPE (var);
   14294         1409 :                 new_var = lookup_decl (var, ctx);
   14295         1409 :                 if (omp_privatize_by_reference (var))
   14296              :                   {
   14297         1039 :                     type = TREE_TYPE (type);
   14298         1039 :                     if (POINTER_TYPE_P (type)
   14299         1039 :                         && TREE_CODE (type) != ARRAY_TYPE
   14300         1398 :                         && ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_USE_DEVICE_ADDR
   14301           36 :                             && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR)
   14302          331 :                             || (omp_privatize_by_reference (var)
   14303          331 :                                 && omp_is_allocatable_or_ptr (var))))
   14304              :                       {
   14305          357 :                         tree v = create_tmp_var_raw (type, get_name (var));
   14306          357 :                         gimple_add_tmp_var (v);
   14307          357 :                         TREE_ADDRESSABLE (v) = 1;
   14308          357 :                         x = fold_convert (type, x);
   14309          357 :                         gimplify_expr (&x, &assign_body, NULL, is_gimple_val,
   14310              :                                        fb_rvalue);
   14311          357 :                         gimple_seq_add_stmt (&assign_body,
   14312          357 :                                              gimple_build_assign (v, x));
   14313          357 :                         x = build_fold_addr_expr (v);
   14314          357 :                         do_optional_check = true;
   14315              :                       }
   14316              :                   }
   14317         1409 :                 new_var = DECL_VALUE_EXPR (new_var);
   14318         1409 :                 x = fold_convert (TREE_TYPE (new_var), x);
   14319         1409 :                 gimplify_expr (&x, &assign_body, NULL, is_gimple_val, fb_rvalue);
   14320         1409 :                 gimple_seq_add_stmt (&assign_body,
   14321         1409 :                                      gimple_build_assign (new_var, x));
   14322              :               }
   14323         2411 :             tree present;
   14324         1002 :             present = ((do_optional_check
   14325          958 :                         && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR
   14326          952 :                         && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IS_DEVICE_PTR)
   14327         2342 :                        ? omp_check_optional_argument (OMP_CLAUSE_DECL (c), true)
   14328              :                        : NULL_TREE);
   14329         2411 :             if (present)
   14330              :               {
   14331          480 :                 tree null_label = create_artificial_label (UNKNOWN_LOCATION);
   14332          480 :                 tree notnull_label = create_artificial_label (UNKNOWN_LOCATION);
   14333          480 :                 tree opt_arg_label = create_artificial_label (UNKNOWN_LOCATION);
   14334          480 :                 glabel *null_glabel = gimple_build_label (null_label);
   14335          480 :                 glabel *notnull_glabel = gimple_build_label (notnull_label);
   14336          480 :                 ggoto *opt_arg_ggoto = gimple_build_goto (opt_arg_label);
   14337          480 :                 gimplify_expr (&x, &new_body, NULL, is_gimple_val,
   14338              :                                            fb_rvalue);
   14339          480 :                 gimplify_expr (&present, &new_body, NULL, is_gimple_val,
   14340              :                                fb_rvalue);
   14341          480 :                 gcond *cond = gimple_build_cond_from_tree (present,
   14342              :                                                            notnull_label,
   14343              :                                                            null_label);
   14344          480 :                 gimple_seq_add_stmt (&new_body, cond);
   14345          480 :                 gimple_seq_add_stmt (&new_body, null_glabel);
   14346          480 :                 gimplify_assign (new_var, null_pointer_node, &new_body);
   14347          480 :                 gimple_seq_add_stmt (&new_body, opt_arg_ggoto);
   14348          480 :                 gimple_seq_add_stmt (&new_body, notnull_glabel);
   14349          480 :                 gimple_seq_add_seq (&new_body, assign_body);
   14350          480 :                 gimple_seq_add_stmt (&new_body,
   14351          480 :                                      gimple_build_label (opt_arg_label));
   14352              :               }
   14353              :             else
   14354         1931 :               gimple_seq_add_seq (&new_body, assign_body);
   14355              :             break;
   14356              :           }
   14357              :       /* Handle GOMP_MAP_FIRSTPRIVATE_{POINTER,REFERENCE} in second pass,
   14358              :          so that firstprivate vars holding OMP_CLAUSE_SIZE if needed
   14359              :          are already handled.  Similarly OMP_CLAUSE_PRIVATE for VLAs
   14360              :          or references to VLAs.  */
   14361       140186 :       for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   14362       115118 :         switch (OMP_CLAUSE_CODE (c))
   14363              :           {
   14364              :             tree var, new_var, *allocate_ptr;
   14365              :           default:
   14366        99982 :             break;
   14367        63298 :           case OMP_CLAUSE_MAP:
   14368        63298 :             if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   14369        63298 :                 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   14370              :               {
   14371         3664 :                 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   14372         3664 :                 poly_int64 offset = 0;
   14373         3664 :                 gcc_assert (prev);
   14374         3664 :                 var = OMP_CLAUSE_DECL (c);
   14375         3664 :                 if (DECL_P (var)
   14376         3664 :                     && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
   14377         1125 :                     && is_global_var (maybe_lookup_decl_in_outer_ctx (var,
   14378              :                                                                       ctx))
   14379         3762 :                     && varpool_node::get_create (var)->offloadable)
   14380              :                   break;
   14381         3662 :                 if (TREE_CODE (var) == INDIRECT_REF
   14382         3662 :                     && TREE_CODE (TREE_OPERAND (var, 0)) == COMPONENT_REF)
   14383            0 :                   var = TREE_OPERAND (var, 0);
   14384         3662 :                 if (TREE_CODE (var) == COMPONENT_REF)
   14385              :                   {
   14386            0 :                     var = get_addr_base_and_unit_offset (var, &offset);
   14387            0 :                     gcc_assert (var != NULL_TREE && DECL_P (var));
   14388              :                   }
   14389         3662 :                 else if (DECL_SIZE (var)
   14390         3662 :                          && TREE_CODE (DECL_SIZE (var)) != INTEGER_CST)
   14391              :                   {
   14392          710 :                     tree var2 = DECL_VALUE_EXPR (var);
   14393          710 :                     gcc_assert (TREE_CODE (var2) == INDIRECT_REF);
   14394          710 :                     var2 = TREE_OPERAND (var2, 0);
   14395          710 :                     gcc_assert (DECL_P (var2));
   14396              :                     var = var2;
   14397              :                   }
   14398         3662 :                 tree new_var = lookup_decl (var, ctx), x;
   14399         3662 :                 tree type = TREE_TYPE (new_var);
   14400         3662 :                 bool is_ref;
   14401         3662 :                 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == INDIRECT_REF
   14402         3662 :                     && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
   14403              :                         == COMPONENT_REF))
   14404              :                   {
   14405            0 :                     type = TREE_TYPE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0));
   14406            0 :                     is_ref = true;
   14407            0 :                     new_var = build2 (MEM_REF, type,
   14408              :                                       build_fold_addr_expr (new_var),
   14409              :                                       build_int_cst (build_pointer_type (type),
   14410              :                                                      offset));
   14411              :                   }
   14412         3662 :                 else if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPONENT_REF)
   14413              :                   {
   14414            0 :                     type = TREE_TYPE (OMP_CLAUSE_DECL (c));
   14415            0 :                     is_ref = TREE_CODE (type) == REFERENCE_TYPE;
   14416            0 :                     new_var = build2 (MEM_REF, type,
   14417              :                                       build_fold_addr_expr (new_var),
   14418              :                                       build_int_cst (build_pointer_type (type),
   14419              :                                                      offset));
   14420              :                   }
   14421              :                 else
   14422         3662 :                   is_ref = omp_privatize_by_reference (var);
   14423         3662 :                 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   14424              :                   is_ref = false;
   14425         6695 :                 bool ref_to_array = false;
   14426         6695 :                 bool ref_to_ptr = false;
   14427         3233 :                 if (is_ref)
   14428              :                   {
   14429          200 :                     type = TREE_TYPE (type);
   14430          200 :                     if (TREE_CODE (type) == ARRAY_TYPE)
   14431              :                       {
   14432          194 :                         type = build_pointer_type (type);
   14433          194 :                         ref_to_array = true;
   14434              :                       }
   14435              :                   }
   14436         3462 :                 else if (TREE_CODE (type) == ARRAY_TYPE)
   14437              :                   {
   14438          413 :                     tree decl2 = DECL_VALUE_EXPR (new_var);
   14439          413 :                     gcc_assert (TREE_CODE (decl2) == MEM_REF);
   14440          413 :                     decl2 = TREE_OPERAND (decl2, 0);
   14441          413 :                     gcc_assert (DECL_P (decl2));
   14442          413 :                     new_var = decl2;
   14443          413 :                     type = TREE_TYPE (new_var);
   14444              :                   }
   14445         3049 :                 else if (TREE_CODE (type) == REFERENCE_TYPE
   14446         3049 :                          && TREE_CODE (TREE_TYPE (type)) == POINTER_TYPE)
   14447              :                   {
   14448          156 :                     type = TREE_TYPE (type);
   14449          156 :                     ref_to_ptr = true;
   14450              :                   }
   14451         3662 :                 x = build_receiver_ref (prev, false, ctx);
   14452         3662 :                 x = fold_convert_loc (clause_loc, type, x);
   14453         3662 :                 if (!integer_zerop (OMP_CLAUSE_SIZE (c)))
   14454              :                   {
   14455          762 :                     tree bias = OMP_CLAUSE_SIZE (c);
   14456          762 :                     if (DECL_P (bias))
   14457          364 :                       bias = lookup_decl (bias, ctx);
   14458          762 :                     bias = fold_convert_loc (clause_loc, sizetype, bias);
   14459          762 :                     bias = fold_build1_loc (clause_loc, NEGATE_EXPR, sizetype,
   14460              :                                             bias);
   14461          762 :                     x = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
   14462          762 :                                          TREE_TYPE (x), x, bias);
   14463              :                   }
   14464         3662 :                 if (ref_to_array)
   14465          194 :                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
   14466         3662 :                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
   14467         3662 :                 if ((is_ref && !ref_to_array)
   14468         3656 :                     || ref_to_ptr)
   14469              :                   {
   14470          162 :                     tree t = create_tmp_var_raw (type, get_name (var));
   14471          162 :                     gimple_add_tmp_var (t);
   14472          162 :                     TREE_ADDRESSABLE (t) = 1;
   14473          162 :                     gimple_seq_add_stmt (&new_body,
   14474          162 :                                          gimple_build_assign (t, x));
   14475          162 :                     x = build_fold_addr_expr_loc (clause_loc, t);
   14476              :                   }
   14477         3662 :                 gimple_seq_add_stmt (&new_body,
   14478         3662 :                                      gimple_build_assign (new_var, x));
   14479         3662 :                 prev = NULL_TREE;
   14480              :               }
   14481        59634 :             else if (OMP_CLAUSE_CHAIN (c)
   14482        43083 :                      && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c))
   14483              :                         == OMP_CLAUSE_MAP
   14484        97337 :                      && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
   14485              :                          == GOMP_MAP_FIRSTPRIVATE_POINTER
   14486        34468 :                          || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
   14487              :                              == GOMP_MAP_FIRSTPRIVATE_REFERENCE)))
   14488              :               prev = c;
   14489              :             break;
   14490          226 :           case OMP_CLAUSE_PRIVATE:
   14491          226 :             var = OMP_CLAUSE_DECL (c);
   14492          226 :             by_ref = omp_privatize_by_reference (var);
   14493          226 :             new_var = lookup_decl (var, ctx);
   14494          226 :             allocate_ptr = alloc_map.get (new_var);
   14495          226 :             if (is_variable_sized (var, by_ref)
   14496          226 :                 || (!allocate_ptr && by_ref && !is_gimple_omp_oacc (ctx->stmt)))
   14497              :               {
   14498           24 :                 if (allocate_ptr)
   14499              :                   {
   14500           12 :                     gimple_seq *allocate_seq = alloc_seq_map.get (new_var);
   14501           12 :                     gcc_assert (allocate_seq);
   14502           12 :                     gimple_seq_add_seq (&new_body, *allocate_seq);
   14503              :                   }
   14504           24 :                 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   14505           24 :                 tree pvar = var;
   14506           24 :                 if (!by_ref)
   14507              :                   {
   14508            3 :                     pvar = DECL_VALUE_EXPR (var);
   14509            3 :                     gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
   14510            3 :                     pvar = TREE_OPERAND (pvar, 0);
   14511              :                   }
   14512           24 :                 gcc_assert (DECL_P (pvar));
   14513           24 :                 tree new_pvar = lookup_decl (pvar, ctx);
   14514           24 :                 tree x;
   14515           24 :                 if (!allocate_ptr)
   14516              :                   {
   14517           12 :                     tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
   14518           12 :                     tree ty = TREE_TYPE (new_var);
   14519           12 :                     if (by_ref)
   14520           11 :                       ty = TREE_TYPE (ty);
   14521           12 :                     x = TYPE_SIZE_UNIT (ty);
   14522           12 :                     if (TREE_CONSTANT (x))
   14523              :                       break;
   14524            9 :                     tree al = size_int (TYPE_ALIGN (ty));
   14525            9 :                     x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
   14526            9 :                     x = fold_convert_loc (clause_loc, TREE_TYPE (new_pvar), x);
   14527              :                   }
   14528              :                 else
   14529           12 :                   x = *allocate_ptr;
   14530           21 :                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
   14531           21 :                 gimple_seq_add_stmt (&new_body,
   14532           21 :                                      gimple_build_assign (new_pvar, x));
   14533              :               }
   14534              :             break;
   14535        15144 :           case OMP_CLAUSE_FIRSTPRIVATE:
   14536        15144 :             var = OMP_CLAUSE_DECL (c);
   14537        15144 :             by_ref = omp_privatize_by_reference (var);
   14538        15144 :             if (is_variable_sized (var, by_ref))
   14539              :               {
   14540           23 :                 tree new_var = lookup_decl (var, ctx);
   14541           23 :                 tree *allocate_ptr = alloc_map.get (new_var);
   14542           23 :                 if (!allocate_ptr)
   14543              :                   break;
   14544           15 :                 gimple_seq *allocate_seq = alloc_seq_map.get (new_var);
   14545           15 :                 gcc_assert (allocate_seq);
   14546           15 :                 gimple_seq_add_seq (&new_body, *allocate_seq);
   14547              : 
   14548           15 :                 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   14549           15 :                 tree pvar = var;
   14550           15 :                 if (!by_ref)
   14551              :                   {
   14552            2 :                     pvar = DECL_VALUE_EXPR (var);
   14553            2 :                     gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
   14554            2 :                     pvar = TREE_OPERAND (pvar, 0);
   14555              :                   }
   14556           15 :                 gcc_assert (DECL_P (pvar));
   14557           15 :                 tree new_pvar = lookup_decl (pvar, ctx);
   14558           15 :                 tree x = fold_convert_loc (clause_loc, TREE_TYPE (new_pvar),
   14559           15 :                                            *allocate_ptr);
   14560           15 :                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
   14561           15 :                 gimple_seq_add_stmt (&new_body,
   14562           15 :                                      gimple_build_assign (new_pvar, x));
   14563              : 
   14564           15 :                 x = build_receiver_ref (var, true, ctx);
   14565           15 :                 new_var = unshare_expr (new_var);
   14566           15 :                 if (by_ref)
   14567           13 :                   new_var = build_fold_indirect_ref (new_var);
   14568           15 :                 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
   14569           15 :                 gimplify_and_add (x, &new_body);
   14570              :               }
   14571              :           }
   14572              : 
   14573        25068 :       gimple_seq fork_seq = NULL;
   14574        25068 :       gimple_seq join_seq = NULL;
   14575              : 
   14576        25068 :       if (offloaded && is_gimple_omp_oacc (ctx->stmt))
   14577              :         {
   14578              :           /* If there are reductions on the offloaded region itself, treat
   14579              :              them as a dummy GANG loop.  */
   14580         9395 :           tree level = build_int_cst (integer_type_node, GOMP_DIM_GANG);
   14581              : 
   14582         9395 :           gcall *private_marker = lower_oacc_private_marker (ctx);
   14583              : 
   14584         9395 :           if (private_marker)
   14585           30 :             gimple_call_set_arg (private_marker, 2, level);
   14586              : 
   14587         9395 :           lower_oacc_reductions (gimple_location (ctx->stmt), clauses, level,
   14588              :                                  false, NULL, private_marker, NULL, &fork_seq,
   14589              :                                  &join_seq, ctx);
   14590              :         }
   14591              : 
   14592        25068 :       gimple_seq_add_seq (&new_body, fork_seq);
   14593        25068 :       gimple_seq_add_seq (&new_body, tgt_body);
   14594        25068 :       gimple_seq_add_seq (&new_body, join_seq);
   14595        25068 :       gimple_seq_add_seq (&new_body, alloc_dlist);
   14596              : 
   14597        25068 :       if (offloaded)
   14598              :         {
   14599        21048 :           new_body = maybe_catch_exception (new_body);
   14600        21048 :           gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
   14601              :         }
   14602        25068 :       gimple_omp_set_body (stmt, new_body);
   14603              :     }
   14604              : 
   14605        36984 :   gsi_insert_seq_before (gsi_p, gimple_omp_target_iterator_loops (stmt),
   14606              :                          GSI_SAME_STMT);
   14607        36984 :   gimple_omp_target_set_iterator_loops (stmt, NULL);
   14608        58032 :   bind = gimple_build_bind (NULL, NULL,
   14609        21048 :                             tgt_bind ? gimple_bind_block (tgt_bind)
   14610              :                                      : NULL_TREE);
   14611        73576 :   gsi_replace (gsi_p, dep_bind ? dep_bind : bind, true);
   14612        36984 :   gimple_bind_add_seq (bind, ilist);
   14613        36984 :   gimple_bind_add_stmt (bind, stmt);
   14614        36984 :   gimple_bind_add_seq (bind, olist);
   14615              : 
   14616        36984 :   pop_gimplify_context (NULL);
   14617              : 
   14618        36984 :   if (dep_bind)
   14619              :     {
   14620          392 :       gimple_bind_add_seq (dep_bind, dep_ilist);
   14621          392 :       gimple_bind_add_stmt (dep_bind, bind);
   14622          392 :       gimple_bind_add_seq (dep_bind, dep_olist);
   14623          392 :       pop_gimplify_context (dep_bind);
   14624              :     }
   14625        36984 : }
   14626              : 
   14627              : /* Generate code to implement the action-clauses (destroy, init, use) of an
   14628              :    OpenMP interop construct.  */
   14629              : 
   14630              : static void
   14631          492 : lower_omp_interop_action_clauses (gimple_seq *seq, vec<tree> &objs,
   14632              :                                   vec<tree> *interop_types = NULL,
   14633              :                                   vec<tree> *prefer_types = NULL)
   14634              : {
   14635          492 :   if (objs.length () == 0)
   14636          229 :     return;
   14637              : 
   14638          263 :   enum omp_clause_code action = OMP_CLAUSE_CODE (objs[0]);
   14639          263 :   if (action == OMP_CLAUSE_INIT)
   14640          402 :     gcc_checking_assert (objs.length () == interop_types->length ()
   14641              :                          && objs.length () == prefer_types->length ());
   14642              :   else
   14643          129 :     gcc_assert (prefer_types == NULL && interop_types == NULL);
   14644              : 
   14645          263 :   tree ret_objs = NULL_TREE, ret_interop_types = NULL_TREE,
   14646          263 :        ret_prefer_types = NULL_TREE;
   14647              : 
   14648              :   /* Build an array of interop objects. */
   14649              : 
   14650          263 :   tree type_obj_pref = build_array_type_nelts (ptr_type_node, objs.length ());
   14651          263 :   ret_objs = create_tmp_var (type_obj_pref, "interopobjs");
   14652              : 
   14653          263 :   bool have_pref_type = false;
   14654          263 :   if (action == OMP_CLAUSE_INIT)
   14655              :     {
   14656          592 :       for (tree pref_type : prefer_types)
   14657          260 :         if (pref_type != NULL_TREE)
   14658              :           {
   14659              :             have_pref_type = true;
   14660              :             break;
   14661              :           }
   14662          134 :       tree type_tgtsync
   14663          134 :         = build_array_type_nelts (integer_type_node, objs.length ());
   14664          134 :       ret_interop_types = create_tmp_var (type_tgtsync, "tgt_tgtsync");
   14665          134 :       if (have_pref_type)
   14666           70 :         ret_prefer_types = create_tmp_var (type_obj_pref, "pref_type");
   14667              :       else
   14668              :         {
   14669           64 :           ret_prefer_types = null_pointer_node;
   14670           64 :           prefer_types->truncate (0);
   14671              :         }
   14672              :     }
   14673              : 
   14674          856 :   for (size_t i = 0; !objs.is_empty (); i++)
   14675              :     {
   14676          593 :       tree offset = build_int_cst (integer_type_node, i);
   14677          593 :       tree init = build4 (ARRAY_REF, ptr_type_node, ret_objs, offset, NULL_TREE,
   14678              :                           NULL_TREE);
   14679          593 :       tree obj = OMP_CLAUSE_DECL (objs.pop ());
   14680          593 :       if (TREE_CODE (TREE_TYPE (obj)) == REFERENCE_TYPE)
   14681            6 :         obj = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (obj)), obj);
   14682          593 :       if (action != OMP_CLAUSE_USE
   14683          593 :           && TREE_CODE (TREE_TYPE (obj)) != POINTER_TYPE)
   14684              :         /* For modifying actions, we need a pointer. */
   14685          483 :         obj = build_fold_addr_expr (obj);
   14686          110 :       else if (action == OMP_CLAUSE_USE
   14687          110 :                && TREE_CODE (TREE_TYPE (obj)) == POINTER_TYPE)
   14688              :         /* For use action, we need the value. */
   14689            2 :         obj = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (obj)), obj);
   14690          593 :       init = build2 (MODIFY_EXPR, ptr_type_node, init,
   14691              :                      fold_convert (ptr_type_node, obj));
   14692          593 :       gimplify_and_add (init, seq);
   14693              : 
   14694          593 :       if (action == OMP_CLAUSE_INIT)
   14695              :         {
   14696          384 :           init = build4 (ARRAY_REF, integer_type_node, ret_interop_types,
   14697              :                          offset, NULL_TREE, NULL_TREE);
   14698          384 :           init = build2 (MODIFY_EXPR, integer_type_node, init,
   14699          384 :                          interop_types->pop ());
   14700          384 :           gimplify_and_add (init, seq);
   14701              : 
   14702          384 :           if (have_pref_type)
   14703              :             {
   14704          194 :               tree prefer_type = prefer_types->pop ();
   14705          194 :               tree pref = (prefer_type == NULL_TREE
   14706          194 :                              ? null_pointer_node
   14707          194 :                              : build_fold_addr_expr (prefer_type));
   14708          194 :               init = build4 (ARRAY_REF, ptr_type_node, ret_prefer_types, offset,
   14709              :                              NULL_TREE, NULL_TREE);
   14710          194 :               init = build2 (MODIFY_EXPR, ptr_type_node, init, pref);
   14711          194 :               gimplify_and_add (init, seq);
   14712              :             }
   14713              :         }
   14714              :     }
   14715          263 :   if (action == OMP_CLAUSE_INIT)
   14716              :     {
   14717          134 :       if (have_pref_type)
   14718           70 :         ret_prefer_types = build_fold_addr_expr (ret_prefer_types);
   14719          134 :       ret_interop_types = build_fold_addr_expr (ret_interop_types);
   14720              :     }
   14721          263 :   ret_objs = build_fold_addr_expr (ret_objs);
   14722              : 
   14723          660 :   gcc_assert (objs.is_empty ()
   14724              :               && (!interop_types || interop_types->is_empty ())
   14725              :               && (!prefer_types || prefer_types->is_empty ()));
   14726              : 
   14727          263 :   objs.safe_push (ret_objs);
   14728          263 :   if (action == OMP_CLAUSE_INIT)
   14729              :     {
   14730          134 :       interop_types->safe_push (ret_interop_types);
   14731          134 :       prefer_types->safe_push (ret_prefer_types);
   14732              :     }
   14733              : }
   14734              : 
   14735              : /* Lower code for an OpenMP interop directive.  */
   14736              : 
   14737              : static void
   14738          164 : lower_omp_interop (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   14739              : {
   14740          164 :   push_gimplify_context ();
   14741              : 
   14742          164 :   tree block = make_node (BLOCK);
   14743          164 :   gbind *bind = gimple_build_bind (NULL, NULL, block);
   14744          164 :   gimple_seq bind_body = NULL;
   14745              : 
   14746              :   /* Emit call to GOMP_interop:
   14747              :       void
   14748              :       GOMP_interop (int device_num, int n_init, omp_interop_t **init,
   14749              :                     const void *target_targetsync, const void *prefer_type,
   14750              :                     int n_use, omp_interop_t *use, int n_destroy,
   14751              :                     omp_interop_t **destroy, unsigned int flags,
   14752              :                     void **depend)  */
   14753              : 
   14754          164 :   tree flags = NULL_TREE;
   14755          164 :   tree depend = null_pointer_node;
   14756          164 :   tree device_num = NULL_TREE;
   14757              : 
   14758          164 :   auto_vec<tree> init_objs, use_objs, destroy_objs, prefer_type,
   14759          164 :     target_targetsync;
   14760          164 :   gimple_seq dep_ilist = NULL, dep_olist = NULL;
   14761          164 :   tree clauses = gimple_omp_interop_clauses (gsi_stmt (*gsi_p));
   14762          868 :   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   14763              :     {
   14764          704 :       switch (OMP_CLAUSE_CODE (c))
   14765              :         {
   14766          384 :         case OMP_CLAUSE_INIT:
   14767          384 :           {
   14768          384 :             init_objs.safe_push (c);
   14769          384 :             int target_targetsync_bits = 0;
   14770          384 :             if (OMP_CLAUSE_INIT_TARGET (c))
   14771          229 :               target_targetsync_bits |= GOMP_INTEROP_TARGET;
   14772          384 :             if (OMP_CLAUSE_INIT_TARGETSYNC (c))
   14773          204 :               target_targetsync_bits |= GOMP_INTEROP_TARGETSYNC;
   14774          384 :             tree t = build_int_cst (integer_type_node, target_targetsync_bits);
   14775          384 :             target_targetsync.safe_push (t);
   14776          384 :             prefer_type.safe_push (OMP_CLAUSE_INIT_PREFER_TYPE (c));
   14777              :           }
   14778          384 :           break;
   14779          106 :         case OMP_CLAUSE_USE:
   14780          106 :           use_objs.safe_push (c);
   14781          106 :           break;
   14782          103 :         case OMP_CLAUSE_DESTROY:
   14783          103 :           destroy_objs.safe_push (c);
   14784          103 :           break;
   14785           50 :         case OMP_CLAUSE_NOWAIT:
   14786           50 :           flags = build_int_cst (integer_type_node, GOMP_INTEROP_FLAG_NOWAIT);
   14787           50 :           break;
   14788           35 :         case OMP_CLAUSE_DEPEND:
   14789           35 :           {
   14790           35 :             tree *cp = gimple_omp_interop_clauses_ptr (gsi_stmt (*gsi_p));
   14791           35 :             lower_depend_clauses (cp, &dep_ilist, &dep_olist);
   14792           35 :             depend = OMP_CLAUSE_DECL (*cp);
   14793              :           }
   14794           35 :           break;
   14795           26 :         case OMP_CLAUSE_DEVICE:
   14796           26 :           device_num = OMP_CLAUSE_DEVICE_ID (c);
   14797           26 :           break;
   14798            0 :         default:
   14799            0 :           gcc_unreachable ();
   14800              :         }
   14801              :     }
   14802              : 
   14803          164 :   if (flags == NULL_TREE)
   14804          114 :     flags = build_int_cst (integer_type_node, 0);
   14805              : 
   14806          164 :   if (device_num == NULL_TREE)
   14807          138 :     device_num = build_int_cst (integer_type_node, GOMP_DEVICE_DEFAULT_OMP_61);
   14808              : 
   14809          298 :   tree n_init = build_int_cst (integer_type_node, init_objs.length ());
   14810          234 :   tree n_use = build_int_cst (integer_type_node, use_objs.length ());
   14811          223 :   tree n_destroy = build_int_cst (integer_type_node, destroy_objs.length ());
   14812              : 
   14813          164 :   lower_omp_interop_action_clauses (&bind_body, init_objs, &target_targetsync,
   14814              :                                     &prefer_type);
   14815          164 :   lower_omp_interop_action_clauses (&bind_body, use_objs);
   14816          164 :   lower_omp_interop_action_clauses (&bind_body, destroy_objs);
   14817              : 
   14818          164 :   gimple_seq_add_seq (&bind_body, dep_ilist);
   14819          164 :   tree fn = builtin_decl_explicit (BUILT_IN_GOMP_INTEROP);
   14820          298 :   tree init_arg = init_objs.length () ? init_objs.pop () : null_pointer_node;
   14821          164 :   tree target_targetsync_arg = target_targetsync.length ()
   14822          134 :                                  ? target_targetsync.pop ()
   14823          164 :                                  : null_pointer_node;
   14824          164 :   tree prefer_type_arg
   14825          298 :     = prefer_type.length () ? prefer_type.pop () : null_pointer_node;
   14826          234 :   tree use_arg = use_objs.length () ? use_objs.pop () : null_pointer_node;
   14827          164 :   tree destroy_arg
   14828          223 :     = destroy_objs.length () ? destroy_objs.pop () : null_pointer_node;
   14829          164 :   gcall *call
   14830          164 :     = gimple_build_call (fn, 11, device_num, n_init, init_arg,
   14831              :                          target_targetsync_arg, prefer_type_arg, n_use, use_arg,
   14832              :                          n_destroy, destroy_arg, flags, depend);
   14833          164 :   gimple_seq_add_stmt (&bind_body, call);
   14834          164 :   gimple_seq_add_seq (&bind_body, dep_olist);
   14835              : 
   14836          164 :   gsi_replace (gsi_p, bind, true);
   14837          164 :   gimple_bind_set_body (bind, bind_body);
   14838          164 :   pop_gimplify_context (bind);
   14839          164 :   gimple_bind_append_vars (bind, ctx->block_vars);
   14840          164 :   BLOCK_VARS (block) = ctx->block_vars;
   14841          164 : }
   14842              : 
   14843              : /* Expand code for an OpenMP teams directive.  */
   14844              : 
   14845              : static void
   14846         5917 : lower_omp_teams (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   14847              : {
   14848         5917 :   gomp_teams *teams_stmt = as_a <gomp_teams *> (gsi_stmt (*gsi_p));
   14849         5917 :   push_gimplify_context ();
   14850              : 
   14851         5917 :   tree block = make_node (BLOCK);
   14852         5917 :   gbind *bind = gimple_build_bind (NULL, NULL, block);
   14853         5917 :   gsi_replace (gsi_p, bind, true);
   14854         5917 :   gimple_seq bind_body = NULL;
   14855         5917 :   gimple_seq dlist = NULL;
   14856         5917 :   gimple_seq olist = NULL;
   14857              : 
   14858         5917 :   tree num_teams = omp_find_clause (gimple_omp_teams_clauses (teams_stmt),
   14859         5917 :                                     OMP_CLAUSE_NUM_TEAMS);
   14860         5917 :   tree num_teams_lower = NULL_TREE;
   14861         5917 :   if (num_teams == NULL_TREE)
   14862         5300 :     num_teams = build_int_cst (unsigned_type_node, 0);
   14863              :   else
   14864              :     {
   14865          617 :       num_teams_lower = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (num_teams);
   14866          617 :       if (num_teams_lower)
   14867              :         {
   14868          148 :           num_teams_lower = fold_convert (unsigned_type_node, num_teams_lower);
   14869          148 :           gimplify_expr (&num_teams_lower, &bind_body, NULL, is_gimple_val,
   14870              :                          fb_rvalue);
   14871              :         }
   14872          617 :       num_teams = OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (num_teams);
   14873          617 :       num_teams = fold_convert (unsigned_type_node, num_teams);
   14874          617 :       gimplify_expr (&num_teams, &bind_body, NULL, is_gimple_val, fb_rvalue);
   14875              :     }
   14876         5917 :   if (num_teams_lower == NULL_TREE)
   14877         5769 :     num_teams_lower = num_teams;
   14878         5917 :   tree thread_limit = omp_find_clause (gimple_omp_teams_clauses (teams_stmt),
   14879         5917 :                                        OMP_CLAUSE_THREAD_LIMIT);
   14880         5917 :   if (thread_limit == NULL_TREE)
   14881         5446 :     thread_limit = build_int_cst (unsigned_type_node, 0);
   14882              :   else
   14883              :     {
   14884          471 :       thread_limit = OMP_CLAUSE_THREAD_LIMIT_EXPR (thread_limit);
   14885          471 :       thread_limit = fold_convert (unsigned_type_node, thread_limit);
   14886          471 :       gimplify_expr (&thread_limit, &bind_body, NULL, is_gimple_val,
   14887              :                      fb_rvalue);
   14888              :     }
   14889         5917 :   location_t loc = gimple_location (teams_stmt);
   14890         5917 :   tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TEAMS4);
   14891         5917 :   tree rettype = TREE_TYPE (TREE_TYPE (decl));
   14892         5917 :   tree first = create_tmp_var (rettype);
   14893         5917 :   gimple_seq_add_stmt (&bind_body,
   14894         5917 :                        gimple_build_assign (first, build_one_cst (rettype)));
   14895         5917 :   tree llabel = create_artificial_label (loc);
   14896         5917 :   gimple_seq_add_stmt (&bind_body, gimple_build_label (llabel));
   14897         5917 :   gimple *call
   14898         5917 :     = gimple_build_call (decl, 4, num_teams_lower, num_teams, thread_limit,
   14899              :                          first);
   14900         5917 :   gimple_set_location (call, loc);
   14901         5917 :   tree temp = create_tmp_var (rettype);
   14902         5917 :   gimple_call_set_lhs (call, temp);
   14903         5917 :   gimple_seq_add_stmt (&bind_body, call);
   14904              : 
   14905         5917 :   tree tlabel = create_artificial_label (loc);
   14906         5917 :   tree flabel = create_artificial_label (loc);
   14907         5917 :   gimple *cond = gimple_build_cond (NE_EXPR, temp, build_zero_cst (rettype),
   14908              :                                     tlabel, flabel);
   14909         5917 :   gimple_seq_add_stmt (&bind_body, cond);
   14910         5917 :   gimple_seq_add_stmt (&bind_body, gimple_build_label (tlabel));
   14911         5917 :   gimple_seq_add_stmt (&bind_body,
   14912         5917 :                        gimple_build_assign (first, build_zero_cst (rettype)));
   14913              : 
   14914         5917 :   lower_rec_input_clauses (gimple_omp_teams_clauses (teams_stmt),
   14915              :                            &bind_body, &dlist, ctx, NULL);
   14916         5917 :   lower_omp (gimple_omp_body_ptr (teams_stmt), ctx);
   14917         5917 :   lower_reduction_clauses (gimple_omp_teams_clauses (teams_stmt), &olist,
   14918              :                            NULL, ctx);
   14919         5917 :   gimple_seq_add_stmt (&bind_body, teams_stmt);
   14920              : 
   14921         5917 :   gimple_seq_add_seq (&bind_body, gimple_omp_body (teams_stmt));
   14922         5917 :   gimple_omp_set_body (teams_stmt, NULL);
   14923         5917 :   gimple_seq_add_seq (&bind_body, olist);
   14924         5917 :   gimple_seq_add_seq (&bind_body, dlist);
   14925         5917 :   gimple_seq_add_stmt (&bind_body, gimple_build_omp_return (true));
   14926         5917 :   gimple_seq_add_stmt (&bind_body, gimple_build_goto (llabel));
   14927         5917 :   gimple_seq_add_stmt (&bind_body, gimple_build_label (flabel));
   14928         5917 :   gimple_bind_set_body (bind, bind_body);
   14929              : 
   14930         5917 :   pop_gimplify_context (bind);
   14931              : 
   14932         5917 :   gimple_bind_append_vars (bind, ctx->block_vars);
   14933         5917 :   BLOCK_VARS (block) = ctx->block_vars;
   14934         5917 :   if (BLOCK_VARS (block))
   14935          687 :     TREE_USED (block) = 1;
   14936         5917 : }
   14937              : 
   14938              : /* Callback for lower_omp_1.  Return non-NULL if *tp needs to be
   14939              :    regimplified.  If DATA is non-NULL, lower_omp_1 is outside
   14940              :    of OMP context, but with make_addressable_vars set.  */
   14941              : 
   14942              : static tree
   14943      3199558 : lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
   14944              :                         void *data)
   14945              : {
   14946      3199558 :   tree t = *tp;
   14947              : 
   14948              :   /* Any variable with DECL_VALUE_EXPR needs to be regimplified.  */
   14949      3199558 :   if ((VAR_P (t) || TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
   14950      1488267 :       && data == NULL
   14951      1427841 :       && DECL_HAS_VALUE_EXPR_P (t))
   14952              :     return t;
   14953              : 
   14954      3094121 :   if (make_addressable_vars
   14955       422645 :       && DECL_P (t)
   14956      3299167 :       && bitmap_bit_p (make_addressable_vars, DECL_UID (t)))
   14957              :     return t;
   14958              : 
   14959              :   /* If a global variable has been privatized, TREE_CONSTANT on
   14960              :      ADDR_EXPR might be wrong.  */
   14961      3091532 :   if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
   14962       108627 :     recompute_tree_invariant_for_addr_expr (t);
   14963              : 
   14964      3091532 :   *walk_subtrees = !IS_TYPE_OR_DECL_P (t);
   14965      3091532 :   return NULL_TREE;
   14966              : }
   14967              : 
   14968              : /* Data to be communicated between lower_omp_regimplify_operands and
   14969              :    lower_omp_regimplify_operands_p.  */
   14970              : 
   14971              : struct lower_omp_regimplify_operands_data
   14972              : {
   14973              :   omp_context *ctx;
   14974              :   vec<tree> *decls;
   14975              : };
   14976              : 
   14977              : /* Helper function for lower_omp_regimplify_operands.  Find
   14978              :    omp_member_access_dummy_var vars and adjust temporarily their
   14979              :    DECL_VALUE_EXPRs if needed.  */
   14980              : 
   14981              : static tree
   14982       424882 : lower_omp_regimplify_operands_p (tree *tp, int *walk_subtrees,
   14983              :                                  void *data)
   14984              : {
   14985       424882 :   tree t = omp_member_access_dummy_var (*tp);
   14986       424882 :   if (t)
   14987              :     {
   14988            9 :       struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
   14989            9 :       lower_omp_regimplify_operands_data *ldata
   14990              :         = (lower_omp_regimplify_operands_data *) wi->info;
   14991            9 :       tree o = maybe_lookup_decl (t, ldata->ctx);
   14992            9 :       if (o == NULL_TREE)
   14993            5 :         o = maybe_lookup_decl_in_outer_ctx (t, ldata->ctx);
   14994            9 :       if (o != t)
   14995              :         {
   14996            9 :           ldata->decls->safe_push (DECL_VALUE_EXPR (*tp));
   14997            9 :           ldata->decls->safe_push (*tp);
   14998            9 :           tree v = unshare_and_remap (DECL_VALUE_EXPR (*tp), t, o);
   14999            9 :           SET_DECL_VALUE_EXPR (*tp, v);
   15000              :         }
   15001              :     }
   15002       424882 :   *walk_subtrees = !IS_TYPE_OR_DECL_P (*tp);
   15003       424882 :   return NULL_TREE;
   15004              : }
   15005              : 
   15006              : /* Wrapper around gimple_regimplify_operands that adjusts DECL_VALUE_EXPRs
   15007              :    of omp_member_access_dummy_var vars during regimplification.  */
   15008              : 
   15009              : static void
   15010       107871 : lower_omp_regimplify_operands (omp_context *ctx, gimple *stmt,
   15011              :                                gimple_stmt_iterator *gsi_p)
   15012              : {
   15013       107871 :   auto_vec<tree, 10> decls;
   15014       107871 :   if (ctx)
   15015              :     {
   15016       105349 :       struct walk_stmt_info wi;
   15017       105349 :       memset (&wi, '\0', sizeof (wi));
   15018       105349 :       struct lower_omp_regimplify_operands_data data;
   15019       105349 :       data.ctx = ctx;
   15020       105349 :       data.decls = &decls;
   15021       105349 :       wi.info = &data;
   15022       105349 :       walk_gimple_op (stmt, lower_omp_regimplify_operands_p, &wi);
   15023              :     }
   15024       107871 :   gimple_regimplify_operands (stmt, gsi_p);
   15025       323622 :   while (!decls.is_empty ())
   15026              :     {
   15027            9 :       tree t = decls.pop ();
   15028            9 :       tree v = decls.pop ();
   15029            9 :       SET_DECL_VALUE_EXPR (t, v);
   15030              :     }
   15031       107871 : }
   15032              : 
   15033              : static void
   15034      2499513 : lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   15035              : {
   15036      2499513 :   gimple *stmt = gsi_stmt (*gsi_p);
   15037      2499513 :   struct walk_stmt_info wi;
   15038      2499513 :   gcall *call_stmt;
   15039              : 
   15040      2499513 :   if (gimple_has_location (stmt))
   15041      2053021 :     input_location = gimple_location (stmt);
   15042              : 
   15043      2499513 :   if (make_addressable_vars)
   15044       154096 :     memset (&wi, '\0', sizeof (wi));
   15045              : 
   15046              :   /* If we have issued syntax errors, avoid doing any heavy lifting.
   15047              :      Just replace the OMP directives with a NOP to avoid
   15048              :      confusing RTL expansion.  */
   15049      2499513 :   if (seen_error () && is_gimple_omp (stmt))
   15050              :     {
   15051        11423 :       gsi_replace (gsi_p, gimple_build_nop (), true);
   15052        11423 :       return;
   15053              :     }
   15054              : 
   15055      2488090 :   switch (gimple_code (stmt))
   15056              :     {
   15057       155488 :     case GIMPLE_COND:
   15058       155488 :       {
   15059       155488 :         gcond *cond_stmt = as_a <gcond *> (stmt);
   15060        88413 :         if ((ctx || make_addressable_vars)
   15061       159096 :             && (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
   15062              :                            lower_omp_regimplify_p,
   15063              :                            ctx ? NULL : &wi, NULL)
   15064       135815 :                 || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
   15065              :                               lower_omp_regimplify_p,
   15066              :                               ctx ? NULL : &wi, NULL)))
   15067         1245 :           lower_omp_regimplify_operands (ctx, cond_stmt, gsi_p);
   15068              :       }
   15069              :       break;
   15070           20 :     case GIMPLE_CATCH:
   15071           20 :       lower_omp (gimple_catch_handler_ptr (as_a <gcatch *> (stmt)), ctx);
   15072           20 :       break;
   15073            0 :     case GIMPLE_EH_FILTER:
   15074            0 :       lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
   15075            0 :       break;
   15076        25858 :     case GIMPLE_TRY:
   15077        25858 :       lower_omp (gimple_try_eval_ptr (stmt), ctx);
   15078        25853 :       lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
   15079        25853 :       break;
   15080            0 :     case GIMPLE_ASSUME:
   15081            0 :       lower_omp (gimple_assume_body_ptr (stmt), ctx);
   15082            0 :       break;
   15083            5 :     case GIMPLE_TRANSACTION:
   15084            5 :       lower_omp (gimple_transaction_body_ptr (as_a <gtransaction *> (stmt)),
   15085              :                  ctx);
   15086            5 :       break;
   15087       167412 :     case GIMPLE_BIND:
   15088       167412 :       if (ctx && is_gimple_omp_oacc (ctx->stmt))
   15089              :         {
   15090        17785 :           tree vars = gimple_bind_vars (as_a <gbind *> (stmt));
   15091        17785 :           oacc_privatization_scan_decl_chain (ctx, vars);
   15092              :         }
   15093       167412 :       lower_omp (gimple_bind_body_ptr (as_a <gbind *> (stmt)), ctx);
   15094       167405 :       maybe_remove_omp_member_access_dummy_vars (as_a <gbind *> (stmt));
   15095       167405 :       break;
   15096        19964 :     case GIMPLE_OMP_PARALLEL:
   15097        19964 :     case GIMPLE_OMP_TASK:
   15098        19964 :       ctx = maybe_lookup_ctx (stmt);
   15099        19964 :       gcc_assert (ctx);
   15100        19964 :       if (ctx->cancellable)
   15101          135 :         ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
   15102        19964 :       lower_omp_taskreg (gsi_p, ctx);
   15103        19964 :       break;
   15104        46888 :     case GIMPLE_OMP_FOR:
   15105        46888 :       ctx = maybe_lookup_ctx (stmt);
   15106        46888 :       gcc_assert (ctx);
   15107        46888 :       if (ctx->cancellable)
   15108           84 :         ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
   15109        46888 :       lower_omp_for (gsi_p, ctx);
   15110        46888 :       break;
   15111          378 :     case GIMPLE_OMP_SECTIONS:
   15112          378 :       ctx = maybe_lookup_ctx (stmt);
   15113          378 :       gcc_assert (ctx);
   15114          378 :       if (ctx->cancellable)
   15115           19 :         ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
   15116          378 :       lower_omp_sections (gsi_p, ctx);
   15117          378 :       break;
   15118          133 :     case GIMPLE_OMP_SCOPE:
   15119          133 :       ctx = maybe_lookup_ctx (stmt);
   15120          133 :       gcc_assert (ctx);
   15121          133 :       lower_omp_scope (gsi_p, ctx);
   15122          133 :       break;
   15123          659 :     case GIMPLE_OMP_DISPATCH:
   15124          659 :       ctx = maybe_lookup_ctx (stmt);
   15125          659 :       gcc_assert (ctx);
   15126          659 :       lower_omp_dispatch (gsi_p, ctx);
   15127          659 :       break;
   15128          164 :     case GIMPLE_OMP_INTEROP:
   15129          164 :       ctx = maybe_lookup_ctx (stmt);
   15130          164 :       gcc_assert (ctx);
   15131          164 :       lower_omp_interop (gsi_p, ctx);
   15132          164 :       break;
   15133         1119 :     case GIMPLE_OMP_SINGLE:
   15134         1119 :       ctx = maybe_lookup_ctx (stmt);
   15135         1119 :       gcc_assert (ctx);
   15136         1119 :       lower_omp_single (gsi_p, ctx);
   15137         1119 :       break;
   15138          658 :     case GIMPLE_OMP_STRUCTURED_BLOCK:
   15139              :       /* We have already done error checking at this point, so these nodes
   15140              :          can be completely removed and replaced with their body.  */
   15141          658 :       ctx = maybe_lookup_ctx (stmt);
   15142          658 :       gcc_assert (ctx);
   15143          658 :       lower_omp (gimple_omp_body_ptr (stmt), ctx);
   15144          658 :       gsi_replace_with_seq (gsi_p, gimple_omp_body (stmt), true);
   15145          658 :       break;
   15146         1108 :     case GIMPLE_OMP_MASTER:
   15147         1108 :     case GIMPLE_OMP_MASKED:
   15148         1108 :       ctx = maybe_lookup_ctx (stmt);
   15149         1108 :       gcc_assert (ctx);
   15150         1108 :       lower_omp_master (gsi_p, ctx);
   15151         1108 :       break;
   15152          536 :     case GIMPLE_OMP_TASKGROUP:
   15153          536 :       ctx = maybe_lookup_ctx (stmt);
   15154          536 :       gcc_assert (ctx);
   15155          536 :       lower_omp_taskgroup (gsi_p, ctx);
   15156          536 :       break;
   15157         1124 :     case GIMPLE_OMP_ORDERED:
   15158         1124 :       ctx = maybe_lookup_ctx (stmt);
   15159         1124 :       gcc_assert (ctx);
   15160         1124 :       lower_omp_ordered (gsi_p, ctx);
   15161         1124 :       break;
   15162         1268 :     case GIMPLE_OMP_SCAN:
   15163         1268 :       ctx = maybe_lookup_ctx (stmt);
   15164         1268 :       gcc_assert (ctx);
   15165         1268 :       lower_omp_scan (gsi_p, ctx);
   15166         1268 :       break;
   15167          311 :     case GIMPLE_OMP_CRITICAL:
   15168          311 :       ctx = maybe_lookup_ctx (stmt);
   15169          311 :       gcc_assert (ctx);
   15170          311 :       lower_omp_critical (gsi_p, ctx);
   15171          311 :       break;
   15172         2516 :     case GIMPLE_OMP_ATOMIC_LOAD:
   15173           85 :       if ((ctx || make_addressable_vars)
   15174         2516 :           && walk_tree (gimple_omp_atomic_load_rhs_ptr (
   15175              :                           as_a <gomp_atomic_load *> (stmt)),
   15176              :                         lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
   15177         1425 :         lower_omp_regimplify_operands (ctx, stmt, gsi_p);
   15178              :       break;
   15179        36984 :     case GIMPLE_OMP_TARGET:
   15180        36984 :       ctx = maybe_lookup_ctx (stmt);
   15181        36984 :       gcc_assert (ctx);
   15182        36984 :       lower_omp_target (gsi_p, ctx);
   15183        36984 :       break;
   15184         8413 :     case GIMPLE_OMP_TEAMS:
   15185         8413 :       ctx = maybe_lookup_ctx (stmt);
   15186         8413 :       gcc_assert (ctx);
   15187         8413 :       if (gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
   15188         2496 :         lower_omp_taskreg (gsi_p, ctx);
   15189              :       else
   15190         5917 :         lower_omp_teams (gsi_p, ctx);
   15191              :       break;
   15192       134302 :     case GIMPLE_CALL:
   15193       134302 :       tree fndecl;
   15194       134302 :       call_stmt = as_a <gcall *> (stmt);
   15195       134302 :       fndecl = gimple_call_fndecl (call_stmt);
   15196       134302 :       if (fndecl
   15197       134302 :           && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
   15198        38593 :         switch (DECL_FUNCTION_CODE (fndecl))
   15199              :           {
   15200          727 :           case BUILT_IN_GOMP_BARRIER:
   15201          727 :             if (ctx == NULL)
   15202              :               break;
   15203              :             /* FALLTHRU */
   15204         1037 :           case BUILT_IN_GOMP_CANCEL:
   15205         1037 :           case BUILT_IN_GOMP_CANCELLATION_POINT:
   15206         1037 :             omp_context *cctx;
   15207         1037 :             cctx = ctx;
   15208         1037 :             if (gimple_code (cctx->stmt) == GIMPLE_OMP_SECTION)
   15209           43 :               cctx = cctx->outer;
   15210         1037 :             gcc_assert (gimple_call_lhs (call_stmt) == NULL_TREE);
   15211         1037 :             if (!cctx->cancellable)
   15212              :               {
   15213          679 :                 if (DECL_FUNCTION_CODE (fndecl)
   15214              :                     == BUILT_IN_GOMP_CANCELLATION_POINT)
   15215              :                   {
   15216            0 :                     stmt = gimple_build_nop ();
   15217            0 :                     gsi_replace (gsi_p, stmt, false);
   15218              :                   }
   15219              :                 break;
   15220              :               }
   15221          358 :             if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
   15222              :               {
   15223           14 :                 fndecl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER_CANCEL);
   15224           14 :                 gimple_call_set_fndecl (call_stmt, fndecl);
   15225           14 :                 gimple_call_set_fntype (call_stmt, TREE_TYPE (fndecl));
   15226              :               }
   15227          358 :             tree lhs;
   15228          358 :             lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (fndecl)));
   15229          358 :             gimple_call_set_lhs (call_stmt, lhs);
   15230          358 :             tree fallthru_label;
   15231          358 :             fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
   15232          358 :             gimple *g;
   15233          358 :             g = gimple_build_label (fallthru_label);
   15234          358 :             gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
   15235          358 :             g = gimple_build_cond (NE_EXPR, lhs,
   15236          358 :                                    fold_convert (TREE_TYPE (lhs),
   15237              :                                                  boolean_false_node),
   15238              :                                    cctx->cancel_label, fallthru_label);
   15239          358 :             gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
   15240          358 :             break;
   15241              :           default:
   15242              :             break;
   15243              :           }
   15244       134267 :       goto regimplify;
   15245              : 
   15246              :     case GIMPLE_ASSIGN:
   15247      1451370 :       for (omp_context *up = ctx; up; up = up->outer)
   15248              :         {
   15249       681716 :           if (gimple_code (up->stmt) == GIMPLE_OMP_ORDERED
   15250              :               || gimple_code (up->stmt) == GIMPLE_OMP_CRITICAL
   15251              :               || gimple_code (up->stmt) == GIMPLE_OMP_TASKGROUP
   15252              :               || gimple_code (up->stmt) == GIMPLE_OMP_SCOPE
   15253              :               || gimple_code (up->stmt) == GIMPLE_OMP_SECTION
   15254              :               || gimple_code (up->stmt) == GIMPLE_OMP_SCAN
   15255              :               || (gimple_code (up->stmt) == GIMPLE_OMP_TARGET
   15256       227839 :                   && (gimple_omp_target_kind (up->stmt)
   15257              :                       == GF_OMP_TARGET_KIND_DATA)))
   15258        90647 :             continue;
   15259       591069 :           else if (!up->lastprivate_conditional_map)
   15260              :             break;
   15261         4204 :           tree lhs = get_base_address (gimple_assign_lhs (stmt));
   15262         4204 :           if (TREE_CODE (lhs) == MEM_REF
   15263           26 :               && DECL_P (TREE_OPERAND (lhs, 0))
   15264         4227 :               && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs,
   15265              :                                                      0))) == REFERENCE_TYPE)
   15266           19 :             lhs = TREE_OPERAND (lhs, 0);
   15267         4204 :           if (DECL_P (lhs))
   15268         3161 :             if (tree *v = up->lastprivate_conditional_map->get (lhs))
   15269              :               {
   15270          382 :                 tree clauses;
   15271          382 :                 if (up->combined_into_simd_safelen1)
   15272              :                   {
   15273           54 :                     up = up->outer;
   15274           54 :                     if (gimple_code (up->stmt) == GIMPLE_OMP_SCAN)
   15275            3 :                       up = up->outer;
   15276              :                   }
   15277          382 :                 if (gimple_code (up->stmt) == GIMPLE_OMP_FOR)
   15278          298 :                   clauses = gimple_omp_for_clauses (up->stmt);
   15279              :                 else
   15280           84 :                   clauses = gimple_omp_sections_clauses (up->stmt);
   15281          382 :                 tree c = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_);
   15282          382 :                 if (!OMP_CLAUSE__CONDTEMP__ITER (c))
   15283          348 :                   c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
   15284              :                                        OMP_CLAUSE__CONDTEMP_);
   15285          382 :                 gcc_assert (OMP_CLAUSE__CONDTEMP__ITER (c));
   15286          382 :                 gimple *g = gimple_build_assign (*v, OMP_CLAUSE_DECL (c));
   15287          382 :                 gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
   15288              :               }
   15289              :         }
   15290              :       /* FALLTHRU */
   15291              : 
   15292      2017084 :     default:
   15293      2017084 :     regimplify:
   15294      1064657 :       if ((ctx || make_addressable_vars)
   15295      2092913 :           && walk_gimple_op (stmt, lower_omp_regimplify_p,
   15296              :                              ctx ? NULL : &wi))
   15297              :         {
   15298              :           /* Just remove clobbers, this should happen only if we have
   15299              :              "privatized" local addressable variables in SIMD regions,
   15300              :              the clobber isn't needed in that case and gimplifying address
   15301              :              of the ARRAY_REF into a pointer and creating MEM_REF based
   15302              :              clobber would create worse code than we get with the clobber
   15303              :              dropped.  */
   15304       105356 :           if (gimple_clobber_p (stmt))
   15305              :             {
   15306          155 :               gsi_replace (gsi_p, gimple_build_nop (), true);
   15307          155 :               break;
   15308              :             }
   15309       105201 :           lower_omp_regimplify_operands (ctx, stmt, gsi_p);
   15310              :         }
   15311              :       break;
   15312              :     }
   15313              : }
   15314              : 
   15315              : static void
   15316       409532 : lower_omp (gimple_seq *body, omp_context *ctx)
   15317              : {
   15318       409532 :   location_t saved_location = input_location;
   15319       409532 :   gimple_stmt_iterator gsi;
   15320      3270425 :   for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
   15321      2499513 :     lower_omp_1 (&gsi, ctx);
   15322              :   /* During gimplification, we haven't folded statments inside offloading
   15323              :      or taskreg regions (gimplify.cc:maybe_fold_stmt); do that now.  */
   15324       409516 :   if (target_nesting_level || taskreg_nesting_level)
   15325       651734 :     for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
   15326       439394 :       fold_stmt (&gsi);
   15327       409516 :   input_location = saved_location;
   15328       409516 : }
   15329              : 
   15330              : /* Main entry point.  */
   15331              : 
   15332              : static unsigned int
   15333      2899842 : execute_lower_omp (void)
   15334              : {
   15335      2899842 :   gimple_seq body;
   15336      2899842 :   int i;
   15337      2899842 :   omp_context *ctx;
   15338              : 
   15339              :   /* This pass always runs, to provide PROP_gimple_lomp.
   15340              :      But often, there is nothing to do.  */
   15341      2899842 :   if (flag_openacc == 0 && flag_openmp == 0
   15342      2845438 :       && flag_openmp_simd == 0)
   15343              :     return 0;
   15344              : 
   15345        56661 :   all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
   15346              :                                  delete_omp_context);
   15347              : 
   15348        56661 :   body = gimple_body (current_function_decl);
   15349              : 
   15350        56661 :   scan_omp (&body, NULL);
   15351        56661 :   gcc_assert (taskreg_nesting_level == 0);
   15352        82659 :   FOR_EACH_VEC_ELT (taskreg_contexts, i, ctx)
   15353        25998 :     finish_taskreg_scan (ctx);
   15354        56661 :   taskreg_contexts.release ();
   15355              : 
   15356        56661 :   if (all_contexts->root)
   15357              :     {
   15358        25635 :       if (make_addressable_vars)
   15359          620 :         push_gimplify_context ();
   15360        25635 :       lower_omp (&body, NULL);
   15361        25631 :       if (make_addressable_vars)
   15362          620 :         pop_gimplify_context (NULL);
   15363              :     }
   15364              : 
   15365        56657 :   if (all_contexts)
   15366              :     {
   15367        56657 :       splay_tree_delete (all_contexts);
   15368        56657 :       all_contexts = NULL;
   15369              :     }
   15370        56657 :   BITMAP_FREE (make_addressable_vars);
   15371        56657 :   BITMAP_FREE (global_nonaddressable_vars);
   15372              : 
   15373              :   /* If current function is a method, remove artificial dummy VAR_DECL created
   15374              :      for non-static data member privatization, they aren't needed for
   15375              :      debuginfo nor anything else, have been already replaced everywhere in the
   15376              :      IL and cause problems with LTO.  */
   15377        56657 :   if (DECL_ARGUMENTS (current_function_decl)
   15378        32410 :       && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl))
   15379        66204 :       && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl)))
   15380              :           == POINTER_TYPE))
   15381         8991 :     remove_member_access_dummy_vars (DECL_INITIAL (current_function_decl));
   15382              : 
   15383        57633 :   for (auto task_stmt : task_cpyfns)
   15384          504 :     finalize_task_copyfn (task_stmt);
   15385        56657 :   task_cpyfns.release ();
   15386        56657 :   return 0;
   15387              : }
   15388              : 
   15389              : namespace {
   15390              : 
   15391              : const pass_data pass_data_lower_omp =
   15392              : {
   15393              :   GIMPLE_PASS, /* type */
   15394              :   "omplower", /* name */
   15395              :   OPTGROUP_OMP, /* optinfo_flags */
   15396              :   TV_NONE, /* tv_id */
   15397              :   PROP_gimple_any, /* properties_required */
   15398              :   PROP_gimple_lomp | PROP_gimple_lomp_dev, /* properties_provided */
   15399              :   0, /* properties_destroyed */
   15400              :   0, /* todo_flags_start */
   15401              :   0, /* todo_flags_finish */
   15402              : };
   15403              : 
   15404              : class pass_lower_omp : public gimple_opt_pass
   15405              : {
   15406              : public:
   15407       288767 :   pass_lower_omp (gcc::context *ctxt)
   15408       577534 :     : gimple_opt_pass (pass_data_lower_omp, ctxt)
   15409              :   {}
   15410              : 
   15411              :   /* opt_pass methods: */
   15412      2899842 :   unsigned int execute (function *) final override
   15413              :   {
   15414      2899842 :     return execute_lower_omp ();
   15415              :   }
   15416              : 
   15417              : }; // class pass_lower_omp
   15418              : 
   15419              : } // anon namespace
   15420              : 
   15421              : gimple_opt_pass *
   15422       288767 : make_pass_lower_omp (gcc::context *ctxt)
   15423              : {
   15424       288767 :   return new pass_lower_omp (ctxt);
   15425              : }
   15426              : 
   15427              : /* The following is a utility to diagnose structured block violations.
   15428              :    It is not part of the "omplower" pass, as that's invoked too late.  It
   15429              :    should be invoked by the respective front ends after gimplification.  */
   15430              : 
   15431              : static splay_tree all_labels;
   15432              : 
   15433              : /* Check for mismatched contexts and generate an error if needed.  Return
   15434              :    true if an error is detected.  */
   15435              : 
   15436              : static bool
   15437       558774 : diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
   15438              :                gimple *branch_ctx, gimple *label_ctx)
   15439              : {
   15440       558774 :   gcc_checking_assert (!branch_ctx || is_gimple_omp (branch_ctx));
   15441       558774 :   gcc_checking_assert (!label_ctx || is_gimple_omp (label_ctx));
   15442              : 
   15443       558774 :   if (label_ctx == branch_ctx)
   15444              :     return false;
   15445              : 
   15446          180 :   const char* kind = NULL;
   15447              : 
   15448          180 :   if (flag_openacc)
   15449              :     {
   15450            7 :       if ((branch_ctx && is_gimple_omp_oacc (branch_ctx))
   15451           16 :           || (label_ctx && is_gimple_omp_oacc (label_ctx)))
   15452              :         {
   15453              :           gcc_checking_assert (kind == NULL);
   15454              :           kind = "OpenACC";
   15455              :         }
   15456              :     }
   15457              :   if (kind == NULL)
   15458              :     {
   15459          164 :       gcc_checking_assert (flag_openmp || flag_openmp_simd);
   15460              :       kind = "OpenMP";
   15461              :     }
   15462              : 
   15463              :   /* Previously we kept track of the label's entire context in diagnose_sb_[12]
   15464              :      so we could traverse it and issue a correct "exit" or "enter" error
   15465              :      message upon a structured block violation.
   15466              : 
   15467              :      We built the context by building a list with tree_cons'ing, but there is
   15468              :      no easy counterpart in gimple tuples.  It seems like far too much work
   15469              :      for issuing exit/enter error messages.  If someone really misses the
   15470              :      distinct error message... patches welcome.  */
   15471              : 
   15472              : #if 0
   15473              :   /* Try to avoid confusing the user by producing and error message
   15474              :      with correct "exit" or "enter" verbiage.  We prefer "exit"
   15475              :      unless we can show that LABEL_CTX is nested within BRANCH_CTX.  */
   15476              :   if (branch_ctx == NULL)
   15477              :     exit_p = false;
   15478              :   else
   15479              :     {
   15480              :       while (label_ctx)
   15481              :         {
   15482              :           if (TREE_VALUE (label_ctx) == branch_ctx)
   15483              :             {
   15484              :               exit_p = false;
   15485              :               break;
   15486              :             }
   15487              :           label_ctx = TREE_CHAIN (label_ctx);
   15488              :         }
   15489              :     }
   15490              : 
   15491              :   if (exit_p)
   15492              :     error ("invalid exit from %s structured block", kind);
   15493              :   else
   15494              :     error ("invalid entry to %s structured block", kind);
   15495              : #endif
   15496              : 
   15497              :   /* If it's obvious we have an invalid entry, be specific about the error.  */
   15498          180 :   if (branch_ctx == NULL)
   15499           53 :     error ("invalid entry to %s structured block", kind);
   15500              :   else
   15501              :     {
   15502              :       /* Otherwise, be vague and lazy, but efficient.  */
   15503          127 :       error ("invalid branch to/from %s structured block", kind);
   15504              :     }
   15505              : 
   15506          180 :   gsi_replace (gsi_p, gimple_build_nop (), false);
   15507          180 :   return true;
   15508              : }
   15509              : 
   15510              : /* Pass 1: Create a minimal tree of structured blocks, and record
   15511              :    where each label is found.  */
   15512              : 
   15513              : static tree
   15514      3335517 : diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
   15515              :                struct walk_stmt_info *wi)
   15516              : {
   15517      3335517 :   gimple *context = (gimple *) wi->info;
   15518      3335517 :   gimple *inner_context;
   15519      3335517 :   gimple *stmt = gsi_stmt (*gsi_p);
   15520              : 
   15521      3335517 :   *handled_ops_p = true;
   15522              : 
   15523      3335517 :   switch (gimple_code (stmt))
   15524              :     {
   15525       318315 :     WALK_SUBSTMTS;
   15526              : 
   15527        83470 :     case GIMPLE_OMP_PARALLEL:
   15528        83470 :     case GIMPLE_OMP_TASK:
   15529        83470 :     case GIMPLE_OMP_SCOPE:
   15530        83470 :     case GIMPLE_OMP_SECTIONS:
   15531        83470 :     case GIMPLE_OMP_SINGLE:
   15532        83470 :     case GIMPLE_OMP_SECTION:
   15533        83470 :     case GIMPLE_OMP_STRUCTURED_BLOCK:
   15534        83470 :     case GIMPLE_OMP_MASTER:
   15535        83470 :     case GIMPLE_OMP_MASKED:
   15536        83470 :     case GIMPLE_OMP_ORDERED:
   15537        83470 :     case GIMPLE_OMP_SCAN:
   15538        83470 :     case GIMPLE_OMP_CRITICAL:
   15539        83470 :     case GIMPLE_OMP_TARGET:
   15540        83470 :     case GIMPLE_OMP_TEAMS:
   15541        83470 :     case GIMPLE_OMP_TASKGROUP:
   15542              :       /* The minimal context here is just the current OMP construct.  */
   15543        83470 :       inner_context = stmt;
   15544        83470 :       wi->info = inner_context;
   15545        83470 :       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
   15546        83470 :       wi->info = context;
   15547        83470 :       break;
   15548              : 
   15549        52752 :     case GIMPLE_OMP_FOR:
   15550        52752 :       inner_context = stmt;
   15551        52752 :       wi->info = inner_context;
   15552              :       /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
   15553              :          walk them.  */
   15554        52752 :       walk_gimple_seq (gimple_omp_for_pre_body (stmt),
   15555              :                        diagnose_sb_1, NULL, wi);
   15556        52752 :       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
   15557        52752 :       wi->info = context;
   15558        52752 :       break;
   15559              : 
   15560       555405 :     case GIMPLE_LABEL:
   15561      1110810 :       splay_tree_insert (all_labels,
   15562       555405 :                          (splay_tree_key) gimple_label_label (
   15563       555405 :                                             as_a <glabel *> (stmt)),
   15564              :                          (splay_tree_value) context);
   15565       555405 :       break;
   15566              : 
   15567              :     default:
   15568              :       break;
   15569              :     }
   15570              : 
   15571      3335517 :   return NULL_TREE;
   15572              : }
   15573              : 
   15574              : /* Pass 2: Check each branch and see if its context differs from that of
   15575              :    the destination label's context.  */
   15576              : 
   15577              : static tree
   15578      3335517 : diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
   15579              :                struct walk_stmt_info *wi)
   15580              : {
   15581      3335517 :   gimple *context = (gimple *) wi->info;
   15582      3335517 :   splay_tree_node n;
   15583      3335517 :   gimple *stmt = gsi_stmt (*gsi_p);
   15584              : 
   15585      3335517 :   *handled_ops_p = true;
   15586              : 
   15587      3335517 :   switch (gimple_code (stmt))
   15588              :     {
   15589       318315 :     WALK_SUBSTMTS;
   15590              : 
   15591        83470 :     case GIMPLE_OMP_PARALLEL:
   15592        83470 :     case GIMPLE_OMP_TASK:
   15593        83470 :     case GIMPLE_OMP_SCOPE:
   15594        83470 :     case GIMPLE_OMP_SECTIONS:
   15595        83470 :     case GIMPLE_OMP_SINGLE:
   15596        83470 :     case GIMPLE_OMP_SECTION:
   15597        83470 :     case GIMPLE_OMP_STRUCTURED_BLOCK:
   15598        83470 :     case GIMPLE_OMP_MASTER:
   15599        83470 :     case GIMPLE_OMP_MASKED:
   15600        83470 :     case GIMPLE_OMP_ORDERED:
   15601        83470 :     case GIMPLE_OMP_SCAN:
   15602        83470 :     case GIMPLE_OMP_CRITICAL:
   15603        83470 :     case GIMPLE_OMP_TARGET:
   15604        83470 :     case GIMPLE_OMP_TEAMS:
   15605        83470 :     case GIMPLE_OMP_TASKGROUP:
   15606        83470 :       wi->info = stmt;
   15607        83470 :       walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
   15608        83470 :       wi->info = context;
   15609        83470 :       break;
   15610              : 
   15611        52752 :     case GIMPLE_OMP_FOR:
   15612        52752 :       wi->info = stmt;
   15613              :       /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
   15614              :          walk them.  */
   15615        52752 :       walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
   15616              :                            diagnose_sb_2, NULL, wi);
   15617        52752 :       walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
   15618        52752 :       wi->info = context;
   15619        52752 :       break;
   15620              : 
   15621       205718 :     case GIMPLE_COND:
   15622       205718 :         {
   15623       205718 :           gcond *cond_stmt = as_a <gcond *> (stmt);
   15624       205718 :           tree lab = gimple_cond_true_label (cond_stmt);
   15625       205718 :           if (lab)
   15626              :             {
   15627       205718 :               n = splay_tree_lookup (all_labels,
   15628              :                                      (splay_tree_key) lab);
   15629       411436 :               diagnose_sb_0 (gsi_p, context,
   15630       205718 :                              n ? (gimple *) n->value : NULL);
   15631              :             }
   15632       205718 :           lab = gimple_cond_false_label (cond_stmt);
   15633       205718 :           if (lab)
   15634              :             {
   15635       205718 :               n = splay_tree_lookup (all_labels,
   15636              :                                      (splay_tree_key) lab);
   15637       411436 :               diagnose_sb_0 (gsi_p, context,
   15638       205718 :                              n ? (gimple *) n->value : NULL);
   15639              :             }
   15640              :         }
   15641              :       break;
   15642              : 
   15643       111635 :     case GIMPLE_GOTO:
   15644       111635 :       {
   15645       111635 :         tree lab = gimple_goto_dest (stmt);
   15646       111635 :         if (TREE_CODE (lab) != LABEL_DECL)
   15647              :           break;
   15648              : 
   15649       111635 :         n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
   15650       111635 :         diagnose_sb_0 (gsi_p, context, n ? (gimple *) n->value : NULL);
   15651              :       }
   15652       111635 :       break;
   15653              : 
   15654          424 :     case GIMPLE_SWITCH:
   15655          424 :       {
   15656          424 :         gswitch *switch_stmt = as_a <gswitch *> (stmt);
   15657          424 :         unsigned int i;
   15658         1724 :         for (i = 0; i < gimple_switch_num_labels (switch_stmt); ++i)
   15659              :           {
   15660         1316 :             tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
   15661         1316 :             n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
   15662         1316 :             if (n && diagnose_sb_0 (gsi_p, context, (gimple *) n->value))
   15663              :               break;
   15664              :           }
   15665              :       }
   15666              :       break;
   15667              : 
   15668          737 :     case GIMPLE_ASM:
   15669          737 :       {
   15670          737 :         gasm *asm_stmt = as_a <gasm *> (stmt);
   15671          752 :         for (unsigned i = 0; i < gimple_asm_nlabels (asm_stmt); ++i)
   15672              :           {
   15673           21 :             tree lab = TREE_VALUE (gimple_asm_label_op (asm_stmt, i));
   15674           21 :             n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
   15675           21 :             if (n && diagnose_sb_0 (gsi_p, context, (gimple *) n->value))
   15676              :               break;
   15677              :           }
   15678              :       }
   15679              :       break;
   15680              : 
   15681        34366 :     case GIMPLE_RETURN:
   15682        34366 :       diagnose_sb_0 (gsi_p, context, NULL);
   15683        34366 :       break;
   15684              : 
   15685              :     default:
   15686              :       break;
   15687              :     }
   15688              : 
   15689      3335517 :   return NULL_TREE;
   15690              : }
   15691              : 
   15692              : static unsigned int
   15693        56670 : diagnose_omp_structured_block_errors (void)
   15694              : {
   15695        56670 :   struct walk_stmt_info wi;
   15696        56670 :   gimple_seq body = gimple_body (current_function_decl);
   15697              : 
   15698        56670 :   all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
   15699              : 
   15700        56670 :   memset (&wi, 0, sizeof (wi));
   15701        56670 :   walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
   15702              : 
   15703        56670 :   memset (&wi, 0, sizeof (wi));
   15704        56670 :   wi.want_locations = true;
   15705        56670 :   walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);
   15706              : 
   15707        56670 :   gimple_set_body (current_function_decl, body);
   15708              : 
   15709        56670 :   splay_tree_delete (all_labels);
   15710        56670 :   all_labels = NULL;
   15711              : 
   15712        56670 :   return 0;
   15713              : }
   15714              : 
   15715              : namespace {
   15716              : 
   15717              : const pass_data pass_data_diagnose_omp_blocks =
   15718              : {
   15719              :   GIMPLE_PASS, /* type */
   15720              :   "*diagnose_omp_blocks", /* name */
   15721              :   OPTGROUP_OMP, /* optinfo_flags */
   15722              :   TV_NONE, /* tv_id */
   15723              :   PROP_gimple_any, /* properties_required */
   15724              :   0, /* properties_provided */
   15725              :   0, /* properties_destroyed */
   15726              :   0, /* todo_flags_start */
   15727              :   0, /* todo_flags_finish */
   15728              : };
   15729              : 
   15730              : class pass_diagnose_omp_blocks : public gimple_opt_pass
   15731              : {
   15732              : public:
   15733       288767 :   pass_diagnose_omp_blocks (gcc::context *ctxt)
   15734       577534 :     : gimple_opt_pass (pass_data_diagnose_omp_blocks, ctxt)
   15735              :   {}
   15736              : 
   15737              :   /* opt_pass methods: */
   15738      2899856 :   bool gate (function *) final override
   15739              :   {
   15740      2899856 :     return flag_openacc || flag_openmp || flag_openmp_simd;
   15741              :   }
   15742        56670 :   unsigned int execute (function *) final override
   15743              :     {
   15744        56670 :       return diagnose_omp_structured_block_errors ();
   15745              :     }
   15746              : 
   15747              : }; // class pass_diagnose_omp_blocks
   15748              : 
   15749              : } // anon namespace
   15750              : 
   15751              : gimple_opt_pass *
   15752       288767 : make_pass_diagnose_omp_blocks (gcc::context *ctxt)
   15753              : {
   15754       288767 :   return new pass_diagnose_omp_blocks (ctxt);
   15755              : }
   15756              : 
   15757              : 
   15758              : #include "gt-omp-low.h"
        

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.