LCOV - code coverage report
Current view: top level - gcc - omp-low.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.9 % 8790 8345
Test Date: 2024-04-20 14:03:02 Functions: 96.8 % 126 122
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     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-2024 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                 :       15614 : is_oacc_parallel_or_serial (omp_context *ctx)
     216                 :             : {
     217                 :       15614 :   enum gimple_code outer_type = gimple_code (ctx->stmt);
     218                 :       15614 :   return ((outer_type == GIMPLE_OMP_TARGET)
     219                 :       15614 :           && ((gimple_omp_target_kind (ctx->stmt)
     220                 :             :                == GF_OMP_TARGET_KIND_OACC_PARALLEL)
     221                 :         270 :               || (gimple_omp_target_kind (ctx->stmt)
     222                 :       15614 :                   == 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                 :       45795 : is_oacc_kernels (omp_context *ctx)
     230                 :             : {
     231                 :       45795 :   enum gimple_code outer_type = gimple_code (ctx->stmt);
     232                 :       45795 :   return ((outer_type == GIMPLE_OMP_TARGET)
     233                 :       45795 :           && (gimple_omp_target_kind (ctx->stmt)
     234                 :       45795 :               == GF_OMP_TARGET_KIND_OACC_KERNELS));
     235                 :             : }
     236                 :             : 
     237                 :             : /* Return whether CTX represents an OpenACC 'kernels' decomposed part.  */
     238                 :             : 
     239                 :             : static bool
     240                 :       18777 : is_oacc_kernels_decomposed_part (omp_context *ctx)
     241                 :             : {
     242                 :       18777 :   enum gimple_code outer_type = gimple_code (ctx->stmt);
     243                 :       18777 :   return ((outer_type == GIMPLE_OMP_TARGET)
     244                 :       18777 :           && ((gimple_omp_target_kind (ctx->stmt)
     245                 :             :                == GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED)
     246                 :       12762 :               || (gimple_omp_target_kind (ctx->stmt)
     247                 :             :                   == GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE)
     248                 :       12762 :               || (gimple_omp_target_kind (ctx->stmt)
     249                 :       18777 :                   == GF_OMP_TARGET_KIND_OACC_DATA_KERNELS)));
     250                 :             : }
     251                 :             : 
     252                 :             : /* Return true if STMT corresponds to an OpenMP target region.  */
     253                 :             : static bool
     254                 :       42463 : is_omp_target (gimple *stmt)
     255                 :             : {
     256                 :       42463 :   if (gimple_code (stmt) == GIMPLE_OMP_TARGET)
     257                 :             :     {
     258                 :        5857 :       int kind = gimple_omp_target_kind (stmt);
     259                 :        5857 :       return (kind == GF_OMP_TARGET_KIND_REGION
     260                 :        5857 :               || kind == GF_OMP_TARGET_KIND_DATA
     261                 :        5857 :               || kind == GF_OMP_TARGET_KIND_ENTER_DATA
     262                 :       10336 :               || 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                 :      476285 : omp_member_access_dummy_var (tree decl)
     273                 :             : {
     274                 :      476285 :   if (!VAR_P (decl)
     275                 :      305301 :       || !DECL_ARTIFICIAL (decl)
     276                 :      148698 :       || !DECL_IGNORED_P (decl)
     277                 :      143949 :       || !DECL_HAS_VALUE_EXPR_P (decl)
     278                 :      487941 :       || !lang_hooks.decls.omp_disregard_value_expr (decl, false))
     279                 :      473624 :     return NULL_TREE;
     280                 :             : 
     281                 :        2661 :   tree v = DECL_VALUE_EXPR (decl);
     282                 :        2661 :   if (TREE_CODE (v) != COMPONENT_REF)
     283                 :             :     return NULL_TREE;
     284                 :             : 
     285                 :       19195 :   while (1)
     286                 :       10913 :     switch (TREE_CODE (v))
     287                 :             :       {
     288                 :        8282 :       case COMPONENT_REF:
     289                 :        8282 :       case MEM_REF:
     290                 :        8282 :       case INDIRECT_REF:
     291                 :        8282 :       CASE_CONVERT:
     292                 :        8282 :       case POINTER_PLUS_EXPR:
     293                 :        8282 :         v = TREE_OPERAND (v, 0);
     294                 :        8282 :         continue;
     295                 :        2612 :       case PARM_DECL:
     296                 :        2612 :         if (DECL_CONTEXT (v) == current_function_decl
     297                 :        2612 :             && DECL_ARTIFICIAL (v)
     298                 :        5224 :             && 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                 :        1798 : unshare_and_remap_1 (tree *tp, int *walk_subtrees, void *data)
     310                 :             : {
     311                 :        1798 :   tree *pair = (tree *) data;
     312                 :        1798 :   if (*tp == pair[0])
     313                 :             :     {
     314                 :         266 :       *tp = unshare_expr (pair[1]);
     315                 :         266 :       *walk_subtrees = 0;
     316                 :             :     }
     317                 :        1532 :   else if (IS_TYPE_OR_DECL_P (*tp))
     318                 :         277 :     *walk_subtrees = 0;
     319                 :        1798 :   return NULL_TREE;
     320                 :             : }
     321                 :             : 
     322                 :             : /* Return unshare_expr (X) with all occurrences of FROM
     323                 :             :    replaced with TO.  */
     324                 :             : 
     325                 :             : static tree
     326                 :         169 : unshare_and_remap (tree x, tree from, tree to)
     327                 :             : {
     328                 :         169 :   tree pair[2] = { from, to };
     329                 :         169 :   x = unshare_expr (x);
     330                 :         169 :   walk_tree (&x, unshare_and_remap_1, pair, NULL);
     331                 :         169 :   return x;
     332                 :             : }
     333                 :             : 
     334                 :             : /* Convenience function for calling scan_omp_1_op on tree operands.  */
     335                 :             : 
     336                 :             : static inline tree
     337                 :      343033 : scan_omp_op (tree *tp, omp_context *ctx)
     338                 :             : {
     339                 :      343033 :   struct walk_stmt_info wi;
     340                 :             : 
     341                 :      343033 :   memset (&wi, 0, sizeof (wi));
     342                 :      343033 :   wi.info = ctx;
     343                 :      343033 :   wi.want_locations = true;
     344                 :             : 
     345                 :      343033 :   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                 :      767059 : is_parallel_ctx (omp_context *ctx)
     356                 :             : {
     357                 :       60734 :   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                 :      231790 : is_task_ctx (omp_context *ctx)
     365                 :             : {
     366                 :       38979 :   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                 :        8612 : is_taskloop_ctx (omp_context *ctx)
     374                 :             : {
     375                 :        8612 :   return gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
     376                 :        8612 :          && 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                 :      515923 : is_host_teams_ctx (omp_context *ctx)
     384                 :             : {
     385                 :      515923 :   return gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
     386                 :      515923 :          && 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                 :      654951 : is_taskreg_ctx (omp_context *ctx)
     395                 :             : {
     396                 :      654951 :   return is_parallel_ctx (ctx) || is_task_ctx (ctx) || is_host_teams_ctx (ctx);
     397                 :             : }
     398                 :             : 
     399                 :             : /* Return true if EXPR is variable sized.  */
     400                 :             : 
     401                 :             : static inline bool
     402                 :      875713 : is_variable_sized (const_tree expr)
     403                 :             : {
     404                 :      875713 :   return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
     405                 :             : }
     406                 :             : 
     407                 :             : /* Lookup variables.  The "maybe" form
     408                 :             :    allows for the variable form to not have been entered, otherwise we
     409                 :             :    assert that the variable must have been entered.  */
     410                 :             : 
     411                 :             : static inline tree
     412                 :      697895 : lookup_decl (tree var, omp_context *ctx)
     413                 :             : {
     414                 :     1395690 :   tree *n = ctx->cb.decl_map->get (var);
     415                 :      697895 :   return *n;
     416                 :             : }
     417                 :             : 
     418                 :             : static inline tree
     419                 :      707580 : maybe_lookup_decl (const_tree var, omp_context *ctx)
     420                 :             : {
     421                 :      707580 :   tree *n = ctx->cb.decl_map->get (const_cast<tree> (var));
     422                 :      707580 :   return n ? *n : NULL_TREE;
     423                 :             : }
     424                 :             : 
     425                 :             : static inline tree
     426                 :      123652 : lookup_field (tree var, omp_context *ctx)
     427                 :             : {
     428                 :      123652 :   splay_tree_node n;
     429                 :      247304 :   n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
     430                 :      123652 :   return (tree) n->value;
     431                 :             : }
     432                 :             : 
     433                 :             : static inline tree
     434                 :      161788 : lookup_sfield (splay_tree_key key, omp_context *ctx)
     435                 :             : {
     436                 :      161788 :   splay_tree_node n;
     437                 :      161788 :   n = splay_tree_lookup (ctx->sfield_map
     438                 :             :                          ? ctx->sfield_map : ctx->field_map, key);
     439                 :      161788 :   return (tree) n->value;
     440                 :             : }
     441                 :             : 
     442                 :             : static inline tree
     443                 :        1033 : lookup_sfield (tree var, omp_context *ctx)
     444                 :             : {
     445                 :        1033 :   return lookup_sfield ((splay_tree_key) var, ctx);
     446                 :             : }
     447                 :             : 
     448                 :             : static inline tree
     449                 :      213818 : maybe_lookup_field (splay_tree_key key, omp_context *ctx)
     450                 :             : {
     451                 :      213818 :   splay_tree_node n;
     452                 :      213818 :   n = splay_tree_lookup (ctx->field_map, key);
     453                 :      213818 :   return n ? (tree) n->value : NULL_TREE;
     454                 :             : }
     455                 :             : 
     456                 :             : static inline tree
     457                 :      213818 : maybe_lookup_field (tree var, omp_context *ctx)
     458                 :             : {
     459                 :        2507 :   return maybe_lookup_field ((splay_tree_key) var, ctx);
     460                 :             : }
     461                 :             : 
     462                 :             : /* Return true if DECL should be copied by pointer.  SHARED_CTX is
     463                 :             :    the parallel context if DECL is to be shared.  */
     464                 :             : 
     465                 :             : static bool
     466                 :      225019 : use_pointer_for_field (tree decl, omp_context *shared_ctx)
     467                 :             : {
     468                 :      438479 :   if (AGGREGATE_TYPE_P (TREE_TYPE (decl))
     469                 :      433430 :       || TYPE_ATOMIC (TREE_TYPE (decl)))
     470                 :             :     return true;
     471                 :             : 
     472                 :             :   /* We can only use copy-in/copy-out semantics for shared variables
     473                 :             :      when we know the value is not accessible from an outer scope.  */
     474                 :      208381 :   if (shared_ctx)
     475                 :             :     {
     476                 :       27654 :       gcc_assert (!is_gimple_omp_oacc (shared_ctx->stmt));
     477                 :             : 
     478                 :             :       /* ??? Trivially accessible from anywhere.  But why would we even
     479                 :             :          be passing an address in this case?  Should we simply assert
     480                 :             :          this to be false, or should we have a cleanup pass that removes
     481                 :             :          these from the list of mappings?  */
     482                 :       27654 :       if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, shared_ctx)))
     483                 :             :         return true;
     484                 :             : 
     485                 :             :       /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
     486                 :             :          without analyzing the expression whether or not its location
     487                 :             :          is accessible to anyone else.  In the case of nested parallel
     488                 :             :          regions it certainly may be.  */
     489                 :       27654 :       if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
     490                 :             :         return true;
     491                 :             : 
     492                 :             :       /* Do not use copy-in/copy-out for variables that have their
     493                 :             :          address taken.  */
     494                 :       26739 :       if (is_global_var (decl))
     495                 :             :         {
     496                 :             :           /* For file scope vars, track whether we've seen them as
     497                 :             :              non-addressable initially and in that case, keep the same
     498                 :             :              answer for the duration of the pass, even when they are made
     499                 :             :              addressable later on e.g. through reduction expansion.  Global
     500                 :             :              variables which weren't addressable before the pass will not
     501                 :             :              have their privatized copies address taken.  See PR91216.  */
     502                 :        1369 :           if (!TREE_ADDRESSABLE (decl))
     503                 :             :             {
     504                 :         609 :               if (!global_nonaddressable_vars)
     505                 :          91 :                 global_nonaddressable_vars = BITMAP_ALLOC (NULL);
     506                 :         609 :               bitmap_set_bit (global_nonaddressable_vars, DECL_UID (decl));
     507                 :             :             }
     508                 :         760 :           else if (!global_nonaddressable_vars
     509                 :        1016 :                    || !bitmap_bit_p (global_nonaddressable_vars,
     510                 :         256 :                                      DECL_UID (decl)))
     511                 :         738 :             return true;
     512                 :             :         }
     513                 :       25370 :       else if (TREE_ADDRESSABLE (decl))
     514                 :             :         return true;
     515                 :             : 
     516                 :             :       /* lower_send_shared_vars only uses copy-in, but not copy-out
     517                 :             :          for these.  */
     518                 :       17084 :       if (TREE_READONLY (decl)
     519                 :       17084 :           || ((TREE_CODE (decl) == RESULT_DECL
     520                 :       11299 :                || TREE_CODE (decl) == PARM_DECL)
     521                 :         694 :               && DECL_BY_REFERENCE (decl)))
     522                 :             :         return false;
     523                 :             : 
     524                 :             :       /* Disallow copy-in/out in nested parallel if
     525                 :             :          decl is shared in outer parallel, otherwise
     526                 :             :          each thread could store the shared variable
     527                 :             :          in its own copy-in location, making the
     528                 :             :          variable no longer really shared.  */
     529                 :       11066 :       if (shared_ctx->is_nested)
     530                 :             :         {
     531                 :        2405 :           omp_context *up;
     532                 :             : 
     533                 :        5877 :           for (up = shared_ctx->outer; up; up = up->outer)
     534                 :        5586 :             if ((is_taskreg_ctx (up)
     535                 :        3646 :                  || (gimple_code (up->stmt) == GIMPLE_OMP_TARGET
     536                 :         465 :                      && is_gimple_omp_offloaded (up->stmt)))
     537                 :        6051 :                 && maybe_lookup_decl (decl, up))
     538                 :             :               break;
     539                 :             : 
     540                 :        2405 :           if (up)
     541                 :             :             {
     542                 :        2114 :               tree c;
     543                 :             : 
     544                 :        2114 :               if (gimple_code (up->stmt) == GIMPLE_OMP_TARGET)
     545                 :             :                 {
     546                 :         357 :                   for (c = gimple_omp_target_clauses (up->stmt);
     547                 :        2187 :                        c; c = OMP_CLAUSE_CHAIN (c))
     548                 :        2067 :                     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
     549                 :        2067 :                         && OMP_CLAUSE_DECL (c) == decl)
     550                 :             :                       break;
     551                 :             :                 }
     552                 :             :               else
     553                 :        1757 :                 for (c = gimple_omp_taskreg_clauses (up->stmt);
     554                 :        5661 :                      c; c = OMP_CLAUSE_CHAIN (c))
     555                 :        5450 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
     556                 :        5450 :                       && OMP_CLAUSE_DECL (c) == decl)
     557                 :             :                     break;
     558                 :             : 
     559                 :        2114 :               if (c)
     560                 :        1783 :                 goto maybe_mark_addressable_and_ret;
     561                 :             :             }
     562                 :             :         }
     563                 :             : 
     564                 :             :       /* For tasks avoid using copy-in/out.  As tasks can be
     565                 :             :          deferred or executed in different thread, when GOMP_task
     566                 :             :          returns, the task hasn't necessarily terminated.  */
     567                 :        9283 :       if (is_task_ctx (shared_ctx))
     568                 :             :         {
     569                 :        2226 :           tree outer;
     570                 :         443 :         maybe_mark_addressable_and_ret:
     571                 :        2226 :           outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
     572                 :        2226 :           if (is_gimple_reg (outer) && !omp_member_access_dummy_var (outer))
     573                 :             :             {
     574                 :             :               /* Taking address of OUTER in lower_send_shared_vars
     575                 :             :                  might need regimplification of everything that uses the
     576                 :             :                  variable.  */
     577                 :         939 :               if (!make_addressable_vars)
     578                 :         470 :                 make_addressable_vars = BITMAP_ALLOC (NULL);
     579                 :         939 :               bitmap_set_bit (make_addressable_vars, DECL_UID (outer));
     580                 :         939 :               TREE_ADDRESSABLE (outer) = 1;
     581                 :             :             }
     582                 :        2226 :           return true;
     583                 :             :         }
     584                 :             :     }
     585                 :             : 
     586                 :             :   return false;
     587                 :             : }
     588                 :             : 
     589                 :             : /* Construct a new automatic decl similar to VAR.  */
     590                 :             : 
     591                 :             : static tree
     592                 :      228315 : omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
     593                 :             : {
     594                 :      228315 :   tree copy = copy_var_decl (var, name, type);
     595                 :             : 
     596                 :      228315 :   DECL_CONTEXT (copy) = current_function_decl;
     597                 :             : 
     598                 :      228315 :   if (ctx)
     599                 :             :     {
     600                 :      228002 :       DECL_CHAIN (copy) = ctx->block_vars;
     601                 :      228002 :       ctx->block_vars = copy;
     602                 :             :     }
     603                 :             :   else
     604                 :         313 :     record_vars (copy);
     605                 :             : 
     606                 :             :   /* If VAR is listed in make_addressable_vars, it wasn't
     607                 :             :      originally addressable, but was only later made so.
     608                 :             :      We don't need to take address of privatizations
     609                 :             :      from that var.  */
     610                 :      228315 :   if (TREE_ADDRESSABLE (var)
     611                 :      228315 :       && ((make_addressable_vars
     612                 :        3662 :            && bitmap_bit_p (make_addressable_vars, DECL_UID (var)))
     613                 :       38365 :           || (global_nonaddressable_vars
     614                 :         574 :               && bitmap_bit_p (global_nonaddressable_vars, DECL_UID (var)))))
     615                 :        2154 :     TREE_ADDRESSABLE (copy) = 0;
     616                 :             : 
     617                 :      228315 :   return copy;
     618                 :             : }
     619                 :             : 
     620                 :             : static tree
     621                 :      228315 : omp_copy_decl_1 (tree var, omp_context *ctx)
     622                 :             : {
     623                 :      228315 :   return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
     624                 :             : }
     625                 :             : 
     626                 :             : /* Build tree nodes to access the field for VAR on the receiver side.  */
     627                 :             : 
     628                 :             : static tree
     629                 :      118991 : build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
     630                 :             : {
     631                 :      118991 :   tree x, field = lookup_field (var, ctx);
     632                 :             : 
     633                 :             :   /* If the receiver record type was remapped in the child function,
     634                 :             :      remap the field into the new record type.  */
     635                 :      118991 :   x = maybe_lookup_field (field, ctx);
     636                 :      118991 :   if (x != NULL)
     637                 :       10287 :     field = x;
     638                 :             : 
     639                 :      118991 :   x = build_simple_mem_ref (ctx->receiver_decl);
     640                 :      118991 :   TREE_THIS_NOTRAP (x) = 1;
     641                 :      118991 :   x = omp_build_component_ref (x, field);
     642                 :      118991 :   if (by_ref)
     643                 :             :     {
     644                 :       34419 :       x = build_simple_mem_ref (x);
     645                 :       34419 :       TREE_THIS_NOTRAP (x) = 1;
     646                 :             :     }
     647                 :             : 
     648                 :      118991 :   return x;
     649                 :             : }
     650                 :             : 
     651                 :             : /* Build tree nodes to access VAR in the scope outer to CTX.  In the case
     652                 :             :    of a parallel, this is a component reference; for workshare constructs
     653                 :             :    this is some variable.  */
     654                 :             : 
     655                 :             : static tree
     656                 :      115966 : build_outer_var_ref (tree var, omp_context *ctx,
     657                 :             :                      enum omp_clause_code code = OMP_CLAUSE_ERROR)
     658                 :             : {
     659                 :      115966 :   tree x;
     660                 :      115966 :   omp_context *outer = ctx->outer;
     661                 :      116361 :   for (; outer; outer = outer->outer)
     662                 :             :     {
     663                 :       84248 :       if (gimple_code (outer->stmt) == GIMPLE_OMP_TASKGROUP)
     664                 :         377 :         continue;
     665                 :       83889 :       if (gimple_code (outer->stmt) == GIMPLE_OMP_SCOPE
     666                 :       83871 :           && !maybe_lookup_decl (var, outer))
     667                 :          18 :         continue;
     668                 :             :       break;
     669                 :             :     }
     670                 :             : 
     671                 :      115966 :   if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
     672                 :             :     x = var;
     673                 :      107392 :   else if (is_variable_sized (var))
     674                 :             :     {
     675                 :          47 :       x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
     676                 :          47 :       x = build_outer_var_ref (x, ctx, code);
     677                 :          47 :       x = build_simple_mem_ref (x);
     678                 :             :     }
     679                 :      107345 :   else if (is_taskreg_ctx (ctx))
     680                 :             :     {
     681                 :       62573 :       bool by_ref = use_pointer_for_field (var, NULL);
     682                 :       62573 :       x = build_receiver_ref (var, by_ref, ctx);
     683                 :             :     }
     684                 :       44772 :   else if ((gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
     685                 :       43330 :             && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
     686                 :       14741 :            || ctx->loop_p
     687                 :       13858 :            || code == OMP_CLAUSE_ALLOCATE
     688                 :       58371 :            || (code == OMP_CLAUSE_PRIVATE
     689                 :          44 :                && (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
     690                 :             :                    || gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS
     691                 :             :                    || gimple_code (ctx->stmt) == GIMPLE_OMP_SINGLE)))
     692                 :             :     {
     693                 :             :       /* #pragma omp simd isn't a worksharing construct, and can reference
     694                 :             :          even private vars in its linear etc. clauses.
     695                 :             :          Similarly for OMP_CLAUSE_PRIVATE with outer ref, that can refer
     696                 :             :          to private vars in all worksharing constructs.  */
     697                 :       31192 :       x = NULL_TREE;
     698                 :       31192 :       if (outer && is_taskreg_ctx (outer))
     699                 :        1119 :         x = lookup_decl (var, outer);
     700                 :       30073 :       else if (outer)
     701                 :       23440 :         x = maybe_lookup_decl_in_outer_ctx (var, ctx);
     702                 :       24559 :       if (x == NULL_TREE)
     703                 :             :         x = var;
     704                 :             :     }
     705                 :       13580 :   else if (code == OMP_CLAUSE_LASTPRIVATE && is_taskloop_ctx (ctx))
     706                 :             :     {
     707                 :         749 :       gcc_assert (outer);
     708                 :         749 :       splay_tree_node n
     709                 :        1498 :         = splay_tree_lookup (outer->field_map,
     710                 :         749 :                              (splay_tree_key) &DECL_UID (var));
     711                 :         749 :       if (n == NULL)
     712                 :             :         {
     713                 :         666 :           if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, outer)))
     714                 :             :             x = var;
     715                 :             :           else
     716                 :         413 :             x = lookup_decl (var, outer);
     717                 :             :         }
     718                 :             :       else
     719                 :             :         {
     720                 :          83 :           tree field = (tree) n->value;
     721                 :             :           /* If the receiver record type was remapped in the child function,
     722                 :             :              remap the field into the new record type.  */
     723                 :          83 :           x = maybe_lookup_field (field, outer);
     724                 :          83 :           if (x != NULL)
     725                 :           0 :             field = x;
     726                 :             : 
     727                 :          83 :           x = build_simple_mem_ref (outer->receiver_decl);
     728                 :          83 :           x = omp_build_component_ref (x, field);
     729                 :          83 :           if (use_pointer_for_field (var, outer))
     730                 :          63 :             x = build_simple_mem_ref (x);
     731                 :             :         }
     732                 :             :     }
     733                 :       12831 :   else if (outer)
     734                 :       12609 :     x = lookup_decl (var, outer);
     735                 :         222 :   else if (omp_privatize_by_reference (var))
     736                 :             :     /* This can happen with orphaned constructs.  If var is reference, it is
     737                 :             :        possible it is shared and as such valid.  */
     738                 :             :     x = var;
     739                 :         124 :   else if (omp_member_access_dummy_var (var))
     740                 :             :     x = var;
     741                 :             :   else
     742                 :           0 :     gcc_unreachable ();
     743                 :             : 
     744                 :      115966 :   if (x == var)
     745                 :             :     {
     746                 :       17386 :       tree t = omp_member_access_dummy_var (var);
     747                 :       17386 :       if (t)
     748                 :             :         {
     749                 :         284 :           x = DECL_VALUE_EXPR (var);
     750                 :         284 :           tree o = maybe_lookup_decl_in_outer_ctx (t, ctx);
     751                 :         284 :           if (o != t)
     752                 :          72 :             x = unshare_and_remap (x, t, o);
     753                 :             :           else
     754                 :         212 :             x = unshare_expr (x);
     755                 :             :         }
     756                 :             :     }
     757                 :             : 
     758                 :      115966 :   if (omp_privatize_by_reference (var))
     759                 :        3583 :     x = build_simple_mem_ref (x);
     760                 :             : 
     761                 :      115966 :   return x;
     762                 :             : }
     763                 :             : 
     764                 :             : /* Build tree nodes to access the field for VAR on the sender side.  */
     765                 :             : 
     766                 :             : static tree
     767                 :      160672 : build_sender_ref (splay_tree_key key, omp_context *ctx)
     768                 :             : {
     769                 :      160672 :   tree field = lookup_sfield (key, ctx);
     770                 :      160672 :   return omp_build_component_ref (ctx->sender_decl, field);
     771                 :             : }
     772                 :             : 
     773                 :             : static tree
     774                 :      156504 : build_sender_ref (tree var, omp_context *ctx)
     775                 :             : {
     776                 :           0 :   return build_sender_ref ((splay_tree_key) var, ctx);
     777                 :             : }
     778                 :             : 
     779                 :             : /* Add a new field for VAR inside the structure CTX->SENDER_DECL.  If
     780                 :             :    BASE_POINTERS_RESTRICT, declare the field with restrict.  */
     781                 :             : 
     782                 :             : static void
     783                 :      127664 : install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
     784                 :             : {
     785                 :      127664 :   tree field, type, sfield = NULL_TREE;
     786                 :      127664 :   splay_tree_key key = (splay_tree_key) var;
     787                 :             : 
     788                 :      127664 :   if ((mask & 16) != 0)
     789                 :             :     {
     790                 :         618 :       key = (splay_tree_key) &DECL_NAME (var);
     791                 :         618 :       gcc_checking_assert (key != (splay_tree_key) var);
     792                 :             :     }
     793                 :      127664 :   if ((mask & 8) != 0)
     794                 :             :     {
     795                 :        1647 :       key = (splay_tree_key) &DECL_UID (var);
     796                 :        1647 :       gcc_checking_assert (key != (splay_tree_key) var);
     797                 :             :     }
     798                 :      127664 :   gcc_assert ((mask & 1) == 0
     799                 :             :               || !splay_tree_lookup (ctx->field_map, key));
     800                 :      127664 :   gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
     801                 :             :               || !splay_tree_lookup (ctx->sfield_map, key));
     802                 :      127664 :   gcc_assert ((mask & 3) == 3
     803                 :             :               || !is_gimple_omp_oacc (ctx->stmt));
     804                 :             : 
     805                 :      127664 :   type = TREE_TYPE (var);
     806                 :      127664 :   if ((mask & 16) != 0)
     807                 :         618 :     type = lang_hooks.decls.omp_array_data (var, true);
     808                 :             : 
     809                 :             :   /* Prevent redeclaring the var in the split-off function with a restrict
     810                 :             :      pointer type.  Note that we only clear type itself, restrict qualifiers in
     811                 :             :      the pointed-to type will be ignored by points-to analysis.  */
     812                 :      127664 :   if (POINTER_TYPE_P (type)
     813                 :      127664 :       && TYPE_RESTRICT (type))
     814                 :        6206 :     type = build_qualified_type (type, TYPE_QUALS (type) & ~TYPE_QUAL_RESTRICT);
     815                 :             : 
     816                 :      127664 :   if (mask & 4)
     817                 :             :     {
     818                 :         425 :       gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
     819                 :         425 :       type = build_pointer_type (build_pointer_type (type));
     820                 :             :     }
     821                 :      127239 :   else if (by_ref)
     822                 :       61840 :     type = build_pointer_type (type);
     823                 :       65399 :   else if ((mask & (32 | 3)) == 1
     824                 :       65399 :            && omp_privatize_by_reference (var))
     825                 :         207 :     type = TREE_TYPE (type);
     826                 :             : 
     827                 :      127664 :   field = build_decl (DECL_SOURCE_LOCATION (var),
     828                 :      127664 :                       FIELD_DECL, DECL_NAME (var), type);
     829                 :             : 
     830                 :             :   /* Remember what variable this field was created for.  This does have a
     831                 :             :      side effect of making dwarf2out ignore this member, so for helpful
     832                 :             :      debugging we clear it later in delete_omp_context.  */
     833                 :      127664 :   DECL_ABSTRACT_ORIGIN (field) = var;
     834                 :      127664 :   if ((mask & 16) == 0 && type == TREE_TYPE (var))
     835                 :             :     {
     836                 :       61463 :       SET_DECL_ALIGN (field, DECL_ALIGN (var));
     837                 :       61463 :       DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
     838                 :       61463 :       TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
     839                 :             :     }
     840                 :             :   else
     841                 :       66201 :     SET_DECL_ALIGN (field, TYPE_ALIGN (type));
     842                 :             : 
     843                 :      127664 :   if ((mask & 3) == 3)
     844                 :             :     {
     845                 :      126488 :       insert_field_into_struct (ctx->record_type, field);
     846                 :      126488 :       if (ctx->srecord_type)
     847                 :             :         {
     848                 :         949 :           sfield = build_decl (DECL_SOURCE_LOCATION (var),
     849                 :         949 :                                FIELD_DECL, DECL_NAME (var), type);
     850                 :         949 :           DECL_ABSTRACT_ORIGIN (sfield) = var;
     851                 :         949 :           SET_DECL_ALIGN (sfield, DECL_ALIGN (field));
     852                 :         949 :           DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
     853                 :         949 :           TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
     854                 :         949 :           insert_field_into_struct (ctx->srecord_type, sfield);
     855                 :             :         }
     856                 :             :     }
     857                 :             :   else
     858                 :             :     {
     859                 :        1176 :       if (ctx->srecord_type == NULL_TREE)
     860                 :             :         {
     861                 :         595 :           tree t;
     862                 :             : 
     863                 :         595 :           ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
     864                 :         595 :           ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
     865                 :        2156 :           for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
     866                 :             :             {
     867                 :        1561 :               sfield = build_decl (DECL_SOURCE_LOCATION (t),
     868                 :        1561 :                                    FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
     869                 :        1561 :               DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
     870                 :        1561 :               insert_field_into_struct (ctx->srecord_type, sfield);
     871                 :        3122 :               splay_tree_insert (ctx->sfield_map,
     872                 :        1561 :                                  (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
     873                 :             :                                  (splay_tree_value) sfield);
     874                 :             :             }
     875                 :             :         }
     876                 :        1176 :       sfield = field;
     877                 :        1176 :       insert_field_into_struct ((mask & 1) ? ctx->record_type
     878                 :             :                                 : ctx->srecord_type, field);
     879                 :             :     }
     880                 :             : 
     881                 :      127664 :   if (mask & 1)
     882                 :      127232 :     splay_tree_insert (ctx->field_map, key, (splay_tree_value) field);
     883                 :      127664 :   if ((mask & 2) && ctx->sfield_map)
     884                 :        1381 :     splay_tree_insert (ctx->sfield_map, key, (splay_tree_value) sfield);
     885                 :      127664 : }
     886                 :             : 
     887                 :             : static tree
     888                 :      227852 : install_var_local (tree var, omp_context *ctx)
     889                 :             : {
     890                 :      227852 :   tree new_var = omp_copy_decl_1 (var, ctx);
     891                 :      227852 :   insert_decl_map (&ctx->cb, var, new_var);
     892                 :      227852 :   return new_var;
     893                 :             : }
     894                 :             : 
     895                 :             : /* Adjust the replacement for DECL in CTX for the new context.  This means
     896                 :             :    copying the DECL_VALUE_EXPR, and fixing up the type.  */
     897                 :             : 
     898                 :             : static void
     899                 :      201990 : fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
     900                 :             : {
     901                 :      201990 :   tree new_decl, size;
     902                 :             : 
     903                 :      201990 :   new_decl = lookup_decl (decl, ctx);
     904                 :             : 
     905                 :      201990 :   TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
     906                 :             : 
     907                 :      402789 :   if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
     908                 :      202179 :       && DECL_HAS_VALUE_EXPR_P (decl))
     909                 :             :     {
     910                 :        1380 :       tree ve = DECL_VALUE_EXPR (decl);
     911                 :        1380 :       walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
     912                 :        1380 :       SET_DECL_VALUE_EXPR (new_decl, ve);
     913                 :        1380 :       DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
     914                 :             :     }
     915                 :             : 
     916                 :      201990 :   if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
     917                 :             :     {
     918                 :        1191 :       size = remap_decl (DECL_SIZE (decl), &ctx->cb);
     919                 :        1191 :       if (size == error_mark_node)
     920                 :         322 :         size = TYPE_SIZE (TREE_TYPE (new_decl));
     921                 :        1191 :       DECL_SIZE (new_decl) = size;
     922                 :             : 
     923                 :        1191 :       size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
     924                 :        1191 :       if (size == error_mark_node)
     925                 :         309 :         size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
     926                 :        1191 :       DECL_SIZE_UNIT (new_decl) = size;
     927                 :             :     }
     928                 :      201990 : }
     929                 :             : 
     930                 :             : /* The callback for remap_decl.  Search all containing contexts for a
     931                 :             :    mapping of the variable; this avoids having to duplicate the splay
     932                 :             :    tree ahead of time.  We know a mapping doesn't already exist in the
     933                 :             :    given context.  Create new mappings to implement default semantics.  */
     934                 :             : 
     935                 :             : static tree
     936                 :      434708 : omp_copy_decl (tree var, copy_body_data *cb)
     937                 :             : {
     938                 :      434708 :   omp_context *ctx = (omp_context *) cb;
     939                 :      434708 :   tree new_var;
     940                 :             : 
     941                 :      434708 :   if (TREE_CODE (var) == LABEL_DECL)
     942                 :             :     {
     943                 :      171477 :       if (FORCED_LABEL (var) || DECL_NONLOCAL (var))
     944                 :             :         return var;
     945                 :      171471 :       new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
     946                 :      171471 :       DECL_CONTEXT (new_var) = current_function_decl;
     947                 :      171471 :       insert_decl_map (&ctx->cb, var, new_var);
     948                 :      171471 :       return new_var;
     949                 :             :     }
     950                 :             : 
     951                 :      347052 :   while (!is_taskreg_ctx (ctx))
     952                 :             :     {
     953                 :      328362 :       ctx = ctx->outer;
     954                 :      328362 :       if (ctx == NULL)
     955                 :             :         return var;
     956                 :      272035 :       new_var = maybe_lookup_decl (var, ctx);
     957                 :      272035 :       if (new_var)
     958                 :      188214 :         return new_var;
     959                 :             :     }
     960                 :             : 
     961                 :       18690 :   if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
     962                 :       13461 :     return var;
     963                 :             : 
     964                 :        5229 :   return error_mark_node;
     965                 :             : }
     966                 :             : 
     967                 :             : /* Create a new context, with OUTER_CTX being the surrounding context.  */
     968                 :             : 
     969                 :             : static omp_context *
     970                 :      137324 : new_omp_context (gimple *stmt, omp_context *outer_ctx)
     971                 :             : {
     972                 :      137324 :   omp_context *ctx = XCNEW (omp_context);
     973                 :             : 
     974                 :      137324 :   splay_tree_insert (all_contexts, (splay_tree_key) stmt,
     975                 :             :                      (splay_tree_value) ctx);
     976                 :      137324 :   ctx->stmt = stmt;
     977                 :             : 
     978                 :      137324 :   if (outer_ctx)
     979                 :             :     {
     980                 :       75358 :       ctx->outer = outer_ctx;
     981                 :       75358 :       ctx->cb = outer_ctx->cb;
     982                 :       75358 :       ctx->cb.block = NULL;
     983                 :       75358 :       ctx->depth = outer_ctx->depth + 1;
     984                 :             :     }
     985                 :             :   else
     986                 :             :     {
     987                 :       61966 :       ctx->cb.src_fn = current_function_decl;
     988                 :       61966 :       ctx->cb.dst_fn = current_function_decl;
     989                 :       61966 :       ctx->cb.src_node = cgraph_node::get (current_function_decl);
     990                 :       61966 :       gcc_checking_assert (ctx->cb.src_node);
     991                 :       61966 :       ctx->cb.dst_node = ctx->cb.src_node;
     992                 :       61966 :       ctx->cb.src_cfun = cfun;
     993                 :       61966 :       ctx->cb.copy_decl = omp_copy_decl;
     994                 :       61966 :       ctx->cb.eh_lp_nr = 0;
     995                 :       61966 :       ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
     996                 :       61966 :       ctx->cb.adjust_array_error_bounds = true;
     997                 :       61966 :       ctx->cb.dont_remap_vla_if_no_change = true;
     998                 :       61966 :       ctx->depth = 1;
     999                 :             :     }
    1000                 :             : 
    1001                 :      137324 :   ctx->cb.decl_map = new hash_map<tree, tree>;
    1002                 :             : 
    1003                 :      137324 :   return ctx;
    1004                 :             : }
    1005                 :             : 
    1006                 :             : static gimple_seq maybe_catch_exception (gimple_seq);
    1007                 :             : 
    1008                 :             : /* Finalize task copyfn.  */
    1009                 :             : 
    1010                 :             : static void
    1011                 :         549 : finalize_task_copyfn (gomp_task *task_stmt)
    1012                 :             : {
    1013                 :         549 :   struct function *child_cfun;
    1014                 :         549 :   tree child_fn;
    1015                 :         549 :   gimple_seq seq = NULL, new_seq;
    1016                 :         549 :   gbind *bind;
    1017                 :             : 
    1018                 :         549 :   child_fn = gimple_omp_task_copy_fn (task_stmt);
    1019                 :         549 :   if (child_fn == NULL_TREE)
    1020                 :           0 :     return;
    1021                 :             : 
    1022                 :         549 :   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
    1023                 :         549 :   DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
    1024                 :             : 
    1025                 :         549 :   push_cfun (child_cfun);
    1026                 :         549 :   bind = gimplify_body (child_fn, false);
    1027                 :         549 :   gimple_seq_add_stmt (&seq, bind);
    1028                 :         549 :   new_seq = maybe_catch_exception (seq);
    1029                 :         549 :   if (new_seq != seq)
    1030                 :             :     {
    1031                 :         384 :       bind = gimple_build_bind (NULL, new_seq, NULL);
    1032                 :         384 :       seq = NULL;
    1033                 :         384 :       gimple_seq_add_stmt (&seq, bind);
    1034                 :             :     }
    1035                 :         549 :   gimple_set_body (child_fn, seq);
    1036                 :         549 :   pop_cfun ();
    1037                 :             : 
    1038                 :             :   /* Inform the callgraph about the new function.  */
    1039                 :         549 :   cgraph_node *node = cgraph_node::get_create (child_fn);
    1040                 :         549 :   node->parallelized_function = 1;
    1041                 :         549 :   cgraph_node::add_new_function (child_fn, false);
    1042                 :             : }
    1043                 :             : 
    1044                 :             : /* Destroy a omp_context data structures.  Called through the splay tree
    1045                 :             :    value delete callback.  */
    1046                 :             : 
    1047                 :             : static void
    1048                 :      137318 : delete_omp_context (splay_tree_value value)
    1049                 :             : {
    1050                 :      137318 :   omp_context *ctx = (omp_context *) value;
    1051                 :             : 
    1052                 :      274636 :   delete ctx->cb.decl_map;
    1053                 :             : 
    1054                 :      137318 :   if (ctx->field_map)
    1055                 :       68689 :     splay_tree_delete (ctx->field_map);
    1056                 :      137318 :   if (ctx->sfield_map)
    1057                 :         595 :     splay_tree_delete (ctx->sfield_map);
    1058                 :             : 
    1059                 :             :   /* We hijacked DECL_ABSTRACT_ORIGIN earlier.  We need to clear it before
    1060                 :             :      it produces corrupt debug information.  */
    1061                 :      137318 :   if (ctx->record_type)
    1062                 :             :     {
    1063                 :       52266 :       tree t;
    1064                 :      214692 :       for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
    1065                 :      162426 :         DECL_ABSTRACT_ORIGIN (t) = NULL;
    1066                 :             :     }
    1067                 :      137318 :   if (ctx->srecord_type)
    1068                 :             :     {
    1069                 :         595 :       tree t;
    1070                 :        3537 :       for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = DECL_CHAIN (t))
    1071                 :        2942 :         DECL_ABSTRACT_ORIGIN (t) = NULL;
    1072                 :             :     }
    1073                 :             : 
    1074                 :      137318 :   if (ctx->task_reduction_map)
    1075                 :             :     {
    1076                 :        1267 :       ctx->task_reductions.release ();
    1077                 :        2534 :       delete ctx->task_reduction_map;
    1078                 :             :     }
    1079                 :             : 
    1080                 :      137601 :   delete ctx->lastprivate_conditional_map;
    1081                 :      138949 :   delete ctx->allocate_map;
    1082                 :             : 
    1083                 :      137318 :   XDELETE (ctx);
    1084                 :      137318 : }
    1085                 :             : 
    1086                 :             : /* Fix up RECEIVER_DECL with a type that has been remapped to the child
    1087                 :             :    context.  */
    1088                 :             : 
    1089                 :             : static void
    1090                 :       35812 : fixup_child_record_type (omp_context *ctx)
    1091                 :             : {
    1092                 :       35812 :   tree f, type = ctx->record_type;
    1093                 :             : 
    1094                 :       35812 :   if (!ctx->receiver_decl)
    1095                 :             :     return;
    1096                 :             :   /* ??? It isn't sufficient to just call remap_type here, because
    1097                 :             :      variably_modified_type_p doesn't work the way we expect for
    1098                 :             :      record types.  Testing each field for whether it needs remapping
    1099                 :             :      and creating a new record by hand works, however.  */
    1100                 :      156780 :   for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
    1101                 :      122075 :     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
    1102                 :             :       break;
    1103                 :       35812 :   if (f)
    1104                 :             :     {
    1105                 :        1107 :       tree name, new_fields = NULL;
    1106                 :             : 
    1107                 :        1107 :       type = lang_hooks.types.make_type (RECORD_TYPE);
    1108                 :        1107 :       name = DECL_NAME (TYPE_NAME (ctx->record_type));
    1109                 :        1107 :       name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
    1110                 :             :                          TYPE_DECL, name, type);
    1111                 :        1107 :       TYPE_NAME (type) = name;
    1112                 :             : 
    1113                 :       12268 :       for (f = TYPE_FIELDS (ctx->record_type); f ; f = DECL_CHAIN (f))
    1114                 :             :         {
    1115                 :       11161 :           tree new_f = copy_node (f);
    1116                 :       11161 :           DECL_CONTEXT (new_f) = type;
    1117                 :       11161 :           TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
    1118                 :       11161 :           DECL_CHAIN (new_f) = new_fields;
    1119                 :       11161 :           walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
    1120                 :       11161 :           walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
    1121                 :             :                      &ctx->cb, NULL);
    1122                 :       11161 :           walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
    1123                 :             :                      &ctx->cb, NULL);
    1124                 :       11161 :           new_fields = new_f;
    1125                 :             : 
    1126                 :             :           /* Arrange to be able to look up the receiver field
    1127                 :             :              given the sender field.  */
    1128                 :       11161 :           splay_tree_insert (ctx->field_map, (splay_tree_key) f,
    1129                 :             :                              (splay_tree_value) new_f);
    1130                 :             :         }
    1131                 :        1107 :       TYPE_FIELDS (type) = nreverse (new_fields);
    1132                 :        1107 :       layout_type (type);
    1133                 :             :     }
    1134                 :             : 
    1135                 :             :   /* In a target region we never modify any of the pointers in *.omp_data_i,
    1136                 :             :      so attempt to help the optimizers.  */
    1137                 :       35812 :   if (is_gimple_omp_offloaded (ctx->stmt))
    1138                 :       16412 :     type = build_qualified_type (type, TYPE_QUAL_CONST);
    1139                 :             : 
    1140                 :       35812 :   TREE_TYPE (ctx->receiver_decl)
    1141                 :       71624 :     = build_qualified_type (build_reference_type (type), TYPE_QUAL_RESTRICT);
    1142                 :             : }
    1143                 :             : 
    1144                 :             : /* Instantiate decls as necessary in CTX to satisfy the data sharing
    1145                 :             :    specified by CLAUSES.  */
    1146                 :             : 
    1147                 :             : static void
    1148                 :      130365 : scan_sharing_clauses (tree clauses, omp_context *ctx)
    1149                 :             : {
    1150                 :      130365 :   tree c, decl;
    1151                 :      130365 :   bool scan_array_reductions = false;
    1152                 :             : 
    1153                 :      547952 :   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    1154                 :      417587 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE
    1155                 :      417587 :         && (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
    1156                 :             :             /* omp_default_mem_alloc is 1 */
    1157                 :        1261 :             || !integer_onep (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
    1158                 :         653 :             || OMP_CLAUSE_ALLOCATE_ALIGN (c) != NULL_TREE))
    1159                 :             :       {
    1160                 :             :         /* The allocate clauses that appear on a target construct or on
    1161                 :             :            constructs in a target region must specify an allocator expression
    1162                 :             :            unless a requires directive with the dynamic_allocators clause
    1163                 :             :            is present in the same compilation unit.  */
    1164                 :        2087 :         if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
    1165                 :        1429 :             && ((omp_requires_mask & OMP_REQUIRES_DYNAMIC_ALLOCATORS) == 0)
    1166                 :        3501 :             && omp_maybe_offloaded_ctx (ctx))
    1167                 :          12 :           error_at (OMP_CLAUSE_LOCATION (c), "%<allocate%> clause must"
    1168                 :             :                     " specify an allocator here");
    1169                 :        2087 :         if (ctx->allocate_map == NULL)
    1170                 :        1631 :           ctx->allocate_map = new hash_map<tree, tree>;
    1171                 :        2087 :         tree val = integer_zero_node;
    1172                 :        2087 :         if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
    1173                 :         658 :           val = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
    1174                 :        2087 :         if (OMP_CLAUSE_ALLOCATE_ALIGN (c))
    1175                 :         218 :           val = build_tree_list (val, OMP_CLAUSE_ALLOCATE_ALIGN (c));
    1176                 :        2087 :         ctx->allocate_map->put (OMP_CLAUSE_DECL (c), val);
    1177                 :             :       }
    1178                 :             : 
    1179                 :      547952 :   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    1180                 :             :     {
    1181                 :      417587 :       bool by_ref;
    1182                 :             : 
    1183                 :      417587 :       switch (OMP_CLAUSE_CODE (c))
    1184                 :             :         {
    1185                 :       73544 :         case OMP_CLAUSE_PRIVATE:
    1186                 :       73544 :           decl = OMP_CLAUSE_DECL (c);
    1187                 :       73544 :           if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
    1188                 :         163 :             goto do_private;
    1189                 :       73381 :           else if (!is_variable_sized (decl))
    1190                 :       72987 :             install_var_local (decl, ctx);
    1191                 :             :           break;
    1192                 :             : 
    1193                 :       45225 :         case OMP_CLAUSE_SHARED:
    1194                 :       45225 :           decl = OMP_CLAUSE_DECL (c);
    1195                 :       45225 :           if (ctx->allocate_map && ctx->allocate_map->get (decl))
    1196                 :          39 :             ctx->allocate_map->remove (decl);
    1197                 :             :           /* Ignore shared directives in teams construct inside of
    1198                 :             :              target construct.  */
    1199                 :       45225 :           if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
    1200                 :       45225 :               && !is_host_teams_ctx (ctx))
    1201                 :             :             {
    1202                 :             :               /* Global variables don't need to be copied,
    1203                 :             :                  the receiver side will use them directly.  */
    1204                 :       11875 :               tree odecl = maybe_lookup_decl_in_outer_ctx (decl, ctx);
    1205                 :       11875 :               if (is_global_var (odecl))
    1206                 :             :                 break;
    1207                 :        8094 :               insert_decl_map (&ctx->cb, decl, odecl);
    1208                 :        8094 :               break;
    1209                 :             :             }
    1210                 :       33350 :           gcc_assert (is_taskreg_ctx (ctx));
    1211                 :       33350 :           gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
    1212                 :             :                       || !is_variable_sized (decl));
    1213                 :             :           /* Global variables don't need to be copied,
    1214                 :             :              the receiver side will use them directly.  */
    1215                 :       33350 :           if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
    1216                 :             :             break;
    1217                 :       27175 :           if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
    1218                 :             :             {
    1219                 :          90 :               use_pointer_for_field (decl, ctx);
    1220                 :          90 :               break;
    1221                 :             :             }
    1222                 :       27085 :           by_ref = use_pointer_for_field (decl, NULL);
    1223                 :       52055 :           if ((! TREE_READONLY (decl) && !OMP_CLAUSE_SHARED_READONLY (c))
    1224                 :       17746 :               || TREE_ADDRESSABLE (decl)
    1225                 :       17454 :               || by_ref
    1226                 :       44539 :               || omp_privatize_by_reference (decl))
    1227                 :             :             {
    1228                 :       11459 :               by_ref = use_pointer_for_field (decl, ctx);
    1229                 :       11459 :               install_var_field (decl, by_ref, 3, ctx);
    1230                 :       11459 :               install_var_local (decl, ctx);
    1231                 :       11459 :               break;
    1232                 :             :             }
    1233                 :             :           /* We don't need to copy const scalar vars back.  */
    1234                 :       15626 :           OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
    1235                 :       15626 :           goto do_private;
    1236                 :             : 
    1237                 :       14452 :         case OMP_CLAUSE_REDUCTION:
    1238                 :             :           /* Collect 'reduction' clauses on OpenACC compute construct.  */
    1239                 :       14452 :           if (is_gimple_omp_oacc (ctx->stmt)
    1240                 :       14452 :               && is_gimple_omp_offloaded (ctx->stmt))
    1241                 :             :             {
    1242                 :             :               /* No 'reduction' clauses on OpenACC 'kernels'.  */
    1243                 :         536 :               gcc_checking_assert (!is_oacc_kernels (ctx));
    1244                 :             :               /* Likewise, on OpenACC 'kernels' decomposed parts.  */
    1245                 :         536 :               gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));
    1246                 :             : 
    1247                 :         536 :               ctx->local_reduction_clauses
    1248                 :         536 :                 = tree_cons (NULL, c, ctx->local_reduction_clauses);
    1249                 :             :             }
    1250                 :             :           /* FALLTHRU */
    1251                 :             : 
    1252                 :       16583 :         case OMP_CLAUSE_IN_REDUCTION:
    1253                 :       16583 :           decl = OMP_CLAUSE_DECL (c);
    1254                 :       16583 :           if (ctx->allocate_map
    1255                 :       16583 :               && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    1256                 :         589 :                    && (OMP_CLAUSE_REDUCTION_INSCAN (c)
    1257                 :         589 :                        || OMP_CLAUSE_REDUCTION_TASK (c)))
    1258                 :         599 :                   || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
    1259                 :         589 :                   || is_task_ctx (ctx)))
    1260                 :             :             {
    1261                 :             :               /* For now.  */
    1262                 :          21 :               if (ctx->allocate_map->get (decl))
    1263                 :          21 :                 ctx->allocate_map->remove (decl);
    1264                 :             :             }
    1265                 :       16583 :           if (TREE_CODE (decl) == MEM_REF)
    1266                 :             :             {
    1267                 :        2675 :               tree t = TREE_OPERAND (decl, 0);
    1268                 :        2675 :               if (TREE_CODE (t) == POINTER_PLUS_EXPR)
    1269                 :         442 :                 t = TREE_OPERAND (t, 0);
    1270                 :        2675 :               if (INDIRECT_REF_P (t)
    1271                 :        2495 :                   || TREE_CODE (t) == ADDR_EXPR)
    1272                 :        1410 :                 t = TREE_OPERAND (t, 0);
    1273                 :        2675 :               if (is_omp_target (ctx->stmt))
    1274                 :             :                 {
    1275                 :          96 :                   if (is_variable_sized (t))
    1276                 :             :                     {
    1277                 :          32 :                       gcc_assert (DECL_HAS_VALUE_EXPR_P (t));
    1278                 :          32 :                       t = DECL_VALUE_EXPR (t);
    1279                 :          32 :                       gcc_assert (INDIRECT_REF_P (t));
    1280                 :          32 :                       t = TREE_OPERAND (t, 0);
    1281                 :          32 :                       gcc_assert (DECL_P (t));
    1282                 :             :                     }
    1283                 :          96 :                   tree at = t;
    1284                 :          96 :                   if (ctx->outer)
    1285                 :          96 :                     scan_omp_op (&at, ctx->outer);
    1286                 :          96 :                   tree nt = omp_copy_decl_1 (at, ctx->outer);
    1287                 :         192 :                   splay_tree_insert (ctx->field_map,
    1288                 :          96 :                                      (splay_tree_key) &DECL_CONTEXT (t),
    1289                 :             :                                      (splay_tree_value) nt);
    1290                 :          96 :                   if (at != t)
    1291                 :          96 :                     splay_tree_insert (ctx->field_map,
    1292                 :          48 :                                        (splay_tree_key) &DECL_CONTEXT (at),
    1293                 :             :                                        (splay_tree_value) nt);
    1294                 :          96 :                   break;
    1295                 :             :                 }
    1296                 :        2579 :               install_var_local (t, ctx);
    1297                 :        2579 :               if (is_taskreg_ctx (ctx)
    1298                 :        2047 :                   && (!is_global_var (maybe_lookup_decl_in_outer_ctx (t, ctx))
    1299                 :         397 :                       || (is_task_ctx (ctx)
    1300                 :         316 :                           && (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
    1301                 :         257 :                               || (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE
    1302                 :          90 :                                   && (TREE_CODE (TREE_TYPE (TREE_TYPE (t)))
    1303                 :             :                                       == POINTER_TYPE)))))
    1304                 :        1729 :                   && !is_variable_sized (t)
    1305                 :        4247 :                   && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
    1306                 :         831 :                       || (!OMP_CLAUSE_REDUCTION_TASK (c)
    1307                 :         792 :                           && !is_task_ctx (ctx))))
    1308                 :             :                 {
    1309                 :        1544 :                   by_ref = use_pointer_for_field (t, NULL);
    1310                 :        1544 :                   if (is_task_ctx (ctx)
    1311                 :         837 :                       && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE
    1312                 :        1821 :                       && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) == POINTER_TYPE)
    1313                 :             :                     {
    1314                 :          72 :                       install_var_field (t, false, 1, ctx);
    1315                 :          72 :                       install_var_field (t, by_ref, 2, ctx);
    1316                 :             :                     }
    1317                 :             :                   else
    1318                 :        1472 :                     install_var_field (t, by_ref, 3, ctx);
    1319                 :             :                 }
    1320                 :             :               break;
    1321                 :             :             }
    1322                 :       13908 :           if (is_omp_target (ctx->stmt))
    1323                 :             :             {
    1324                 :         367 :               tree at = decl;
    1325                 :         367 :               if (ctx->outer)
    1326                 :          54 :                 scan_omp_op (&at, ctx->outer);
    1327                 :         367 :               tree nt = omp_copy_decl_1 (at, ctx->outer);
    1328                 :         734 :               splay_tree_insert (ctx->field_map,
    1329                 :         367 :                                  (splay_tree_key) &DECL_CONTEXT (decl),
    1330                 :             :                                  (splay_tree_value) nt);
    1331                 :         367 :               if (at != decl)
    1332                 :          24 :                 splay_tree_insert (ctx->field_map,
    1333                 :          12 :                                    (splay_tree_key) &DECL_CONTEXT (at),
    1334                 :             :                                    (splay_tree_value) nt);
    1335                 :         367 :               break;
    1336                 :             :             }
    1337                 :       13541 :           if (is_task_ctx (ctx)
    1338                 :       25933 :               || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    1339                 :       12392 :                   && OMP_CLAUSE_REDUCTION_TASK (c)
    1340                 :         388 :                   && is_parallel_ctx (ctx)))
    1341                 :             :             {
    1342                 :             :               /* Global variables don't need to be copied,
    1343                 :             :                  the receiver side will use them directly.  */
    1344                 :        1234 :               if (!is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
    1345                 :             :                 {
    1346                 :         487 :                   by_ref = use_pointer_for_field (decl, ctx);
    1347                 :         487 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
    1348                 :         310 :                     install_var_field (decl, by_ref, 3, ctx);
    1349                 :             :                 }
    1350                 :        1234 :               install_var_local (decl, ctx);
    1351                 :        1234 :               break;
    1352                 :             :             }
    1353                 :       12307 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    1354                 :       12307 :               && OMP_CLAUSE_REDUCTION_TASK (c))
    1355                 :             :             {
    1356                 :         303 :               install_var_local (decl, ctx);
    1357                 :         303 :               break;
    1358                 :             :             }
    1359                 :       12004 :           goto do_private;
    1360                 :             : 
    1361                 :       23682 :         case OMP_CLAUSE_LASTPRIVATE:
    1362                 :             :           /* Let the corresponding firstprivate clause create
    1363                 :             :              the variable.  */
    1364                 :       23682 :           if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
    1365                 :             :             break;
    1366                 :             :           /* FALLTHRU */
    1367                 :             : 
    1368                 :       60108 :         case OMP_CLAUSE_FIRSTPRIVATE:
    1369                 :       60108 :         case OMP_CLAUSE_LINEAR:
    1370                 :       60108 :           decl = OMP_CLAUSE_DECL (c);
    1371                 :       88217 :         do_private:
    1372                 :       88217 :           if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
    1373                 :             :                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR
    1374                 :             :                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
    1375                 :       43599 :               && is_gimple_omp_offloaded (ctx->stmt))
    1376                 :             :             {
    1377                 :       15664 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
    1378                 :       15664 :                   || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR
    1379                 :         227 :                       && lang_hooks.decls.omp_array_data (decl, true)))
    1380                 :             :                 {
    1381                 :       15361 :                   by_ref = !omp_privatize_by_reference (decl);
    1382                 :       15361 :                   install_var_field (decl, by_ref, 3, ctx);
    1383                 :             :                 }
    1384                 :         303 :               else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
    1385                 :             :                 {
    1386                 :         214 :                   if (INDIRECT_REF_P (decl))
    1387                 :           0 :                     decl = TREE_OPERAND (decl, 0);
    1388                 :         214 :                   install_var_field (decl, true, 3, ctx);
    1389                 :             :                 }
    1390                 :          89 :               else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    1391                 :           8 :                   install_var_field (decl, true, 3, ctx);
    1392                 :             :               else
    1393                 :          81 :                 install_var_field (decl, false, 3, ctx);
    1394                 :             :             }
    1395                 :       88217 :           if (is_variable_sized (decl))
    1396                 :             :             {
    1397                 :          58 :               if (is_task_ctx (ctx))
    1398                 :             :                 {
    1399                 :          14 :                   if (ctx->allocate_map
    1400                 :          14 :                       && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
    1401                 :             :                     {
    1402                 :             :                       /* For now.  */
    1403                 :           0 :                       if (ctx->allocate_map->get (decl))
    1404                 :           0 :                         ctx->allocate_map->remove (decl);
    1405                 :             :                     }
    1406                 :          14 :                   install_var_field (decl, false, 1, ctx);
    1407                 :             :                 }
    1408                 :             :               break;
    1409                 :             :             }
    1410                 :       88159 :           else if (is_taskreg_ctx (ctx))
    1411                 :             :             {
    1412                 :       36822 :               bool global
    1413                 :       36822 :                 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
    1414                 :       36822 :               by_ref = use_pointer_for_field (decl, NULL);
    1415                 :             : 
    1416                 :       36822 :               if (is_task_ctx (ctx)
    1417                 :       36822 :                   && (global || by_ref || omp_privatize_by_reference (decl)))
    1418                 :             :                 {
    1419                 :         658 :                   if (ctx->allocate_map
    1420                 :         658 :                       && ctx->allocate_map->get (decl))
    1421                 :          44 :                     install_var_field (decl, by_ref, 32 | 1, ctx);
    1422                 :             :                   else
    1423                 :         614 :                     install_var_field (decl, false, 1, ctx);
    1424                 :         658 :                   if (!global)
    1425                 :         360 :                     install_var_field (decl, by_ref, 2, ctx);
    1426                 :             :                 }
    1427                 :       36164 :               else if (!global)
    1428                 :       34771 :                 install_var_field (decl, by_ref, 3, ctx);
    1429                 :             :             }
    1430                 :       88159 :           install_var_local (decl, ctx);
    1431                 :             :           /* For descr arrays on target: firstprivatize data + attach ptr.  */
    1432                 :       88159 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
    1433                 :       43238 :               && is_gimple_omp_offloaded (ctx->stmt)
    1434                 :       15344 :               && !is_gimple_omp_oacc (ctx->stmt)
    1435                 :       99374 :               && lang_hooks.decls.omp_array_data (decl, true))
    1436                 :             :             {
    1437                 :          18 :               install_var_field (decl, false, 16 | 3, ctx);
    1438                 :          18 :               install_var_field (decl, true, 8 | 3, ctx);
    1439                 :             :             }
    1440                 :             :           break;
    1441                 :             : 
    1442                 :        2146 :         case OMP_CLAUSE_USE_DEVICE_PTR:
    1443                 :        2146 :         case OMP_CLAUSE_USE_DEVICE_ADDR:
    1444                 :        2146 :           decl = OMP_CLAUSE_DECL (c);
    1445                 :             : 
    1446                 :             :           /* Fortran array descriptors.  */
    1447                 :        2146 :           if (lang_hooks.decls.omp_array_data (decl, true))
    1448                 :         600 :             install_var_field (decl, false, 19, ctx);
    1449                 :        1546 :           else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
    1450                 :        1325 :                     && !omp_privatize_by_reference (decl)
    1451                 :         526 :                     && !omp_is_allocatable_or_ptr (decl))
    1452                 :        2483 :                    || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    1453                 :         428 :             install_var_field (decl, true, 11, ctx);
    1454                 :             :           else
    1455                 :        1118 :             install_var_field (decl, false, 11, ctx);
    1456                 :        2146 :           if (DECL_SIZE (decl)
    1457                 :        2146 :               && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
    1458                 :             :             {
    1459                 :           6 :               tree decl2 = DECL_VALUE_EXPR (decl);
    1460                 :           6 :               gcc_assert (INDIRECT_REF_P (decl2));
    1461                 :           6 :               decl2 = TREE_OPERAND (decl2, 0);
    1462                 :           6 :               gcc_assert (DECL_P (decl2));
    1463                 :           6 :               install_var_local (decl2, ctx);
    1464                 :             :             }
    1465                 :        2146 :           install_var_local (decl, ctx);
    1466                 :        2146 :           break;
    1467                 :             : 
    1468                 :         227 :         case OMP_CLAUSE_HAS_DEVICE_ADDR:
    1469                 :         227 :           decl = OMP_CLAUSE_DECL (c);
    1470                 :         227 :           while (INDIRECT_REF_P (decl)
    1471                 :         244 :                  || TREE_CODE (decl) == ARRAY_REF)
    1472                 :          17 :             decl = TREE_OPERAND (decl, 0);
    1473                 :         227 :           goto do_private;
    1474                 :             : 
    1475                 :          89 :         case OMP_CLAUSE_IS_DEVICE_PTR:
    1476                 :          89 :           decl = OMP_CLAUSE_DECL (c);
    1477                 :          89 :           goto do_private;
    1478                 :             : 
    1479                 :       20628 :         case OMP_CLAUSE__LOOPTEMP_:
    1480                 :       20628 :         case OMP_CLAUSE__REDUCTEMP_:
    1481                 :       20628 :           gcc_assert (is_taskreg_ctx (ctx));
    1482                 :       20628 :           decl = OMP_CLAUSE_DECL (c);
    1483                 :       20628 :           install_var_field (decl, false, 3, ctx);
    1484                 :       20628 :           install_var_local (decl, ctx);
    1485                 :       20628 :           break;
    1486                 :             : 
    1487                 :         946 :         case OMP_CLAUSE_COPYPRIVATE:
    1488                 :         946 :         case OMP_CLAUSE_COPYIN:
    1489                 :         946 :           decl = OMP_CLAUSE_DECL (c);
    1490                 :         946 :           by_ref = use_pointer_for_field (decl, NULL);
    1491                 :         946 :           install_var_field (decl, by_ref, 3, ctx);
    1492                 :         946 :           break;
    1493                 :             : 
    1494                 :       54533 :         case OMP_CLAUSE_FINAL:
    1495                 :       54533 :         case OMP_CLAUSE_IF:
    1496                 :       54533 :         case OMP_CLAUSE_SELF:
    1497                 :       54533 :         case OMP_CLAUSE_NUM_THREADS:
    1498                 :       54533 :         case OMP_CLAUSE_NUM_TEAMS:
    1499                 :       54533 :         case OMP_CLAUSE_THREAD_LIMIT:
    1500                 :       54533 :         case OMP_CLAUSE_DEVICE:
    1501                 :       54533 :         case OMP_CLAUSE_SCHEDULE:
    1502                 :       54533 :         case OMP_CLAUSE_DIST_SCHEDULE:
    1503                 :       54533 :         case OMP_CLAUSE_DEPEND:
    1504                 :       54533 :         case OMP_CLAUSE_PRIORITY:
    1505                 :       54533 :         case OMP_CLAUSE_GRAINSIZE:
    1506                 :       54533 :         case OMP_CLAUSE_NUM_TASKS:
    1507                 :       54533 :         case OMP_CLAUSE_NUM_GANGS:
    1508                 :       54533 :         case OMP_CLAUSE_NUM_WORKERS:
    1509                 :       54533 :         case OMP_CLAUSE_VECTOR_LENGTH:
    1510                 :       54533 :         case OMP_CLAUSE_DETACH:
    1511                 :       54533 :         case OMP_CLAUSE_FILTER:
    1512                 :       54533 :           if (ctx->outer)
    1513                 :       18402 :             scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
    1514                 :             :           break;
    1515                 :             : 
    1516                 :       83960 :         case OMP_CLAUSE_TO:
    1517                 :       83960 :         case OMP_CLAUSE_FROM:
    1518                 :       83960 :         case OMP_CLAUSE_MAP:
    1519                 :       83960 :           if (ctx->outer)
    1520                 :       15663 :             scan_omp_op (&OMP_CLAUSE_SIZE (c), ctx->outer);
    1521                 :       83960 :           decl = OMP_CLAUSE_DECL (c);
    1522                 :             :           /* If requested, make 'decl' addressable.  */
    1523                 :       83960 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
    1524                 :       83960 :               && OMP_CLAUSE_MAP_DECL_MAKE_ADDRESSABLE (c))
    1525                 :             :             {
    1526                 :         497 :               gcc_checking_assert (DECL_P (decl));
    1527                 :             : 
    1528                 :         497 :               bool decl_addressable = TREE_ADDRESSABLE (decl);
    1529                 :         497 :               if (!decl_addressable)
    1530                 :             :                 {
    1531                 :         271 :                   if (!make_addressable_vars)
    1532                 :         162 :                     make_addressable_vars = BITMAP_ALLOC (NULL);
    1533                 :         271 :                   bitmap_set_bit (make_addressable_vars, DECL_UID (decl));
    1534                 :         271 :                   TREE_ADDRESSABLE (decl) = 1;
    1535                 :             :                 }
    1536                 :             : 
    1537                 :         497 :               if (dump_enabled_p ())
    1538                 :             :                 {
    1539                 :         483 :                   location_t loc = OMP_CLAUSE_LOCATION (c);
    1540                 :         483 :                   const dump_user_location_t d_u_loc
    1541                 :         483 :                     = dump_user_location_t::from_location_t (loc);
    1542                 :             :                   /* PR100695 "Format decoder, quoting in 'dump_printf' etc." */
    1543                 :             : #if __GNUC__ >= 10
    1544                 :         483 : # pragma GCC diagnostic push
    1545                 :         483 : # pragma GCC diagnostic ignored "-Wformat"
    1546                 :             : #endif
    1547                 :         483 :                   if (!decl_addressable)
    1548                 :         257 :                     dump_printf_loc (MSG_NOTE, d_u_loc,
    1549                 :             :                                      "variable %<%T%>"
    1550                 :             :                                      " made addressable\n",
    1551                 :             :                                      decl);
    1552                 :             :                   else
    1553                 :         226 :                     dump_printf_loc (MSG_NOTE, d_u_loc,
    1554                 :             :                                      "variable %<%T%>"
    1555                 :             :                                      " already made addressable\n",
    1556                 :             :                                      decl);
    1557                 :             : #if __GNUC__ >= 10
    1558                 :         483 : # pragma GCC diagnostic pop
    1559                 :             : #endif
    1560                 :             :                 }
    1561                 :             : 
    1562                 :             :               /* Done.  */
    1563                 :         497 :               OMP_CLAUSE_MAP_DECL_MAKE_ADDRESSABLE (c) = 0;
    1564                 :             :             }
    1565                 :             :           /* Global variables with "omp declare target" attribute
    1566                 :             :              don't need to be copied, the receiver side will use them
    1567                 :             :              directly.  However, global variables with "omp declare target link"
    1568                 :             :              attribute need to be copied.  Or when ALWAYS modifier is used.  */
    1569                 :       83960 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
    1570                 :       76287 :               && DECL_P (decl)
    1571                 :       42802 :               && ((OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
    1572                 :       38909 :                    && (OMP_CLAUSE_MAP_KIND (c)
    1573                 :             :                        != GOMP_MAP_FIRSTPRIVATE_REFERENCE)
    1574                 :       38510 :                    && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
    1575                 :       38288 :                    && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH)
    1576                 :        4574 :                   || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    1577                 :       39428 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_TO
    1578                 :       39298 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_FROM
    1579                 :       39276 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_TOFROM
    1580                 :       38786 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_PRESENT_TO
    1581                 :       38756 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_PRESENT_FROM
    1582                 :       38730 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_PRESENT_TOFROM
    1583                 :       38718 :               && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
    1584                 :       34792 :               && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
    1585                 :        7564 :               && varpool_node::get_create (decl)->offloadable
    1586                 :       89332 :               && !lookup_attribute ("omp declare target link",
    1587                 :        5372 :                                     DECL_ATTRIBUTES (decl)))
    1588                 :             :             break;
    1589                 :       78607 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
    1590                 :       78607 :               && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)
    1591                 :             :             {
    1592                 :             :               /* Ignore GOMP_MAP_POINTER kind for arrays in regions that are
    1593                 :             :                  not offloaded; there is nothing to map for those.  */
    1594                 :       10221 :               if (!is_gimple_omp_offloaded (ctx->stmt)
    1595                 :        4924 :                   && !POINTER_TYPE_P (TREE_TYPE (decl))
    1596                 :       10485 :                   && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
    1597                 :             :                 break;
    1598                 :             :             }
    1599                 :       78343 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
    1600                 :       70670 :               && DECL_P (decl)
    1601                 :       37185 :               && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
    1602                 :       36963 :                   || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
    1603                 :       78625 :               && is_omp_target (ctx->stmt))
    1604                 :             :             {
    1605                 :             :               /* If this is an offloaded region, an attach operation should
    1606                 :             :                  only exist when the pointer variable is mapped in a prior
    1607                 :             :                  clause.  An exception is if we have a reference (to pointer):
    1608                 :             :                  in that case we should have mapped "*decl" in a previous
    1609                 :             :                  mapping instead of "decl".  Skip the assertion in that case.
    1610                 :             :                  If we had an error, we may not have attempted to sort clauses
    1611                 :             :                  properly, so avoid the test.  */
    1612                 :         240 :               if (TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
    1613                 :         208 :                   && is_gimple_omp_offloaded (ctx->stmt)
    1614                 :         308 :                   && !seen_error ())
    1615                 :          58 :                 gcc_assert
    1616                 :             :                   (maybe_lookup_decl (decl, ctx)
    1617                 :             :                    || (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
    1618                 :             :                        && lookup_attribute ("omp declare target",
    1619                 :             :                                             DECL_ATTRIBUTES (decl))));
    1620                 :             : 
    1621                 :             :               /* By itself, attach/detach is generated as part of pointer
    1622                 :             :                  variable mapping and should not create new variables in the
    1623                 :             :                  offloaded region, however sender refs for it must be created
    1624                 :             :                  for its address to be passed to the runtime.  */
    1625                 :         240 :               tree field
    1626                 :         240 :                 = build_decl (OMP_CLAUSE_LOCATION (c),
    1627                 :             :                               FIELD_DECL, NULL_TREE, ptr_type_node);
    1628                 :         240 :               SET_DECL_ALIGN (field, TYPE_ALIGN (ptr_type_node));
    1629                 :         240 :               insert_field_into_struct (ctx->record_type, field);
    1630                 :             :               /* To not clash with a map of the pointer variable itself,
    1631                 :             :                  attach/detach maps have their field looked up by the *clause*
    1632                 :             :                  tree expression, not the decl.  */
    1633                 :         240 :               gcc_assert (!splay_tree_lookup (ctx->field_map,
    1634                 :             :                                               (splay_tree_key) c));
    1635                 :         240 :               splay_tree_insert (ctx->field_map, (splay_tree_key) c,
    1636                 :             :                                  (splay_tree_value) field);
    1637                 :         240 :               break;
    1638                 :             :             }
    1639                 :       78103 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
    1640                 :       78103 :               && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
    1641                 :       66539 :                   || (OMP_CLAUSE_MAP_KIND (c)
    1642                 :             :                       == GOMP_MAP_FIRSTPRIVATE_REFERENCE)))
    1643                 :             :             {
    1644                 :        4290 :               if (TREE_CODE (decl) == COMPONENT_REF
    1645                 :        4290 :                   || (INDIRECT_REF_P (decl)
    1646                 :           0 :                       && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
    1647                 :           0 :                       && (((TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
    1648                 :             :                             == REFERENCE_TYPE)
    1649                 :           0 :                            || (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
    1650                 :             :                                == POINTER_TYPE)))))
    1651                 :             :                 break;
    1652                 :        4290 :               if (DECL_SIZE (decl)
    1653                 :        4290 :                   && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
    1654                 :             :                 {
    1655                 :         739 :                   tree decl2 = DECL_VALUE_EXPR (decl);
    1656                 :         739 :                   gcc_assert (INDIRECT_REF_P (decl2));
    1657                 :         739 :                   decl2 = TREE_OPERAND (decl2, 0);
    1658                 :         739 :                   gcc_assert (DECL_P (decl2));
    1659                 :         739 :                   install_var_local (decl2, ctx);
    1660                 :             :                 }
    1661                 :        4290 :               install_var_local (decl, ctx);
    1662                 :        4290 :               break;
    1663                 :             :             }
    1664                 :       73813 :           if (DECL_P (decl))
    1665                 :             :             {
    1666                 :       38847 :               if (DECL_SIZE (decl)
    1667                 :       38847 :                   && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
    1668                 :             :                 {
    1669                 :           0 :                   tree decl2 = DECL_VALUE_EXPR (decl);
    1670                 :           0 :                   gcc_assert (INDIRECT_REF_P (decl2));
    1671                 :           0 :                   decl2 = TREE_OPERAND (decl2, 0);
    1672                 :           0 :                   gcc_assert (DECL_P (decl2));
    1673                 :           0 :                   install_var_field (decl2, true, 3, ctx);
    1674                 :           0 :                   install_var_local (decl2, ctx);
    1675                 :           0 :                   install_var_local (decl, ctx);
    1676                 :             :                 }
    1677                 :             :               else
    1678                 :             :                 {
    1679                 :       38847 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
    1680                 :       32655 :                       && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
    1681                 :        5004 :                       && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
    1682                 :       43851 :                       && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    1683                 :         425 :                     install_var_field (decl, true, 7, ctx);
    1684                 :             :                   else
    1685                 :       38422 :                     install_var_field (decl, true, 3, ctx);
    1686                 :       38847 :                   if (is_gimple_omp_offloaded (ctx->stmt)
    1687                 :       38847 :                       && !(is_gimple_omp_oacc (ctx->stmt)
    1688                 :       13625 :                            && OMP_CLAUSE_MAP_IN_REDUCTION (c)))
    1689                 :       22507 :                     install_var_local (decl, ctx);
    1690                 :             :                 }
    1691                 :             :             }
    1692                 :             :           else
    1693                 :             :             {
    1694                 :       34966 :               tree base = get_base_address (decl);
    1695                 :       34966 :               tree nc = OMP_CLAUSE_CHAIN (c);
    1696                 :       34966 :               if (DECL_P (base)
    1697                 :        8124 :                   && nc != NULL_TREE
    1698                 :        5826 :                   && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
    1699                 :        4744 :                   && OMP_CLAUSE_DECL (nc) == base
    1700                 :        1156 :                   && OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
    1701                 :       35634 :                   && integer_zerop (OMP_CLAUSE_SIZE (nc)))
    1702                 :             :                 {
    1703                 :           0 :                   OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c) = 1;
    1704                 :           0 :                   OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (nc) = 1;
    1705                 :             :                 }
    1706                 :             :               else
    1707                 :             :                 {
    1708                 :       34966 :                   if (ctx->outer)
    1709                 :             :                     {
    1710                 :        7170 :                       scan_omp_op (&OMP_CLAUSE_DECL (c), ctx->outer);
    1711                 :        7170 :                       decl = OMP_CLAUSE_DECL (c);
    1712                 :             :                     }
    1713                 :       34966 :                   gcc_assert (!splay_tree_lookup (ctx->field_map,
    1714                 :             :                                                   (splay_tree_key) decl));
    1715                 :       34966 :                   tree field
    1716                 :       34966 :                     = build_decl (OMP_CLAUSE_LOCATION (c),
    1717                 :             :                                   FIELD_DECL, NULL_TREE, ptr_type_node);
    1718                 :       34966 :                   SET_DECL_ALIGN (field, TYPE_ALIGN (ptr_type_node));
    1719                 :       34966 :                   insert_field_into_struct (ctx->record_type, field);
    1720                 :       34966 :                   splay_tree_insert (ctx->field_map, (splay_tree_key) decl,
    1721                 :             :                                      (splay_tree_value) field);
    1722                 :             :                 }
    1723                 :             :             }
    1724                 :             :           break;
    1725                 :             : 
    1726                 :        4552 :         case OMP_CLAUSE_ORDER:
    1727                 :        4552 :           ctx->order_concurrent = true;
    1728                 :        4552 :           break;
    1729                 :             : 
    1730                 :        2160 :         case OMP_CLAUSE_BIND:
    1731                 :        2160 :           ctx->loop_p = true;
    1732                 :        2160 :           break;
    1733                 :             : 
    1734                 :             :         case OMP_CLAUSE_NOWAIT:
    1735                 :             :         case OMP_CLAUSE_ORDERED:
    1736                 :             :         case OMP_CLAUSE_COLLAPSE:
    1737                 :             :         case OMP_CLAUSE_UNTIED:
    1738                 :             :         case OMP_CLAUSE_MERGEABLE:
    1739                 :             :         case OMP_CLAUSE_PROC_BIND:
    1740                 :             :         case OMP_CLAUSE_SAFELEN:
    1741                 :             :         case OMP_CLAUSE_SIMDLEN:
    1742                 :             :         case OMP_CLAUSE_THREADS:
    1743                 :             :         case OMP_CLAUSE_SIMD:
    1744                 :             :         case OMP_CLAUSE_NOGROUP:
    1745                 :             :         case OMP_CLAUSE_DEFAULTMAP:
    1746                 :             :         case OMP_CLAUSE_ASYNC:
    1747                 :             :         case OMP_CLAUSE_WAIT:
    1748                 :             :         case OMP_CLAUSE_GANG:
    1749                 :             :         case OMP_CLAUSE_WORKER:
    1750                 :             :         case OMP_CLAUSE_VECTOR:
    1751                 :             :         case OMP_CLAUSE_INDEPENDENT:
    1752                 :             :         case OMP_CLAUSE_AUTO:
    1753                 :             :         case OMP_CLAUSE_SEQ:
    1754                 :             :         case OMP_CLAUSE_TILE:
    1755                 :             :         case OMP_CLAUSE__SIMT_:
    1756                 :             :         case OMP_CLAUSE_DEFAULT:
    1757                 :             :         case OMP_CLAUSE_NONTEMPORAL:
    1758                 :             :         case OMP_CLAUSE_IF_PRESENT:
    1759                 :             :         case OMP_CLAUSE_FINALIZE:
    1760                 :             :         case OMP_CLAUSE_TASK_REDUCTION:
    1761                 :             :         case OMP_CLAUSE_ALLOCATE:
    1762                 :             :           break;
    1763                 :             : 
    1764                 :         186 :         case OMP_CLAUSE_ALIGNED:
    1765                 :         186 :           decl = OMP_CLAUSE_DECL (c);
    1766                 :         186 :           if (is_global_var (decl)
    1767                 :         186 :               && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    1768                 :          95 :             install_var_local (decl, ctx);
    1769                 :             :           break;
    1770                 :             : 
    1771                 :         384 :         case OMP_CLAUSE__CONDTEMP_:
    1772                 :         384 :           decl = OMP_CLAUSE_DECL (c);
    1773                 :         384 :           if (is_parallel_ctx (ctx))
    1774                 :             :             {
    1775                 :         126 :               install_var_field (decl, false, 3, ctx);
    1776                 :         126 :               install_var_local (decl, ctx);
    1777                 :             :             }
    1778                 :         258 :           else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    1779                 :         258 :                    && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
    1780                 :         390 :                    && !OMP_CLAUSE__CONDTEMP__ITER (c))
    1781                 :         132 :             install_var_local (decl, ctx);
    1782                 :             :           break;
    1783                 :             : 
    1784                 :           0 :         case OMP_CLAUSE__CACHE_:
    1785                 :           0 :         case OMP_CLAUSE_NOHOST:
    1786                 :           0 :         default:
    1787                 :           0 :           gcc_unreachable ();
    1788                 :             :         }
    1789                 :             :     }
    1790                 :             : 
    1791                 :      547952 :   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    1792                 :             :     {
    1793                 :      417587 :       switch (OMP_CLAUSE_CODE (c))
    1794                 :             :         {
    1795                 :       23682 :         case OMP_CLAUSE_LASTPRIVATE:
    1796                 :             :           /* Let the corresponding firstprivate clause create
    1797                 :             :              the variable.  */
    1798                 :       23682 :           if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
    1799                 :        7375 :             scan_array_reductions = true;
    1800                 :       23682 :           if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
    1801                 :             :             break;
    1802                 :             :           /* FALLTHRU */
    1803                 :             : 
    1804                 :      149594 :         case OMP_CLAUSE_FIRSTPRIVATE:
    1805                 :      149594 :         case OMP_CLAUSE_PRIVATE:
    1806                 :      149594 :         case OMP_CLAUSE_LINEAR:
    1807                 :      149594 :         case OMP_CLAUSE_HAS_DEVICE_ADDR:
    1808                 :      149594 :         case OMP_CLAUSE_IS_DEVICE_PTR:
    1809                 :      149594 :           decl = OMP_CLAUSE_DECL (c);
    1810                 :      149594 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
    1811                 :             :             {
    1812                 :         244 :               while (INDIRECT_REF_P (decl)
    1813                 :         244 :                      || TREE_CODE (decl) == ARRAY_REF)
    1814                 :          17 :                 decl = TREE_OPERAND (decl, 0);
    1815                 :             :             }
    1816                 :             : 
    1817                 :      149594 :           if (is_variable_sized (decl))
    1818                 :             :             {
    1819                 :         452 :               if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
    1820                 :             :                    || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR
    1821                 :             :                    || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
    1822                 :          51 :                   && is_gimple_omp_offloaded (ctx->stmt))
    1823                 :             :                 {
    1824                 :          10 :                   tree decl2 = DECL_VALUE_EXPR (decl);
    1825                 :          10 :                   gcc_assert (INDIRECT_REF_P (decl2));
    1826                 :          10 :                   decl2 = TREE_OPERAND (decl2, 0);
    1827                 :          10 :                   gcc_assert (DECL_P (decl2));
    1828                 :          10 :                   install_var_local (decl2, ctx);
    1829                 :          10 :                   fixup_remapped_decl (decl2, ctx, false);
    1830                 :             :                 }
    1831                 :         452 :               install_var_local (decl, ctx);
    1832                 :             :             }
    1833                 :      299188 :           fixup_remapped_decl (decl, ctx,
    1834                 :      149594 :                                OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
    1835                 :      149594 :                                && OMP_CLAUSE_PRIVATE_DEBUG (c));
    1836                 :      149594 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
    1837                 :      149594 :               && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
    1838                 :             :             scan_array_reductions = true;
    1839                 :             :           break;
    1840                 :             : 
    1841                 :       16583 :         case OMP_CLAUSE_REDUCTION:
    1842                 :       16583 :         case OMP_CLAUSE_IN_REDUCTION:
    1843                 :       16583 :           decl = OMP_CLAUSE_DECL (c);
    1844                 :       16583 :           if (TREE_CODE (decl) != MEM_REF && !is_omp_target (ctx->stmt))
    1845                 :             :             {
    1846                 :       13541 :               if (is_variable_sized (decl))
    1847                 :           0 :                 install_var_local (decl, ctx);
    1848                 :       13541 :               fixup_remapped_decl (decl, ctx, false);
    1849                 :             :             }
    1850                 :       16583 :           if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    1851                 :        2985 :             scan_array_reductions = true;
    1852                 :             :           break;
    1853                 :             : 
    1854                 :         560 :         case OMP_CLAUSE_TASK_REDUCTION:
    1855                 :         560 :           if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    1856                 :        2985 :             scan_array_reductions = true;
    1857                 :             :           break;
    1858                 :             : 
    1859                 :       29599 :         case OMP_CLAUSE_SHARED:
    1860                 :             :           /* Ignore shared directives in teams construct inside of
    1861                 :             :              target construct.  */
    1862                 :       29599 :           if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
    1863                 :       29599 :               && !is_host_teams_ctx (ctx))
    1864                 :             :             break;
    1865                 :       17724 :           decl = OMP_CLAUSE_DECL (c);
    1866                 :       17724 :           if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
    1867                 :             :             break;
    1868                 :       11549 :           if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
    1869                 :             :             {
    1870                 :          90 :               if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl,
    1871                 :             :                                                                  ctx->outer)))
    1872                 :             :                 break;
    1873                 :          83 :               bool by_ref = use_pointer_for_field (decl, ctx);
    1874                 :          83 :               install_var_field (decl, by_ref, 11, ctx);
    1875                 :          83 :               break;
    1876                 :             :             }
    1877                 :       11459 :           fixup_remapped_decl (decl, ctx, false);
    1878                 :       11459 :           break;
    1879                 :             : 
    1880                 :       76287 :         case OMP_CLAUSE_MAP:
    1881                 :       76287 :           if (!is_gimple_omp_offloaded (ctx->stmt))
    1882                 :             :             break;
    1883                 :       51479 :           decl = OMP_CLAUSE_DECL (c);
    1884                 :       51479 :           if (DECL_P (decl)
    1885                 :       32462 :               && ((OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
    1886                 :       28738 :                    && (OMP_CLAUSE_MAP_KIND (c)
    1887                 :             :                        != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
    1888                 :        4123 :                   || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    1889                 :       29539 :               && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
    1890                 :       58922 :               && varpool_node::get_create (decl)->offloadable)
    1891                 :             :             break;
    1892                 :       45694 :           if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
    1893                 :       43681 :                || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
    1894                 :        2013 :               && is_omp_target (ctx->stmt)
    1895                 :       47491 :               && !is_gimple_omp_offloaded (ctx->stmt))
    1896                 :             :             break;
    1897                 :       45694 :           if (DECL_P (decl))
    1898                 :             :             {
    1899                 :       26677 :               if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
    1900                 :       23783 :                    || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
    1901                 :        6616 :                   && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
    1902                 :       28300 :                   && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
    1903                 :             :                 {
    1904                 :          30 :                   tree new_decl = lookup_decl (decl, ctx);
    1905                 :          30 :                   TREE_TYPE (new_decl)
    1906                 :          60 :                     = remap_type (TREE_TYPE (decl), &ctx->cb);
    1907                 :             :                 }
    1908                 :       26647 :               else if (DECL_SIZE (decl)
    1909                 :       26647 :                        && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
    1910                 :             :                 {
    1911                 :         739 :                   tree decl2 = DECL_VALUE_EXPR (decl);
    1912                 :         739 :                   gcc_assert (INDIRECT_REF_P (decl2));
    1913                 :         739 :                   decl2 = TREE_OPERAND (decl2, 0);
    1914                 :         739 :                   gcc_assert (DECL_P (decl2));
    1915                 :         739 :                   fixup_remapped_decl (decl2, ctx, false);
    1916                 :         739 :                   fixup_remapped_decl (decl, ctx, true);
    1917                 :             :                 }
    1918                 :             :               else
    1919                 :       25908 :                 fixup_remapped_decl (decl, ctx, false);
    1920                 :             :             }
    1921                 :             :           break;
    1922                 :             : 
    1923                 :             :         case OMP_CLAUSE_COPYPRIVATE:
    1924                 :             :         case OMP_CLAUSE_COPYIN:
    1925                 :             :         case OMP_CLAUSE_DEFAULT:
    1926                 :             :         case OMP_CLAUSE_IF:
    1927                 :             :         case OMP_CLAUSE_SELF:
    1928                 :             :         case OMP_CLAUSE_NUM_THREADS:
    1929                 :             :         case OMP_CLAUSE_NUM_TEAMS:
    1930                 :             :         case OMP_CLAUSE_THREAD_LIMIT:
    1931                 :             :         case OMP_CLAUSE_DEVICE:
    1932                 :             :         case OMP_CLAUSE_SCHEDULE:
    1933                 :             :         case OMP_CLAUSE_DIST_SCHEDULE:
    1934                 :             :         case OMP_CLAUSE_NOWAIT:
    1935                 :             :         case OMP_CLAUSE_ORDERED:
    1936                 :             :         case OMP_CLAUSE_COLLAPSE:
    1937                 :             :         case OMP_CLAUSE_UNTIED:
    1938                 :             :         case OMP_CLAUSE_FINAL:
    1939                 :             :         case OMP_CLAUSE_MERGEABLE:
    1940                 :             :         case OMP_CLAUSE_PROC_BIND:
    1941                 :             :         case OMP_CLAUSE_SAFELEN:
    1942                 :             :         case OMP_CLAUSE_SIMDLEN:
    1943                 :             :         case OMP_CLAUSE_ALIGNED:
    1944                 :             :         case OMP_CLAUSE_DEPEND:
    1945                 :             :         case OMP_CLAUSE_DETACH:
    1946                 :             :         case OMP_CLAUSE_ALLOCATE:
    1947                 :             :         case OMP_CLAUSE__LOOPTEMP_:
    1948                 :             :         case OMP_CLAUSE__REDUCTEMP_:
    1949                 :             :         case OMP_CLAUSE_TO:
    1950                 :             :         case OMP_CLAUSE_FROM:
    1951                 :             :         case OMP_CLAUSE_PRIORITY:
    1952                 :             :         case OMP_CLAUSE_GRAINSIZE:
    1953                 :             :         case OMP_CLAUSE_NUM_TASKS:
    1954                 :             :         case OMP_CLAUSE_THREADS:
    1955                 :             :         case OMP_CLAUSE_SIMD:
    1956                 :             :         case OMP_CLAUSE_NOGROUP:
    1957                 :             :         case OMP_CLAUSE_DEFAULTMAP:
    1958                 :             :         case OMP_CLAUSE_ORDER:
    1959                 :             :         case OMP_CLAUSE_BIND:
    1960                 :             :         case OMP_CLAUSE_USE_DEVICE_PTR:
    1961                 :             :         case OMP_CLAUSE_USE_DEVICE_ADDR:
    1962                 :             :         case OMP_CLAUSE_NONTEMPORAL:
    1963                 :             :         case OMP_CLAUSE_ASYNC:
    1964                 :             :         case OMP_CLAUSE_WAIT:
    1965                 :             :         case OMP_CLAUSE_NUM_GANGS:
    1966                 :             :         case OMP_CLAUSE_NUM_WORKERS:
    1967                 :             :         case OMP_CLAUSE_VECTOR_LENGTH:
    1968                 :             :         case OMP_CLAUSE_GANG:
    1969                 :             :         case OMP_CLAUSE_WORKER:
    1970                 :             :         case OMP_CLAUSE_VECTOR:
    1971                 :             :         case OMP_CLAUSE_INDEPENDENT:
    1972                 :             :         case OMP_CLAUSE_AUTO:
    1973                 :             :         case OMP_CLAUSE_SEQ:
    1974                 :             :         case OMP_CLAUSE_TILE:
    1975                 :             :         case OMP_CLAUSE__SIMT_:
    1976                 :             :         case OMP_CLAUSE_IF_PRESENT:
    1977                 :             :         case OMP_CLAUSE_FINALIZE:
    1978                 :             :         case OMP_CLAUSE_FILTER:
    1979                 :             :         case OMP_CLAUSE__CONDTEMP_:
    1980                 :             :           break;
    1981                 :             : 
    1982                 :           0 :         case OMP_CLAUSE__CACHE_:
    1983                 :           0 :         case OMP_CLAUSE_NOHOST:
    1984                 :           0 :         default:
    1985                 :           0 :           gcc_unreachable ();
    1986                 :             :         }
    1987                 :             :     }
    1988                 :             : 
    1989                 :      130365 :   gcc_checking_assert (!scan_array_reductions
    1990                 :             :                        || !is_gimple_omp_oacc (ctx->stmt));
    1991                 :             :   if (scan_array_reductions)
    1992                 :             :     {
    1993                 :       35641 :       for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    1994                 :       30245 :         if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    1995                 :       27769 :              || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
    1996                 :       27141 :              || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
    1997                 :       30953 :             && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    1998                 :             :           {
    1999                 :        2239 :             omp_context *rctx = ctx;
    2000                 :        2239 :             if (is_omp_target (ctx->stmt))
    2001                 :          60 :               rctx = ctx->outer;
    2002                 :        2239 :             scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), rctx);
    2003                 :        2239 :             scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), rctx);
    2004                 :             :           }
    2005                 :       28006 :         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    2006                 :       28006 :                  && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
    2007                 :        7375 :           scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
    2008                 :       20631 :         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
    2009                 :       20631 :                  && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
    2010                 :         746 :           scan_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
    2011                 :             :     }
    2012                 :      130365 : }
    2013                 :             : 
    2014                 :             : /* Create a new name for omp child function.  Returns an identifier. */
    2015                 :             : 
    2016                 :             : static tree
    2017                 :       51223 : create_omp_child_function_name (bool task_copy)
    2018                 :             : {
    2019                 :      101851 :   return clone_function_name_numbered (current_function_decl,
    2020                 :       51223 :                                        task_copy ? "_omp_cpyfn" : "_omp_fn");
    2021                 :             : }
    2022                 :             : 
    2023                 :             : /* Return true if CTX may belong to offloaded code: either if current function
    2024                 :             :    is offloaded, or any enclosing context corresponds to a target region.  */
    2025                 :             : 
    2026                 :             : static bool
    2027                 :      116720 : omp_maybe_offloaded_ctx (omp_context *ctx)
    2028                 :             : {
    2029                 :      116720 :   if (cgraph_node::get (current_function_decl)->offloadable)
    2030                 :             :     return true;
    2031                 :      187215 :   for (; ctx; ctx = ctx->outer)
    2032                 :      107430 :     if (is_gimple_omp_offloaded (ctx->stmt))
    2033                 :             :       return true;
    2034                 :             :   return false;
    2035                 :             : }
    2036                 :             : 
    2037                 :             : /* Build a decl for the omp child function.  It'll not contain a body
    2038                 :             :    yet, just the bare decl.  */
    2039                 :             : 
    2040                 :             : static void
    2041                 :       51223 : create_omp_child_function (omp_context *ctx, bool task_copy)
    2042                 :             : {
    2043                 :       51223 :   tree decl, type, name, t;
    2044                 :             : 
    2045                 :       51223 :   name = create_omp_child_function_name (task_copy);
    2046                 :       51223 :   if (task_copy)
    2047                 :         595 :     type = build_function_type_list (void_type_node, ptr_type_node,
    2048                 :             :                                      ptr_type_node, NULL_TREE);
    2049                 :             :   else
    2050                 :       50628 :     type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
    2051                 :             : 
    2052                 :       51223 :   decl = build_decl (gimple_location (ctx->stmt), FUNCTION_DECL, name, type);
    2053                 :             : 
    2054                 :       51223 :   gcc_checking_assert (!is_gimple_omp_oacc (ctx->stmt)
    2055                 :             :                        || !task_copy);
    2056                 :       39893 :   if (!task_copy)
    2057                 :       50628 :     ctx->cb.dst_fn = decl;
    2058                 :             :   else
    2059                 :         595 :     gimple_omp_task_set_copy_fn (ctx->stmt, decl);
    2060                 :             : 
    2061                 :       51223 :   TREE_STATIC (decl) = 1;
    2062                 :       51223 :   TREE_USED (decl) = 1;
    2063                 :       51223 :   DECL_ARTIFICIAL (decl) = 1;
    2064                 :       51223 :   DECL_IGNORED_P (decl) = 0;
    2065                 :       51223 :   TREE_PUBLIC (decl) = 0;
    2066                 :       51223 :   DECL_UNINLINABLE (decl) = 1;
    2067                 :       51223 :   DECL_EXTERNAL (decl) = 0;
    2068                 :       51223 :   DECL_CONTEXT (decl) = NULL_TREE;
    2069                 :       51223 :   DECL_INITIAL (decl) = make_node (BLOCK);
    2070                 :       51223 :   BLOCK_SUPERCONTEXT (DECL_INITIAL (decl)) = decl;
    2071                 :       51223 :   DECL_ATTRIBUTES (decl) = DECL_ATTRIBUTES (current_function_decl);
    2072                 :             :   /* Remove omp declare simd attribute from the new attributes.  */
    2073                 :       51223 :   if (tree a = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (decl)))
    2074                 :             :     {
    2075                 :          11 :       while (tree a2 = lookup_attribute ("omp declare simd", TREE_CHAIN (a)))
    2076                 :             :         a = a2;
    2077                 :          11 :       a = TREE_CHAIN (a);
    2078                 :          27 :       for (tree *p = &DECL_ATTRIBUTES (decl); *p != a;)
    2079                 :          16 :         if (is_attribute_p ("omp declare simd", get_attribute_name (*p)))
    2080                 :          11 :           *p = TREE_CHAIN (*p);
    2081                 :             :         else
    2082                 :             :           {
    2083                 :           5 :             tree chain = TREE_CHAIN (*p);
    2084                 :           5 :             *p = copy_node (*p);
    2085                 :           5 :             p = &TREE_CHAIN (*p);
    2086                 :           5 :             *p = chain;
    2087                 :             :           }
    2088                 :             :     }
    2089                 :      102446 :   DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl)
    2090                 :       51223 :     = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (current_function_decl);
    2091                 :      102446 :   DECL_FUNCTION_SPECIFIC_TARGET (decl)
    2092                 :       51223 :     = DECL_FUNCTION_SPECIFIC_TARGET (current_function_decl);
    2093                 :      102446 :   DECL_FUNCTION_VERSIONED (decl)
    2094                 :       51223 :     = DECL_FUNCTION_VERSIONED (current_function_decl);
    2095                 :             : 
    2096                 :       51223 :   if (omp_maybe_offloaded_ctx (ctx))
    2097                 :             :     {
    2098                 :       29845 :       cgraph_node::get_create (decl)->offloadable = 1;
    2099                 :       29845 :       if (ENABLE_OFFLOADING)
    2100                 :             :         g->have_offload = true;
    2101                 :             :     }
    2102                 :             : 
    2103                 :       51223 :   if (cgraph_node::get_create (decl)->offloadable)
    2104                 :             :     {
    2105                 :       29845 :       const char *target_attr = (is_gimple_omp_offloaded (ctx->stmt)
    2106                 :       29845 :                                  ? "omp target entrypoint"
    2107                 :       29845 :                                  : "omp declare target");
    2108                 :       29845 :       if (lookup_attribute ("omp declare target",
    2109                 :       29845 :                             DECL_ATTRIBUTES (current_function_decl)))
    2110                 :             :         {
    2111                 :        3030 :           if (is_gimple_omp_offloaded (ctx->stmt))
    2112                 :        1623 :             DECL_ATTRIBUTES (decl)
    2113                 :        1623 :               = remove_attribute ("omp declare target",
    2114                 :        1623 :                                   copy_list (DECL_ATTRIBUTES (decl)));
    2115                 :             :           else
    2116                 :             :             target_attr = NULL;
    2117                 :             :         }
    2118                 :        1623 :       if (target_attr
    2119                 :       28438 :           && is_gimple_omp_offloaded (ctx->stmt)
    2120                 :       23717 :           && lookup_attribute ("noclone", DECL_ATTRIBUTES (decl)) == NULL_TREE)
    2121                 :       18209 :         DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("noclone"),
    2122                 :       18209 :                                            NULL_TREE, DECL_ATTRIBUTES (decl));
    2123                 :       29845 :       if (target_attr)
    2124                 :       28438 :         DECL_ATTRIBUTES (decl)
    2125                 :       56876 :           = tree_cons (get_identifier (target_attr),
    2126                 :       28438 :                        NULL_TREE, DECL_ATTRIBUTES (decl));
    2127                 :             :     }
    2128                 :             : 
    2129                 :       51223 :   t = build_decl (DECL_SOURCE_LOCATION (decl),
    2130                 :             :                   RESULT_DECL, NULL_TREE, void_type_node);
    2131                 :       51223 :   DECL_ARTIFICIAL (t) = 1;
    2132                 :       51223 :   DECL_IGNORED_P (t) = 1;
    2133                 :       51223 :   DECL_CONTEXT (t) = decl;
    2134                 :       51223 :   DECL_RESULT (decl) = t;
    2135                 :             : 
    2136                 :       51223 :   tree data_name = get_identifier (".omp_data_i");
    2137                 :       51223 :   t = build_decl (DECL_SOURCE_LOCATION (decl), PARM_DECL, data_name,
    2138                 :             :                   ptr_type_node);
    2139                 :       51223 :   DECL_ARTIFICIAL (t) = 1;
    2140                 :       51223 :   DECL_NAMELESS (t) = 1;
    2141                 :       51223 :   DECL_ARG_TYPE (t) = ptr_type_node;
    2142                 :       51223 :   DECL_CONTEXT (t) = current_function_decl;
    2143                 :       51223 :   TREE_USED (t) = 1;
    2144                 :       51223 :   TREE_READONLY (t) = 1;
    2145                 :       51223 :   DECL_ARGUMENTS (decl) = t;
    2146                 :       51223 :   if (!task_copy)
    2147                 :       50628 :     ctx->receiver_decl = t;
    2148                 :             :   else
    2149                 :             :     {
    2150                 :         595 :       t = build_decl (DECL_SOURCE_LOCATION (decl),
    2151                 :             :                       PARM_DECL, get_identifier (".omp_data_o"),
    2152                 :             :                       ptr_type_node);
    2153                 :         595 :       DECL_ARTIFICIAL (t) = 1;
    2154                 :         595 :       DECL_NAMELESS (t) = 1;
    2155                 :         595 :       DECL_ARG_TYPE (t) = ptr_type_node;
    2156                 :         595 :       DECL_CONTEXT (t) = current_function_decl;
    2157                 :         595 :       TREE_USED (t) = 1;
    2158                 :         595 :       TREE_ADDRESSABLE (t) = 1;
    2159                 :         595 :       DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
    2160                 :         595 :       DECL_ARGUMENTS (decl) = t;
    2161                 :             :     }
    2162                 :             : 
    2163                 :             :   /* Allocate memory for the function structure.  The call to
    2164                 :             :      allocate_struct_function clobbers CFUN, so we need to restore
    2165                 :             :      it afterward.  */
    2166                 :       51223 :   push_struct_function (decl);
    2167                 :       51223 :   cfun->function_end_locus = gimple_location (ctx->stmt);
    2168                 :       51223 :   init_tree_ssa (cfun);
    2169                 :       51223 :   pop_cfun ();
    2170                 :       51223 : }
    2171                 :             : 
    2172                 :             : /* Callback for walk_gimple_seq.  Check if combined parallel
    2173                 :             :    contains gimple_omp_for_combined_into_p OMP_FOR.  */
    2174                 :             : 
    2175                 :             : tree
    2176                 :       34008 : omp_find_combined_for (gimple_stmt_iterator *gsi_p,
    2177                 :             :                        bool *handled_ops_p,
    2178                 :             :                        struct walk_stmt_info *wi)
    2179                 :             : {
    2180                 :       34008 :   gimple *stmt = gsi_stmt (*gsi_p);
    2181                 :             : 
    2182                 :       34008 :   *handled_ops_p = true;
    2183                 :       34008 :   switch (gimple_code (stmt))
    2184                 :             :     {
    2185                 :       19000 :     WALK_SUBSTMTS;
    2186                 :             : 
    2187                 :       13373 :     case GIMPLE_OMP_FOR:
    2188                 :       13373 :       if (gimple_omp_for_combined_into_p (stmt)
    2189                 :       13373 :           && gimple_omp_for_kind (stmt)
    2190                 :        8218 :              == *(const enum gf_mask *) (wi->info))
    2191                 :             :         {
    2192                 :        8218 :           wi->info = stmt;
    2193                 :        8218 :           return integer_zero_node;
    2194                 :             :         }
    2195                 :             :       break;
    2196                 :             :     default:
    2197                 :             :       break;
    2198                 :             :     }
    2199                 :             :   return NULL;
    2200                 :             : }
    2201                 :             : 
    2202                 :             : /* Add _LOOPTEMP_/_REDUCTEMP_ clauses on OpenMP parallel or task.  */
    2203                 :             : 
    2204                 :             : static void
    2205                 :       13964 : add_taskreg_looptemp_clauses (enum gf_mask msk, gimple *stmt,
    2206                 :             :                               omp_context *outer_ctx)
    2207                 :             : {
    2208                 :       13964 :   struct walk_stmt_info wi;
    2209                 :             : 
    2210                 :       13964 :   memset (&wi, 0, sizeof (wi));
    2211                 :       13964 :   wi.val_only = true;
    2212                 :       13964 :   wi.info = (void *) &msk;
    2213                 :       13964 :   walk_gimple_seq (gimple_omp_body (stmt), omp_find_combined_for, NULL, &wi);
    2214                 :       13964 :   if (wi.info != (void *) &msk)
    2215                 :             :     {
    2216                 :        8218 :       gomp_for *for_stmt = as_a <gomp_for *> ((gimple *) wi.info);
    2217                 :        8218 :       struct omp_for_data fd;
    2218                 :        8218 :       omp_extract_for_data (for_stmt, &fd, NULL);
    2219                 :             :       /* We need two temporaries with fd.loop.v type (istart/iend)
    2220                 :             :          and then (fd.collapse - 1) temporaries with the same
    2221                 :             :          type for count2 ... countN-1 vars if not constant.  */
    2222                 :        8218 :       size_t count = 2, i;
    2223                 :        8218 :       tree type = fd.iter_type;
    2224                 :        8218 :       if (fd.collapse > 1
    2225                 :        2620 :           && TREE_CODE (fd.loop.n2) != INTEGER_CST)
    2226                 :             :         {
    2227                 :        1410 :           count += fd.collapse - 1;
    2228                 :             :           /* If there are lastprivate clauses on the inner
    2229                 :             :              GIMPLE_OMP_FOR, add one more temporaries for the total number
    2230                 :             :              of iterations (product of count1 ... countN-1).  */
    2231                 :        1410 :           if (omp_find_clause (gimple_omp_for_clauses (for_stmt),
    2232                 :             :                                OMP_CLAUSE_LASTPRIVATE)
    2233                 :        1410 :               || (msk == GF_OMP_FOR_KIND_FOR
    2234                 :        1319 :                   && omp_find_clause (gimple_omp_parallel_clauses (stmt),
    2235                 :             :                                       OMP_CLAUSE_LASTPRIVATE)))
    2236                 :             :             {
    2237                 :         722 :               tree temp = create_tmp_var (type);
    2238                 :         722 :               tree c = build_omp_clause (UNKNOWN_LOCATION,
    2239                 :             :                                          OMP_CLAUSE__LOOPTEMP_);
    2240                 :         722 :               insert_decl_map (&outer_ctx->cb, temp, temp);
    2241                 :         722 :               OMP_CLAUSE_DECL (c) = temp;
    2242                 :         722 :               OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
    2243                 :         722 :               gimple_omp_taskreg_set_clauses (stmt, c);
    2244                 :             :             }
    2245                 :        1410 :           if (fd.non_rect
    2246                 :          24 :               && fd.last_nonrect == fd.first_nonrect + 1)
    2247                 :          12 :             if (tree v = gimple_omp_for_index (for_stmt, fd.last_nonrect))
    2248                 :          12 :               if (!TYPE_UNSIGNED (TREE_TYPE (v)))
    2249                 :             :                 {
    2250                 :          12 :                   v = gimple_omp_for_index (for_stmt, fd.first_nonrect);
    2251                 :          12 :                   tree type2 = TREE_TYPE (v);
    2252                 :          12 :                   count++;
    2253                 :          48 :                   for (i = 0; i < 3; i++)
    2254                 :             :                     {
    2255                 :          36 :                       tree temp = create_tmp_var (type2);
    2256                 :          36 :                       tree c = build_omp_clause (UNKNOWN_LOCATION,
    2257                 :             :                                                  OMP_CLAUSE__LOOPTEMP_);
    2258                 :          36 :                       insert_decl_map (&outer_ctx->cb, temp, temp);
    2259                 :          36 :                       OMP_CLAUSE_DECL (c) = temp;
    2260                 :          36 :                       OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
    2261                 :          36 :                       gimple_omp_taskreg_set_clauses (stmt, c);
    2262                 :             :                     }
    2263                 :             :                 }
    2264                 :             :         }
    2265                 :       27433 :       for (i = 0; i < count; i++)
    2266                 :             :         {
    2267                 :       19215 :           tree temp = create_tmp_var (type);
    2268                 :       19215 :           tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_);
    2269                 :       19215 :           insert_decl_map (&outer_ctx->cb, temp, temp);
    2270                 :       19215 :           OMP_CLAUSE_DECL (c) = temp;
    2271                 :       19215 :           OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
    2272                 :       19215 :           gimple_omp_taskreg_set_clauses (stmt, c);
    2273                 :             :         }
    2274                 :             :     }
    2275                 :       13964 :   if (msk == GF_OMP_FOR_KIND_TASKLOOP
    2276                 :       15641 :       && omp_find_clause (gimple_omp_task_clauses (stmt),
    2277                 :             :                           OMP_CLAUSE_REDUCTION))
    2278                 :             :     {
    2279                 :         583 :       tree type = build_pointer_type (pointer_sized_int_node);
    2280                 :         583 :       tree temp = create_tmp_var (type);
    2281                 :         583 :       tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
    2282                 :         583 :       insert_decl_map (&outer_ctx->cb, temp, temp);
    2283                 :         583 :       OMP_CLAUSE_DECL (c) = temp;
    2284                 :         583 :       OMP_CLAUSE_CHAIN (c) = gimple_omp_task_clauses (stmt);
    2285                 :         583 :       gimple_omp_task_set_clauses (stmt, c);
    2286                 :             :     }
    2287                 :       13964 : }
    2288                 :             : 
    2289                 :             : /* Scan an OpenMP parallel directive.  */
    2290                 :             : 
    2291                 :             : static void
    2292                 :       18175 : scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
    2293                 :             : {
    2294                 :       18175 :   omp_context *ctx;
    2295                 :       18175 :   tree name;
    2296                 :       18175 :   gomp_parallel *stmt = as_a <gomp_parallel *> (gsi_stmt (*gsi));
    2297                 :             : 
    2298                 :             :   /* Ignore parallel directives with empty bodies, unless there
    2299                 :             :      are copyin clauses.  */
    2300                 :       18175 :   if (optimize > 0
    2301                 :       12008 :       && empty_body_p (gimple_omp_body (stmt))
    2302                 :       18219 :       && omp_find_clause (gimple_omp_parallel_clauses (stmt),
    2303                 :             :                           OMP_CLAUSE_COPYIN) == NULL)
    2304                 :             :     {
    2305                 :          38 :       gsi_replace (gsi, gimple_build_nop (), false);
    2306                 :          38 :       return;
    2307                 :             :     }
    2308                 :             : 
    2309                 :       18137 :   if (gimple_omp_parallel_combined_p (stmt))
    2310                 :       12287 :     add_taskreg_looptemp_clauses (GF_OMP_FOR_KIND_FOR, stmt, outer_ctx);
    2311                 :       18137 :   for (tree c = omp_find_clause (gimple_omp_parallel_clauses (stmt),
    2312                 :             :                                  OMP_CLAUSE_REDUCTION);
    2313                 :       21111 :        c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE_REDUCTION))
    2314                 :        4081 :     if (OMP_CLAUSE_REDUCTION_TASK (c))
    2315                 :             :       {
    2316                 :          72 :         tree type = build_pointer_type (pointer_sized_int_node);
    2317                 :          72 :         tree temp = create_tmp_var (type);
    2318                 :          72 :         tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
    2319                 :          72 :         if (outer_ctx)
    2320                 :          19 :           insert_decl_map (&outer_ctx->cb, temp, temp);
    2321                 :          72 :         OMP_CLAUSE_DECL (c) = temp;
    2322                 :          72 :         OMP_CLAUSE_CHAIN (c) = gimple_omp_parallel_clauses (stmt);
    2323                 :          72 :         gimple_omp_parallel_set_clauses (stmt, c);
    2324                 :          72 :         break;
    2325                 :             :       }
    2326                 :        4009 :     else if (OMP_CLAUSE_CHAIN (c) == NULL_TREE)
    2327                 :             :       break;
    2328                 :             : 
    2329                 :       18137 :   ctx = new_omp_context (stmt, outer_ctx);
    2330                 :       18137 :   taskreg_contexts.safe_push (ctx);
    2331                 :       18137 :   if (taskreg_nesting_level > 1)
    2332                 :        6240 :     ctx->is_nested = true;
    2333                 :       18137 :   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
    2334                 :       18137 :   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
    2335                 :       18137 :   name = create_tmp_var_name (".omp_data_s");
    2336                 :       18137 :   name = build_decl (gimple_location (stmt),
    2337                 :             :                      TYPE_DECL, name, ctx->record_type);
    2338                 :       18137 :   DECL_ARTIFICIAL (name) = 1;
    2339                 :       18137 :   DECL_NAMELESS (name) = 1;
    2340                 :       18137 :   TYPE_NAME (ctx->record_type) = name;
    2341                 :       18137 :   TYPE_ARTIFICIAL (ctx->record_type) = 1;
    2342                 :       18137 :   create_omp_child_function (ctx, false);
    2343                 :       18137 :   gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
    2344                 :             : 
    2345                 :       18137 :   scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
    2346                 :       18137 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    2347                 :             : 
    2348                 :       18137 :   if (TYPE_FIELDS (ctx->record_type) == NULL)
    2349                 :        3614 :     ctx->record_type = ctx->receiver_decl = NULL;
    2350                 :             : }
    2351                 :             : 
    2352                 :             : /* Scan an OpenMP task directive.  */
    2353                 :             : 
    2354                 :             : static void
    2355                 :        6088 : scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
    2356                 :             : {
    2357                 :        6088 :   omp_context *ctx;
    2358                 :        6088 :   tree name, t;
    2359                 :        6088 :   gomp_task *stmt = as_a <gomp_task *> (gsi_stmt (*gsi));
    2360                 :             : 
    2361                 :             :   /* Ignore task directives with empty bodies, unless they have depend
    2362                 :             :      clause.  */
    2363                 :        6088 :   if (optimize > 0
    2364                 :        2497 :       && gimple_omp_body (stmt)
    2365                 :        2462 :       && empty_body_p (gimple_omp_body (stmt))
    2366                 :        6140 :       && !omp_find_clause (gimple_omp_task_clauses (stmt), OMP_CLAUSE_DEPEND))
    2367                 :             :     {
    2368                 :          19 :       gsi_replace (gsi, gimple_build_nop (), false);
    2369                 :         106 :       return;
    2370                 :             :     }
    2371                 :             : 
    2372                 :        6069 :   if (gimple_omp_task_taskloop_p (stmt))
    2373                 :        1677 :     add_taskreg_looptemp_clauses (GF_OMP_FOR_KIND_TASKLOOP, stmt, outer_ctx);
    2374                 :             : 
    2375                 :        6069 :   ctx = new_omp_context (stmt, outer_ctx);
    2376                 :             : 
    2377                 :        6069 :   if (gimple_omp_task_taskwait_p (stmt))
    2378                 :             :     {
    2379                 :          68 :       scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
    2380                 :          68 :       return;
    2381                 :             :     }
    2382                 :             : 
    2383                 :        6001 :   taskreg_contexts.safe_push (ctx);
    2384                 :        6001 :   if (taskreg_nesting_level > 1)
    2385                 :        2347 :     ctx->is_nested = true;
    2386                 :        6001 :   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
    2387                 :        6001 :   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
    2388                 :        6001 :   name = create_tmp_var_name (".omp_data_s");
    2389                 :        6001 :   name = build_decl (gimple_location (stmt),
    2390                 :             :                      TYPE_DECL, name, ctx->record_type);
    2391                 :        6001 :   DECL_ARTIFICIAL (name) = 1;
    2392                 :        6001 :   DECL_NAMELESS (name) = 1;
    2393                 :        6001 :   TYPE_NAME (ctx->record_type) = name;
    2394                 :        6001 :   TYPE_ARTIFICIAL (ctx->record_type) = 1;
    2395                 :        6001 :   create_omp_child_function (ctx, false);
    2396                 :        6001 :   gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
    2397                 :             : 
    2398                 :        6001 :   scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
    2399                 :             : 
    2400                 :        6001 :   if (ctx->srecord_type)
    2401                 :             :     {
    2402                 :         595 :       name = create_tmp_var_name (".omp_data_a");
    2403                 :         595 :       name = build_decl (gimple_location (stmt),
    2404                 :             :                          TYPE_DECL, name, ctx->srecord_type);
    2405                 :         595 :       DECL_ARTIFICIAL (name) = 1;
    2406                 :         595 :       DECL_NAMELESS (name) = 1;
    2407                 :         595 :       TYPE_NAME (ctx->srecord_type) = name;
    2408                 :         595 :       TYPE_ARTIFICIAL (ctx->srecord_type) = 1;
    2409                 :         595 :       create_omp_child_function (ctx, true);
    2410                 :             :     }
    2411                 :             : 
    2412                 :        6001 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    2413                 :             : 
    2414                 :        6001 :   if (TYPE_FIELDS (ctx->record_type) == NULL)
    2415                 :             :     {
    2416                 :        2398 :       ctx->record_type = ctx->receiver_decl = NULL;
    2417                 :        2398 :       t = build_int_cst (long_integer_type_node, 0);
    2418                 :        2398 :       gimple_omp_task_set_arg_size (stmt, t);
    2419                 :        2398 :       t = build_int_cst (long_integer_type_node, 1);
    2420                 :        2398 :       gimple_omp_task_set_arg_align (stmt, t);
    2421                 :             :     }
    2422                 :             : }
    2423                 :             : 
    2424                 :             : /* Helper function for finish_taskreg_scan, called through walk_tree.
    2425                 :             :    If maybe_lookup_decl_in_outer_context returns non-NULL for some
    2426                 :             :    tree, replace it in the expression.  */
    2427                 :             : 
    2428                 :             : static tree
    2429                 :         276 : finish_taskreg_remap (tree *tp, int *walk_subtrees, void *data)
    2430                 :             : {
    2431                 :         276 :   if (VAR_P (*tp))
    2432                 :             :     {
    2433                 :          96 :       omp_context *ctx = (omp_context *) data;
    2434                 :          96 :       tree t = maybe_lookup_decl_in_outer_ctx (*tp, ctx);
    2435                 :          96 :       if (t != *tp)
    2436                 :             :         {
    2437                 :           9 :           if (DECL_HAS_VALUE_EXPR_P (t))
    2438                 :           0 :             t = unshare_expr (DECL_VALUE_EXPR (t));
    2439                 :           9 :           *tp = t;
    2440                 :             :         }
    2441                 :          96 :       *walk_subtrees = 0;
    2442                 :             :     }
    2443                 :         180 :   else if (IS_TYPE_OR_DECL_P (*tp))
    2444                 :           0 :     *walk_subtrees = 0;
    2445                 :         276 :   return NULL_TREE;
    2446                 :             : }
    2447                 :             : 
    2448                 :             : /* If any decls have been made addressable during scan_omp,
    2449                 :             :    adjust their fields if needed, and layout record types
    2450                 :             :    of parallel/task constructs.  */
    2451                 :             : 
    2452                 :             : static void
    2453                 :       26911 : finish_taskreg_scan (omp_context *ctx)
    2454                 :             : {
    2455                 :       26911 :   if (ctx->record_type == NULL_TREE)
    2456                 :             :     return;
    2457                 :             : 
    2458                 :             :   /* If any make_addressable_vars were needed, verify all
    2459                 :             :      OMP_CLAUSE_SHARED clauses on GIMPLE_OMP_{PARALLEL,TASK,TEAMS}
    2460                 :             :      statements if use_pointer_for_field hasn't changed
    2461                 :             :      because of that.  If it did, update field types now.  */
    2462                 :       19400 :   if (make_addressable_vars)
    2463                 :             :     {
    2464                 :        2366 :       tree c;
    2465                 :             : 
    2466                 :       12462 :       for (c = gimple_omp_taskreg_clauses (ctx->stmt);
    2467                 :       12462 :            c; c = OMP_CLAUSE_CHAIN (c))
    2468                 :       10096 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
    2469                 :       10096 :             && !OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
    2470                 :             :           {
    2471                 :        2677 :             tree decl = OMP_CLAUSE_DECL (c);
    2472                 :             : 
    2473                 :             :             /* Global variables don't need to be copied,
    2474                 :             :                the receiver side will use them directly.  */
    2475                 :        2677 :             if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
    2476                 :         297 :               continue;
    2477                 :        2380 :             if (!bitmap_bit_p (make_addressable_vars, DECL_UID (decl))
    2478                 :        2380 :                 || !use_pointer_for_field (decl, ctx))
    2479                 :        1925 :               continue;
    2480                 :         455 :             tree field = lookup_field (decl, ctx);
    2481                 :         455 :             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
    2482                 :         455 :                 && TREE_TYPE (TREE_TYPE (field)) == TREE_TYPE (decl))
    2483                 :         393 :               continue;
    2484                 :          62 :             TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
    2485                 :          62 :             TREE_THIS_VOLATILE (field) = 0;
    2486                 :          62 :             DECL_USER_ALIGN (field) = 0;
    2487                 :          62 :             SET_DECL_ALIGN (field, TYPE_ALIGN (TREE_TYPE (field)));
    2488                 :          62 :             if (TYPE_ALIGN (ctx->record_type) < DECL_ALIGN (field))
    2489                 :          18 :               SET_TYPE_ALIGN (ctx->record_type, DECL_ALIGN (field));
    2490                 :          62 :             if (ctx->srecord_type)
    2491                 :             :               {
    2492                 :           0 :                 tree sfield = lookup_sfield (decl, ctx);
    2493                 :           0 :                 TREE_TYPE (sfield) = TREE_TYPE (field);
    2494                 :           0 :                 TREE_THIS_VOLATILE (sfield) = 0;
    2495                 :           0 :                 DECL_USER_ALIGN (sfield) = 0;
    2496                 :           0 :                 SET_DECL_ALIGN (sfield, DECL_ALIGN (field));
    2497                 :           0 :                 if (TYPE_ALIGN (ctx->srecord_type) < DECL_ALIGN (sfield))
    2498                 :           0 :                   SET_TYPE_ALIGN (ctx->srecord_type, DECL_ALIGN (sfield));
    2499                 :             :               }
    2500                 :             :           }
    2501                 :             :     }
    2502                 :             : 
    2503                 :       19400 :   if (gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
    2504                 :             :     {
    2505                 :       14523 :       tree clauses = gimple_omp_parallel_clauses (ctx->stmt);
    2506                 :       14523 :       tree c = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
    2507                 :       14523 :       if (c)
    2508                 :             :         {
    2509                 :             :           /* Move the _reductemp_ clause first.  GOMP_parallel_reductions
    2510                 :             :              expects to find it at the start of data.  */
    2511                 :          72 :           tree f = lookup_field (OMP_CLAUSE_DECL (c), ctx);
    2512                 :          72 :           tree *p = &TYPE_FIELDS (ctx->record_type);
    2513                 :         158 :           while (*p)
    2514                 :         158 :             if (*p == f)
    2515                 :             :               {
    2516                 :          72 :                 *p = DECL_CHAIN (*p);
    2517                 :          72 :                 break;
    2518                 :             :               }
    2519                 :             :             else
    2520                 :          86 :               p = &DECL_CHAIN (*p);
    2521                 :          72 :           DECL_CHAIN (f) = TYPE_FIELDS (ctx->record_type);
    2522                 :          72 :           TYPE_FIELDS (ctx->record_type) = f;
    2523                 :             :         }
    2524                 :       14523 :       layout_type (ctx->record_type);
    2525                 :       14523 :       fixup_child_record_type (ctx);
    2526                 :             :     }
    2527                 :        4877 :   else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
    2528                 :             :     {
    2529                 :        1274 :       layout_type (ctx->record_type);
    2530                 :        1274 :       fixup_child_record_type (ctx);
    2531                 :             :     }
    2532                 :             :   else
    2533                 :             :     {
    2534                 :        3603 :       location_t loc = gimple_location (ctx->stmt);
    2535                 :        3603 :       tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
    2536                 :        3603 :       tree detach_clause
    2537                 :        3603 :         = omp_find_clause (gimple_omp_task_clauses (ctx->stmt),
    2538                 :             :                            OMP_CLAUSE_DETACH);
    2539                 :             :       /* Move VLA fields to the end.  */
    2540                 :        3603 :       p = &TYPE_FIELDS (ctx->record_type);
    2541                 :       15254 :       while (*p)
    2542                 :       11651 :         if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
    2543                 :       11651 :             || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
    2544                 :             :           {
    2545                 :          96 :             *q = *p;
    2546                 :          96 :             *p = TREE_CHAIN (*p);
    2547                 :          96 :             TREE_CHAIN (*q) = NULL_TREE;
    2548                 :          96 :             q = &TREE_CHAIN (*q);
    2549                 :             :           }
    2550                 :             :         else
    2551                 :       11555 :           p = &DECL_CHAIN (*p);
    2552                 :        3603 :       *p = vla_fields;
    2553                 :        3603 :       if (gimple_omp_task_taskloop_p (ctx->stmt))
    2554                 :             :         {
    2555                 :             :           /* Move fields corresponding to first and second _looptemp_
    2556                 :             :              clause first.  There are filled by GOMP_taskloop
    2557                 :             :              and thus need to be in specific positions.  */
    2558                 :        1677 :           tree clauses = gimple_omp_task_clauses (ctx->stmt);
    2559                 :        1677 :           tree c1 = omp_find_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
    2560                 :        1677 :           tree c2 = omp_find_clause (OMP_CLAUSE_CHAIN (c1),
    2561                 :             :                                      OMP_CLAUSE__LOOPTEMP_);
    2562                 :        1677 :           tree c3 = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
    2563                 :        1677 :           tree f1 = lookup_field (OMP_CLAUSE_DECL (c1), ctx);
    2564                 :        1677 :           tree f2 = lookup_field (OMP_CLAUSE_DECL (c2), ctx);
    2565                 :        2260 :           tree f3 = c3 ? lookup_field (OMP_CLAUSE_DECL (c3), ctx) : NULL_TREE;
    2566                 :        1677 :           p = &TYPE_FIELDS (ctx->record_type);
    2567                 :        8658 :           while (*p)
    2568                 :        6981 :             if (*p == f1 || *p == f2 || *p == f3)
    2569                 :        3937 :               *p = DECL_CHAIN (*p);
    2570                 :             :             else
    2571                 :        3044 :               p = &DECL_CHAIN (*p);
    2572                 :        1677 :           DECL_CHAIN (f1) = f2;
    2573                 :        1677 :           if (c3)
    2574                 :             :             {
    2575                 :         583 :               DECL_CHAIN (f2) = f3;
    2576                 :         583 :               DECL_CHAIN (f3) = TYPE_FIELDS (ctx->record_type);
    2577                 :             :             }
    2578                 :             :           else
    2579                 :        1094 :             DECL_CHAIN (f2) = TYPE_FIELDS (ctx->record_type);
    2580                 :        1677 :           TYPE_FIELDS (ctx->record_type) = f1;
    2581                 :        1677 :           if (ctx->srecord_type)
    2582                 :             :             {
    2583                 :         412 :               f1 = lookup_sfield (OMP_CLAUSE_DECL (c1), ctx);
    2584                 :         412 :               f2 = lookup_sfield (OMP_CLAUSE_DECL (c2), ctx);
    2585                 :         412 :               if (c3)
    2586                 :         206 :                 f3 = lookup_sfield (OMP_CLAUSE_DECL (c3), ctx);
    2587                 :         412 :               p = &TYPE_FIELDS (ctx->srecord_type);
    2588                 :        2202 :               while (*p)
    2589                 :        1790 :                 if (*p == f1 || *p == f2 || *p == f3)
    2590                 :        1030 :                   *p = DECL_CHAIN (*p);
    2591                 :             :                 else
    2592                 :         760 :                   p = &DECL_CHAIN (*p);
    2593                 :         412 :               DECL_CHAIN (f1) = f2;
    2594                 :         412 :               DECL_CHAIN (f2) = TYPE_FIELDS (ctx->srecord_type);
    2595                 :         412 :               if (c3)
    2596                 :             :                 {
    2597                 :         206 :                   DECL_CHAIN (f2) = f3;
    2598                 :         206 :                   DECL_CHAIN (f3) = TYPE_FIELDS (ctx->srecord_type);
    2599                 :             :                 }
    2600                 :             :               else
    2601                 :         206 :                 DECL_CHAIN (f2) = TYPE_FIELDS (ctx->srecord_type);
    2602                 :         412 :               TYPE_FIELDS (ctx->srecord_type) = f1;
    2603                 :             :             }
    2604                 :             :         }
    2605                 :        3603 :       if (detach_clause)
    2606                 :             :         {
    2607                 :         197 :           tree c, field;
    2608                 :             : 
    2609                 :             :           /* Look for a firstprivate clause with the detach event handle.  */
    2610                 :         557 :           for (c = gimple_omp_taskreg_clauses (ctx->stmt);
    2611                 :         557 :                c; c = OMP_CLAUSE_CHAIN (c))
    2612                 :             :             {
    2613                 :         557 :               if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
    2614                 :         356 :                 continue;
    2615                 :         201 :               if (maybe_lookup_decl_in_outer_ctx (OMP_CLAUSE_DECL (c), ctx)
    2616                 :         201 :                   == OMP_CLAUSE_DECL (detach_clause))
    2617                 :             :                 break;
    2618                 :             :             }
    2619                 :             : 
    2620                 :         197 :           gcc_assert (c);
    2621                 :         197 :           field = lookup_field (OMP_CLAUSE_DECL (c), ctx);
    2622                 :             : 
    2623                 :             :           /* Move field corresponding to the detach clause first.
    2624                 :             :              This is filled by GOMP_task and needs to be in a
    2625                 :             :              specific position.  */
    2626                 :         197 :           p = &TYPE_FIELDS (ctx->record_type);
    2627                 :         534 :           while (*p)
    2628                 :         337 :             if (*p == field)
    2629                 :         197 :               *p = DECL_CHAIN (*p);
    2630                 :             :             else
    2631                 :         140 :               p = &DECL_CHAIN (*p);
    2632                 :         197 :           DECL_CHAIN (field) = TYPE_FIELDS (ctx->record_type);
    2633                 :         197 :           TYPE_FIELDS (ctx->record_type) = field;
    2634                 :         197 :           if (ctx->srecord_type)
    2635                 :             :             {
    2636                 :           3 :               field = lookup_sfield (OMP_CLAUSE_DECL (c), ctx);
    2637                 :           3 :               p = &TYPE_FIELDS (ctx->srecord_type);
    2638                 :           9 :               while (*p)
    2639                 :           6 :                 if (*p == field)
    2640                 :           3 :                   *p = DECL_CHAIN (*p);
    2641                 :             :                 else
    2642                 :           3 :                   p = &DECL_CHAIN (*p);
    2643                 :           3 :               DECL_CHAIN (field) = TYPE_FIELDS (ctx->srecord_type);
    2644                 :           3 :               TYPE_FIELDS (ctx->srecord_type) = field;
    2645                 :             :             }
    2646                 :             :         }
    2647                 :        3603 :       layout_type (ctx->record_type);
    2648                 :        3603 :       fixup_child_record_type (ctx);
    2649                 :        3603 :       if (ctx->srecord_type)
    2650                 :         595 :         layout_type (ctx->srecord_type);
    2651                 :        3603 :       tree t = fold_convert_loc (loc, long_integer_type_node,
    2652                 :        3603 :                                  TYPE_SIZE_UNIT (ctx->record_type));
    2653                 :        3603 :       if (TREE_CODE (t) != INTEGER_CST)
    2654                 :             :         {
    2655                 :          21 :           t = unshare_expr (t);
    2656                 :          21 :           walk_tree (&t, finish_taskreg_remap, ctx, NULL);
    2657                 :             :         }
    2658                 :        3603 :       gimple_omp_task_set_arg_size (ctx->stmt, t);
    2659                 :        3603 :       t = build_int_cst (long_integer_type_node,
    2660                 :        3603 :                          TYPE_ALIGN_UNIT (ctx->record_type));
    2661                 :        3603 :       gimple_omp_task_set_arg_align (ctx->stmt, t);
    2662                 :             :     }
    2663                 :             : }
    2664                 :             : 
    2665                 :             : /* Find the enclosing offload context.  */
    2666                 :             : 
    2667                 :             : static omp_context *
    2668                 :        8725 : enclosing_target_ctx (omp_context *ctx)
    2669                 :             : {
    2670                 :       38850 :   for (; ctx; ctx = ctx->outer)
    2671                 :       36945 :     if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET)
    2672                 :             :       break;
    2673                 :             : 
    2674                 :       20600 :   return ctx;
    2675                 :             : }
    2676                 :             : 
    2677                 :             : /* Return whether CTX's parent compute construct is an OpenACC 'kernels'
    2678                 :             :    construct.
    2679                 :             :    (This doesn't include OpenACC 'kernels' decomposed parts.)  */
    2680                 :             : 
    2681                 :             : static bool
    2682                 :       10589 : ctx_in_oacc_kernels_region (omp_context *ctx)
    2683                 :             : {
    2684                 :       35696 :   for (;ctx != NULL; ctx = ctx->outer)
    2685                 :             :     {
    2686                 :       26971 :       gimple *stmt = ctx->stmt;
    2687                 :       26971 :       if (gimple_code (stmt) == GIMPLE_OMP_TARGET
    2688                 :       26971 :           && gimple_omp_target_kind (stmt) == GF_OMP_TARGET_KIND_OACC_KERNELS)
    2689                 :             :         return true;
    2690                 :             :     }
    2691                 :             : 
    2692                 :             :   return false;
    2693                 :             : }
    2694                 :             : 
    2695                 :             : /* Check the parallelism clauses inside a OpenACC 'kernels' region.
    2696                 :             :    (This doesn't include OpenACC 'kernels' decomposed parts.)
    2697                 :             :    Until kernels handling moves to use the same loop indirection
    2698                 :             :    scheme as parallel, we need to do this checking early.  */
    2699                 :             : 
    2700                 :             : static unsigned
    2701                 :        8180 : check_oacc_kernel_gwv (gomp_for *stmt, omp_context *ctx)
    2702                 :             : {
    2703                 :        8180 :   bool checking = true;
    2704                 :        8180 :   unsigned outer_mask = 0;
    2705                 :        8180 :   unsigned this_mask = 0;
    2706                 :        8180 :   bool has_seq = false, has_auto = false;
    2707                 :             : 
    2708                 :        8180 :   if (ctx->outer)
    2709                 :        5491 :     outer_mask = check_oacc_kernel_gwv (NULL,  ctx->outer);
    2710                 :        8180 :   if (!stmt)
    2711                 :             :     {
    2712                 :        5491 :       checking = false;
    2713                 :        5491 :       if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR)
    2714                 :             :         return outer_mask;
    2715                 :        1989 :       stmt = as_a <gomp_for *> (ctx->stmt);
    2716                 :             :     }
    2717                 :             : 
    2718                 :       12901 :   for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
    2719                 :             :     {
    2720                 :        8223 :       switch (OMP_CLAUSE_CODE (c))
    2721                 :             :         {
    2722                 :         698 :         case OMP_CLAUSE_GANG:
    2723                 :         698 :           this_mask |= GOMP_DIM_MASK (GOMP_DIM_GANG);
    2724                 :         698 :           break;
    2725                 :         477 :         case OMP_CLAUSE_WORKER:
    2726                 :         477 :           this_mask |= GOMP_DIM_MASK (GOMP_DIM_WORKER);
    2727                 :         477 :           break;
    2728                 :         379 :         case OMP_CLAUSE_VECTOR:
    2729                 :         379 :           this_mask |= GOMP_DIM_MASK (GOMP_DIM_VECTOR);
    2730                 :         379 :           break;
    2731                 :          72 :         case OMP_CLAUSE_SEQ:
    2732                 :          72 :           has_seq = true;
    2733                 :          72 :           break;
    2734                 :         110 :         case OMP_CLAUSE_AUTO:
    2735                 :         110 :           has_auto = true;
    2736                 :         110 :           break;
    2737                 :             :         default:
    2738                 :             :           break;
    2739                 :             :         }
    2740                 :             :     }
    2741                 :             : 
    2742                 :        4678 :   if (checking)
    2743                 :             :     {
    2744                 :        2689 :       if (has_seq && (this_mask || has_auto))
    2745                 :          43 :         error_at (gimple_location (stmt), "%<seq%> overrides other"
    2746                 :             :                   " OpenACC loop specifiers");
    2747                 :        2646 :       else if (has_auto && this_mask)
    2748                 :          36 :         error_at (gimple_location (stmt), "%<auto%> conflicts with other"
    2749                 :             :                   " OpenACC loop specifiers");
    2750                 :             : 
    2751                 :        2689 :       if (this_mask & outer_mask)
    2752                 :          18 :         error_at (gimple_location (stmt), "inner loop uses same"
    2753                 :             :                   " OpenACC parallelism as containing loop");
    2754                 :             :     }
    2755                 :             : 
    2756                 :        4678 :   return outer_mask | this_mask;
    2757                 :             : }
    2758                 :             : 
    2759                 :             : /* Scan a GIMPLE_OMP_FOR.  */
    2760                 :             : 
    2761                 :             : static omp_context *
    2762                 :       53432 : scan_omp_for (gomp_for *stmt, omp_context *outer_ctx)
    2763                 :             : {
    2764                 :       53432 :   omp_context *ctx;
    2765                 :       53432 :   size_t i;
    2766                 :       53432 :   tree clauses = gimple_omp_for_clauses (stmt);
    2767                 :             : 
    2768                 :       53432 :   ctx = new_omp_context (stmt, outer_ctx);
    2769                 :             : 
    2770                 :       53432 :   if (is_gimple_omp_oacc (stmt))
    2771                 :             :     {
    2772                 :       11875 :       omp_context *tgt = enclosing_target_ctx (outer_ctx);
    2773                 :             : 
    2774                 :       11875 :       if (!(tgt && is_oacc_kernels (tgt)))
    2775                 :       29564 :         for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    2776                 :             :           {
    2777                 :       20378 :             tree c_op0;
    2778                 :       20378 :             switch (OMP_CLAUSE_CODE (c))
    2779                 :             :               {
    2780                 :        1893 :               case OMP_CLAUSE_GANG:
    2781                 :        1893 :                 c_op0 = OMP_CLAUSE_GANG_EXPR (c);
    2782                 :        1893 :                 break;
    2783                 :             : 
    2784                 :        1388 :               case OMP_CLAUSE_WORKER:
    2785                 :        1388 :                 c_op0 = OMP_CLAUSE_WORKER_EXPR (c);
    2786                 :        1388 :                 break;
    2787                 :             : 
    2788                 :        1604 :               case OMP_CLAUSE_VECTOR:
    2789                 :        1604 :                 c_op0 = OMP_CLAUSE_VECTOR_EXPR (c);
    2790                 :        1604 :                 break;
    2791                 :             : 
    2792                 :       15493 :               default:
    2793                 :       15493 :                 continue;
    2794                 :             :               }
    2795                 :             : 
    2796                 :        4885 :             if (c_op0)
    2797                 :             :               {
    2798                 :             :                 /* By construction, this is impossible for OpenACC 'kernels'
    2799                 :             :                    decomposed parts.  */
    2800                 :         180 :                 gcc_assert (!(tgt && is_oacc_kernels_decomposed_part (tgt)));
    2801                 :             : 
    2802                 :         180 :                 error_at (OMP_CLAUSE_LOCATION (c),
    2803                 :             :                           "argument not permitted on %qs clause",
    2804                 :         180 :                           omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
    2805                 :         180 :                 if (tgt)
    2806                 :         144 :                   inform (gimple_location (tgt->stmt),
    2807                 :             :                           "enclosing parent compute construct");
    2808                 :          36 :                 else if (oacc_get_fn_attrib (current_function_decl))
    2809                 :          36 :                   inform (DECL_SOURCE_LOCATION (current_function_decl),
    2810                 :             :                           "enclosing routine");
    2811                 :             :                 else
    2812                 :           0 :                   gcc_unreachable ();
    2813                 :             :               }
    2814                 :             :           }
    2815                 :             : 
    2816                 :       11875 :       if (tgt && is_oacc_kernels (tgt))
    2817                 :        2689 :         check_oacc_kernel_gwv (stmt, ctx);
    2818                 :             : 
    2819                 :             :       /* Collect all variables named in reductions on this loop.  Ensure
    2820                 :             :          that, if this loop has a reduction on some variable v, and there is
    2821                 :             :          a reduction on v somewhere in an outer context, then there is a
    2822                 :             :          reduction on v on all intervening loops as well.  */
    2823                 :       11875 :       tree local_reduction_clauses = NULL;
    2824                 :       37725 :       for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
    2825                 :             :         {
    2826                 :       25850 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
    2827                 :        4277 :             local_reduction_clauses
    2828                 :        4277 :               = tree_cons (NULL, c, local_reduction_clauses);
    2829                 :             :         }
    2830                 :       11875 :       if (ctx->outer_reduction_clauses == NULL && ctx->outer != NULL)
    2831                 :       11259 :         ctx->outer_reduction_clauses
    2832                 :       11259 :           = chainon (unshare_expr (ctx->outer->local_reduction_clauses),
    2833                 :             :                      ctx->outer->outer_reduction_clauses);
    2834                 :       11875 :       tree outer_reduction_clauses = ctx->outer_reduction_clauses;
    2835                 :       11875 :       tree local_iter = local_reduction_clauses;
    2836                 :       16152 :       for (; local_iter; local_iter = TREE_CHAIN (local_iter))
    2837                 :             :         {
    2838                 :        4277 :           tree local_clause = TREE_VALUE (local_iter);
    2839                 :        4277 :           tree local_var = OMP_CLAUSE_DECL (local_clause);
    2840                 :        4277 :           tree_code local_op = OMP_CLAUSE_REDUCTION_CODE (local_clause);
    2841                 :        4277 :           bool have_outer_reduction = false;
    2842                 :        4277 :           tree ctx_iter = outer_reduction_clauses;
    2843                 :        5201 :           for (; ctx_iter; ctx_iter = TREE_CHAIN (ctx_iter))
    2844                 :             :             {
    2845                 :        2741 :               tree outer_clause = TREE_VALUE (ctx_iter);
    2846                 :        2741 :               tree outer_var = OMP_CLAUSE_DECL (outer_clause);
    2847                 :        2741 :               tree_code outer_op = OMP_CLAUSE_REDUCTION_CODE (outer_clause);
    2848                 :        2741 :               if (outer_var == local_var && outer_op != local_op)
    2849                 :             :                 {
    2850                 :         426 :                   if (warning_at (OMP_CLAUSE_LOCATION (local_clause),
    2851                 :             :                                   OPT_Wopenmp, "conflicting reduction "
    2852                 :             :                                                "operations for %qE",
    2853                 :             :                                   local_var))
    2854                 :         426 :                     inform (OMP_CLAUSE_LOCATION (outer_clause),
    2855                 :             :                             "location of the previous reduction for %qE",
    2856                 :             :                             outer_var);
    2857                 :             :                 }
    2858                 :        2741 :               if (outer_var == local_var)
    2859                 :             :                 {
    2860                 :             :                   have_outer_reduction = true;
    2861                 :             :                   break;
    2862                 :             :                 }
    2863                 :             :             }
    2864                 :        4277 :           if (have_outer_reduction)
    2865                 :             :             {
    2866                 :             :               /* There is a reduction on outer_var both on this loop and on
    2867                 :             :                  some enclosing loop.  Walk up the context tree until such a
    2868                 :             :                  loop with a reduction on outer_var is found, and complain
    2869                 :             :                  about all intervening loops that do not have such a
    2870                 :             :                  reduction.  */
    2871                 :        1817 :               struct omp_context *curr_loop = ctx->outer;
    2872                 :        1817 :               bool found = false;
    2873                 :        2299 :               while (curr_loop != NULL)
    2874                 :             :                 {
    2875                 :        2299 :                   tree curr_iter = curr_loop->local_reduction_clauses;
    2876                 :        2863 :                   for (; curr_iter; curr_iter = TREE_CHAIN (curr_iter))
    2877                 :             :                     {
    2878                 :        2381 :                       tree curr_clause = TREE_VALUE (curr_iter);
    2879                 :        2381 :                       tree curr_var = OMP_CLAUSE_DECL (curr_clause);
    2880                 :        2381 :                       if (curr_var == local_var)
    2881                 :             :                         {
    2882                 :             :                           found = true;
    2883                 :             :                           break;
    2884                 :             :                         }
    2885                 :             :                     }
    2886                 :        2299 :                   if (!found)
    2887                 :         482 :                     warning_at (gimple_location (curr_loop->stmt), OPT_Wopenmp,
    2888                 :             :                                 "nested loop in reduction needs "
    2889                 :             :                                 "reduction clause for %qE",
    2890                 :             :                                 local_var);
    2891                 :             :                   else
    2892                 :             :                     break;
    2893                 :         482 :                   curr_loop = curr_loop->outer;
    2894                 :             :                 }
    2895                 :             :             }
    2896                 :             :         }
    2897                 :       11875 :       ctx->local_reduction_clauses = local_reduction_clauses;
    2898                 :       11875 :       ctx->outer_reduction_clauses
    2899                 :       11875 :         = chainon (unshare_expr (ctx->local_reduction_clauses),
    2900                 :             :                    ctx->outer_reduction_clauses);
    2901                 :             : 
    2902                 :       11875 :       if (tgt && is_oacc_kernels (tgt))
    2903                 :             :         {
    2904                 :             :           /* Strip out reductions, as they are not handled yet.  */
    2905                 :             :           tree *prev_ptr = &clauses;
    2906                 :             : 
    2907                 :        8161 :           while (tree probe = *prev_ptr)
    2908                 :             :             {
    2909                 :        5472 :               tree *next_ptr = &OMP_CLAUSE_CHAIN (probe);
    2910                 :             : 
    2911                 :        5472 :               if (OMP_CLAUSE_CODE (probe) == OMP_CLAUSE_REDUCTION)
    2912                 :         839 :                 *prev_ptr = *next_ptr;
    2913                 :             :               else
    2914                 :             :                 prev_ptr = next_ptr;
    2915                 :             :             }
    2916                 :             : 
    2917                 :        2689 :           gimple_omp_for_set_clauses (stmt, clauses);
    2918                 :             :         }
    2919                 :             :     }
    2920                 :             : 
    2921                 :       53432 :   scan_sharing_clauses (clauses, ctx);
    2922                 :             : 
    2923                 :       53432 :   scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
    2924                 :      182276 :   for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
    2925                 :             :     {
    2926                 :       75412 :       scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
    2927                 :       75412 :       scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
    2928                 :       75412 :       scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
    2929                 :       75412 :       scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
    2930                 :             :     }
    2931                 :       53432 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    2932                 :       53432 :   return ctx;
    2933                 :             : }
    2934                 :             : 
    2935                 :             : /* Duplicate #pragma omp simd, one for SIMT, another one for SIMD.  */
    2936                 :             : 
    2937                 :             : static void
    2938                 :           0 : scan_omp_simd (gimple_stmt_iterator *gsi, gomp_for *stmt,
    2939                 :             :                omp_context *outer_ctx)
    2940                 :             : {
    2941                 :           0 :   gbind *bind = gimple_build_bind (NULL, NULL, NULL);
    2942                 :           0 :   gsi_replace (gsi, bind, false);
    2943                 :           0 :   gimple_seq seq = NULL;
    2944                 :           0 :   gimple *g = gimple_build_call_internal (IFN_GOMP_USE_SIMT, 0);
    2945                 :           0 :   tree cond = create_tmp_var_raw (integer_type_node);
    2946                 :           0 :   DECL_CONTEXT (cond) = current_function_decl;
    2947                 :           0 :   DECL_SEEN_IN_BIND_EXPR_P (cond) = 1;
    2948                 :           0 :   gimple_bind_set_vars (bind, cond);
    2949                 :           0 :   gimple_call_set_lhs (g, cond);
    2950                 :           0 :   gimple_seq_add_stmt (&seq, g);
    2951                 :           0 :   tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
    2952                 :           0 :   tree lab2 = create_artificial_label (UNKNOWN_LOCATION);
    2953                 :           0 :   tree lab3 = create_artificial_label (UNKNOWN_LOCATION);
    2954                 :           0 :   g = gimple_build_cond (NE_EXPR, cond, integer_zero_node, lab1, lab2);
    2955                 :           0 :   gimple_seq_add_stmt (&seq, g);
    2956                 :           0 :   g = gimple_build_label (lab1);
    2957                 :           0 :   gimple_seq_add_stmt (&seq, g);
    2958                 :           0 :   gimple_seq new_seq = copy_gimple_seq_and_replace_locals (stmt);
    2959                 :           0 :   gomp_for *new_stmt = as_a <gomp_for *> (new_seq);
    2960                 :           0 :   tree clause = build_omp_clause (gimple_location (stmt), OMP_CLAUSE__SIMT_);
    2961                 :           0 :   OMP_CLAUSE_CHAIN (clause) = gimple_omp_for_clauses (new_stmt);
    2962                 :           0 :   gimple_omp_for_set_clauses (new_stmt, clause);
    2963                 :           0 :   gimple_seq_add_stmt (&seq, new_stmt);
    2964                 :           0 :   g = gimple_build_goto (lab3);
    2965                 :           0 :   gimple_seq_add_stmt (&seq, g);
    2966                 :           0 :   g = gimple_build_label (lab2);
    2967                 :           0 :   gimple_seq_add_stmt (&seq, g);
    2968                 :           0 :   gimple_seq_add_stmt (&seq, stmt);
    2969                 :           0 :   g = gimple_build_label (lab3);
    2970                 :           0 :   gimple_seq_add_stmt (&seq, g);
    2971                 :           0 :   gimple_bind_set_body (bind, seq);
    2972                 :           0 :   update_stmt (bind);
    2973                 :           0 :   scan_omp_for (new_stmt, outer_ctx);
    2974                 :           0 :   scan_omp_for (stmt, outer_ctx)->simt_stmt = new_stmt;
    2975                 :           0 : }
    2976                 :             : 
    2977                 :             : static tree omp_find_scan (gimple_stmt_iterator *, bool *,
    2978                 :             :                            struct walk_stmt_info *);
    2979                 :             : static omp_context *maybe_lookup_ctx (gimple *);
    2980                 :             : 
    2981                 :             : /* Duplicate #pragma omp simd, one for the scan input phase loop and one
    2982                 :             :    for scan phase loop.  */
    2983                 :             : 
    2984                 :             : static void
    2985                 :          84 : scan_omp_simd_scan (gimple_stmt_iterator *gsi, gomp_for *stmt,
    2986                 :             :                     omp_context *outer_ctx)
    2987                 :             : {
    2988                 :             :   /* The only change between inclusive and exclusive scan will be
    2989                 :             :      within the first simd loop, so just use inclusive in the
    2990                 :             :      worksharing loop.  */
    2991                 :          84 :   outer_ctx->scan_inclusive = true;
    2992                 :          84 :   tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_INCLUSIVE);
    2993                 :          84 :   OMP_CLAUSE_DECL (c) = integer_zero_node;
    2994                 :             : 
    2995                 :          84 :   gomp_scan *input_stmt = gimple_build_omp_scan (NULL, NULL_TREE);
    2996                 :          84 :   gomp_scan *scan_stmt = gimple_build_omp_scan (NULL, c);
    2997                 :          84 :   gsi_replace (gsi, input_stmt, false);
    2998                 :          84 :   gimple_seq input_body = NULL;
    2999                 :          84 :   gimple_seq_add_stmt (&input_body, stmt);
    3000                 :          84 :   gsi_insert_after (gsi, scan_stmt, GSI_NEW_STMT);
    3001                 :             : 
    3002                 :          84 :   gimple_stmt_iterator input1_gsi = gsi_none ();
    3003                 :          84 :   struct walk_stmt_info wi;
    3004                 :          84 :   memset (&wi, 0, sizeof (wi));
    3005                 :          84 :   wi.val_only = true;
    3006                 :          84 :   wi.info = (void *) &input1_gsi;
    3007                 :          84 :   walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), omp_find_scan, NULL, &wi);
    3008                 :          84 :   gcc_assert (!gsi_end_p (input1_gsi));
    3009                 :             : 
    3010                 :          84 :   gimple *input_stmt1 = gsi_stmt (input1_gsi);
    3011                 :          84 :   gsi_next (&input1_gsi);
    3012                 :          84 :   gimple *scan_stmt1 = gsi_stmt (input1_gsi);
    3013                 :          84 :   gcc_assert (scan_stmt1 && gimple_code (scan_stmt1) == GIMPLE_OMP_SCAN);
    3014                 :          84 :   c = gimple_omp_scan_clauses (as_a <gomp_scan *> (scan_stmt1));
    3015                 :         168 :   if (c && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_EXCLUSIVE)
    3016                 :             :     std::swap (input_stmt1, scan_stmt1);
    3017                 :             : 
    3018                 :          84 :   gimple_seq input_body1 = gimple_omp_body (input_stmt1);
    3019                 :          84 :   gimple_omp_set_body (input_stmt1, NULL);
    3020                 :             : 
    3021                 :          84 :   gimple_seq scan_body = copy_gimple_seq_and_replace_locals (stmt);
    3022                 :          84 :   gomp_for *new_stmt = as_a <gomp_for *> (scan_body);
    3023                 :             : 
    3024                 :          84 :   gimple_omp_set_body (input_stmt1, input_body1);
    3025                 :          84 :   gimple_omp_set_body (scan_stmt1, NULL);
    3026                 :             : 
    3027                 :          84 :   gimple_stmt_iterator input2_gsi = gsi_none ();
    3028                 :          84 :   memset (&wi, 0, sizeof (wi));
    3029                 :          84 :   wi.val_only = true;
    3030                 :          84 :   wi.info = (void *) &input2_gsi;
    3031                 :          84 :   walk_gimple_seq_mod (gimple_omp_body_ptr (new_stmt), omp_find_scan,
    3032                 :             :                        NULL, &wi);
    3033                 :          84 :   gcc_assert (!gsi_end_p (input2_gsi));
    3034                 :             : 
    3035                 :          84 :   gimple *input_stmt2 = gsi_stmt (input2_gsi);
    3036                 :          84 :   gsi_next (&input2_gsi);
    3037                 :          84 :   gimple *scan_stmt2 = gsi_stmt (input2_gsi);
    3038                 :          84 :   gcc_assert (scan_stmt2 && gimple_code (scan_stmt2) == GIMPLE_OMP_SCAN);
    3039                 :         168 :   if (c && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_EXCLUSIVE)
    3040                 :             :     std::swap (input_stmt2, scan_stmt2);
    3041                 :             : 
    3042                 :          84 :   gimple_omp_set_body (input_stmt2, NULL);
    3043                 :             : 
    3044                 :          84 :   gimple_omp_set_body (input_stmt, input_body);
    3045                 :          84 :   gimple_omp_set_body (scan_stmt, scan_body);
    3046                 :             : 
    3047                 :          84 :   omp_context *ctx = new_omp_context (input_stmt, outer_ctx);
    3048                 :          84 :   scan_omp (gimple_omp_body_ptr (input_stmt), ctx);
    3049                 :             : 
    3050                 :          84 :   ctx = new_omp_context (scan_stmt, outer_ctx);
    3051                 :          84 :   scan_omp (gimple_omp_body_ptr (scan_stmt), ctx);
    3052                 :             : 
    3053                 :          84 :   maybe_lookup_ctx (new_stmt)->for_simd_scan_phase = true;
    3054                 :          84 : }
    3055                 :             : 
    3056                 :             : /* Scan an OpenMP sections directive.  */
    3057                 :             : 
    3058                 :             : static void
    3059                 :         676 : scan_omp_sections (gomp_sections *stmt, omp_context *outer_ctx)
    3060                 :             : {
    3061                 :         676 :   omp_context *ctx;
    3062                 :             : 
    3063                 :         676 :   ctx = new_omp_context (stmt, outer_ctx);
    3064                 :         676 :   scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
    3065                 :         676 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    3066                 :         676 : }
    3067                 :             : 
    3068                 :             : /* Scan an OpenMP single directive.  */
    3069                 :             : 
    3070                 :             : static void
    3071                 :        1288 : scan_omp_single (gomp_single *stmt, omp_context *outer_ctx)
    3072                 :             : {
    3073                 :        1288 :   omp_context *ctx;
    3074                 :        1288 :   tree name;
    3075                 :             : 
    3076                 :        1288 :   ctx = new_omp_context (stmt, outer_ctx);
    3077                 :        1288 :   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
    3078                 :        1288 :   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
    3079                 :        1288 :   name = create_tmp_var_name (".omp_copy_s");
    3080                 :        1288 :   name = build_decl (gimple_location (stmt),
    3081                 :             :                      TYPE_DECL, name, ctx->record_type);
    3082                 :        1288 :   TYPE_NAME (ctx->record_type) = name;
    3083                 :             : 
    3084                 :        1288 :   scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
    3085                 :        1288 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    3086                 :             : 
    3087                 :        1288 :   if (TYPE_FIELDS (ctx->record_type) == NULL)
    3088                 :        1129 :     ctx->record_type = NULL;
    3089                 :             :   else
    3090                 :         159 :     layout_type (ctx->record_type);
    3091                 :        1288 : }
    3092                 :             : 
    3093                 :             : /* Scan a GIMPLE_OMP_TARGET.  */
    3094                 :             : 
    3095                 :             : static void
    3096                 :       40496 : scan_omp_target (gomp_target *stmt, omp_context *outer_ctx)
    3097                 :             : {
    3098                 :       40496 :   omp_context *ctx;
    3099                 :       40496 :   tree name;
    3100                 :       40496 :   bool offloaded = is_gimple_omp_offloaded (stmt);
    3101                 :       40496 :   tree clauses = gimple_omp_target_clauses (stmt);
    3102                 :             : 
    3103                 :       40496 :   ctx = new_omp_context (stmt, outer_ctx);
    3104                 :       40496 :   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
    3105                 :       40496 :   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
    3106                 :       40496 :   name = create_tmp_var_name (".omp_data_t");
    3107                 :       40496 :   name = build_decl (gimple_location (stmt),
    3108                 :             :                      TYPE_DECL, name, ctx->record_type);
    3109                 :       40496 :   DECL_ARTIFICIAL (name) = 1;
    3110                 :       40496 :   DECL_NAMELESS (name) = 1;
    3111                 :       40496 :   TYPE_NAME (ctx->record_type) = name;
    3112                 :       40496 :   TYPE_ARTIFICIAL (ctx->record_type) = 1;
    3113                 :             : 
    3114                 :       40496 :   if (offloaded)
    3115                 :             :     {
    3116                 :       23717 :       create_omp_child_function (ctx, false);
    3117                 :       23717 :       gimple_omp_target_set_child_fn (stmt, ctx->cb.dst_fn);
    3118                 :             :     }
    3119                 :             : 
    3120                 :       40496 :   scan_sharing_clauses (clauses, ctx);
    3121                 :       40496 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    3122                 :             : 
    3123                 :       40496 :   if (TYPE_FIELDS (ctx->record_type) == NULL)
    3124                 :        7783 :     ctx->record_type = ctx->receiver_decl = NULL;
    3125                 :             :   else
    3126                 :             :     {
    3127                 :       32713 :       TYPE_FIELDS (ctx->record_type)
    3128                 :       32713 :         = nreverse (TYPE_FIELDS (ctx->record_type));
    3129                 :       32713 :       if (flag_checking)
    3130                 :             :         {
    3131                 :       32713 :           unsigned int align = DECL_ALIGN (TYPE_FIELDS (ctx->record_type));
    3132                 :       32713 :           for (tree field = TYPE_FIELDS (ctx->record_type);
    3133                 :      124612 :                field;
    3134                 :       91899 :                field = DECL_CHAIN (field))
    3135                 :       91899 :             gcc_assert (DECL_ALIGN (field) == align);
    3136                 :             :         }
    3137                 :       32713 :       layout_type (ctx->record_type);
    3138                 :       32713 :       if (offloaded)
    3139                 :       16412 :         fixup_child_record_type (ctx);
    3140                 :             :     }
    3141                 :             : 
    3142                 :       40496 :   if (ctx->teams_nested_p && ctx->nonteams_nested_p)
    3143                 :             :     {
    3144                 :           5 :       error_at (gimple_location (stmt),
    3145                 :             :                 "%<target%> construct with nested %<teams%> construct "
    3146                 :             :                 "contains directives outside of the %<teams%> construct");
    3147                 :           5 :       gimple_omp_set_body (stmt, gimple_build_bind (NULL, NULL, NULL));
    3148                 :             :     }
    3149                 :       40496 : }
    3150                 :             : 
    3151                 :             : /* Scan an OpenMP teams directive.  */
    3152                 :             : 
    3153                 :             : static void
    3154                 :        8990 : scan_omp_teams (gomp_teams *stmt, omp_context *outer_ctx)
    3155                 :             : {
    3156                 :        8990 :   omp_context *ctx = new_omp_context (stmt, outer_ctx);
    3157                 :             : 
    3158                 :        8990 :   if (!gimple_omp_teams_host (stmt))
    3159                 :             :     {
    3160                 :        6217 :       scan_sharing_clauses (gimple_omp_teams_clauses (stmt), ctx);
    3161                 :        6217 :       scan_omp (gimple_omp_body_ptr (stmt), ctx);
    3162                 :        6217 :       return;
    3163                 :             :     }
    3164                 :        2773 :   taskreg_contexts.safe_push (ctx);
    3165                 :        2773 :   gcc_assert (taskreg_nesting_level == 1);
    3166                 :        2773 :   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
    3167                 :        2773 :   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
    3168                 :        2773 :   tree name = create_tmp_var_name (".omp_data_s");
    3169                 :        2773 :   name = build_decl (gimple_location (stmt),
    3170                 :             :                      TYPE_DECL, name, ctx->record_type);
    3171                 :        2773 :   DECL_ARTIFICIAL (name) = 1;
    3172                 :        2773 :   DECL_NAMELESS (name) = 1;
    3173                 :        2773 :   TYPE_NAME (ctx->record_type) = name;
    3174                 :        2773 :   TYPE_ARTIFICIAL (ctx->record_type) = 1;
    3175                 :        2773 :   create_omp_child_function (ctx, false);
    3176                 :        2773 :   gimple_omp_teams_set_child_fn (stmt, ctx->cb.dst_fn);
    3177                 :             : 
    3178                 :        2773 :   scan_sharing_clauses (gimple_omp_teams_clauses (stmt), ctx);
    3179                 :        2773 :   scan_omp (gimple_omp_body_ptr (stmt), ctx);
    3180                 :             : 
    3181                 :        2773 :   if (TYPE_FIELDS (ctx->record_type) == NULL)
    3182                 :        1499 :     ctx->record_type = ctx->receiver_decl = NULL;
    3183                 :             : }
    3184                 :             : 
    3185                 :             : /* Check nesting restrictions.  */
    3186                 :             : static bool
    3187                 :      158439 : check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
    3188                 :             : {
    3189                 :      158439 :   tree c;
    3190                 :             : 
    3191                 :             :   /* No nesting of non-OpenACC STMT (that is, an OpenMP one, or a GOMP builtin)
    3192                 :             :      inside an OpenACC CTX.  */
    3193                 :      158439 :   if (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
    3194                 :      158439 :       || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE)
    3195                 :             :     /* ..., except for the atomic codes that OpenACC shares with OpenMP.  */
    3196                 :             :     ;
    3197                 :      282141 :   else if (!(is_gimple_omp (stmt)
    3198                 :      138662 :              && is_gimple_omp_oacc (stmt)))
    3199                 :             :     {
    3200                 :      113689 :       if (oacc_get_fn_attrib (cfun->decl) != NULL)
    3201                 :             :         {
    3202                 :          60 :           error_at (gimple_location (stmt),
    3203                 :             :                     "non-OpenACC construct inside of OpenACC routine");
    3204                 :          60 :           return false;
    3205                 :             :         }
    3206                 :             :       else
    3207                 :      241433 :         for (omp_context *octx = ctx; octx != NULL; octx = octx->outer)
    3208                 :      255773 :           if (is_gimple_omp (octx->stmt)
    3209                 :      127969 :               && is_gimple_omp_oacc (octx->stmt))
    3210                 :             :             {
    3211                 :         165 :               error_at (gimple_location (stmt),
    3212                 :             :                         "non-OpenACC construct inside of OpenACC region");
    3213                 :         165 :               return false;
    3214                 :             :             }
    3215                 :             :     }
    3216                 :             : 
    3217                 :      158214 :   if (ctx != NULL)
    3218                 :             :     {
    3219                 :       85676 :       if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
    3220                 :       85676 :           && gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_REGION)
    3221                 :             :         {
    3222                 :        8449 :           c = omp_find_clause (gimple_omp_target_clauses (ctx->stmt),
    3223                 :             :                                OMP_CLAUSE_DEVICE);
    3224                 :        8449 :           if (c && OMP_CLAUSE_DEVICE_ANCESTOR (c))
    3225                 :             :             {
    3226                 :          11 :               error_at (gimple_location (stmt),
    3227                 :             :                         "OpenMP constructs are not allowed in target region "
    3228                 :             :                         "with %<ancestor%>");
    3229                 :          11 :               return false;
    3230                 :             :             }
    3231                 :             : 
    3232                 :        8438 :           if (gimple_code (stmt) == GIMPLE_OMP_TEAMS && !ctx->teams_nested_p)
    3233                 :        6212 :             ctx->teams_nested_p = true;
    3234                 :             :           else
    3235                 :        2226 :             ctx->nonteams_nested_p = true;
    3236                 :             :         }
    3237                 :       85665 :       if (gimple_code (ctx->stmt) == GIMPLE_OMP_SCAN
    3238                 :         174 :           && ctx->outer
    3239                 :       85839 :           && gimple_code (ctx->outer->stmt) == GIMPLE_OMP_FOR)
    3240                 :             :         ctx = ctx->outer;
    3241                 :       85665 :       if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    3242                 :       29068 :           && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
    3243                 :       87712 :           && !ctx->loop_p)
    3244                 :             :         {
    3245                 :        1786 :           c = NULL_TREE;
    3246                 :        1786 :           if (ctx->order_concurrent
    3247                 :        1786 :               && (gimple_code (stmt) == GIMPLE_OMP_ORDERED
    3248                 :         336 :                   || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
    3249                 :         228 :                   || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE))
    3250                 :             :             {
    3251                 :         252 :               error_at (gimple_location (stmt),
    3252                 :             :                         "OpenMP constructs other than %<parallel%>, %<loop%>"
    3253                 :             :                         " or %<simd%> may not be nested inside a region with"
    3254                 :             :                         " the %<order(concurrent)%> clause");
    3255                 :         252 :               return false;
    3256                 :             :             }
    3257                 :        1534 :           if (gimple_code (stmt) == GIMPLE_OMP_ORDERED)
    3258                 :             :             {
    3259                 :         162 :               c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
    3260                 :         162 :               if (omp_find_clause (c, OMP_CLAUSE_SIMD))
    3261                 :             :                 {
    3262                 :         162 :                   if (omp_find_clause (c, OMP_CLAUSE_THREADS)
    3263                 :         162 :                       && (ctx->outer == NULL
    3264                 :          36 :                           || !gimple_omp_for_combined_into_p (ctx->stmt)
    3265                 :          31 :                           || gimple_code (ctx->outer->stmt) != GIMPLE_OMP_FOR
    3266                 :          31 :                           || (gimple_omp_for_kind (ctx->outer->stmt)
    3267                 :             :                               != GF_OMP_FOR_KIND_FOR)
    3268                 :          31 :                           || !gimple_omp_for_combined_p (ctx->outer->stmt)))
    3269                 :             :                     {
    3270                 :          10 :                       error_at (gimple_location (stmt),
    3271                 :             :                                 "%<ordered simd threads%> must be closely "
    3272                 :             :                                 "nested inside of %<%s simd%> region",
    3273                 :          10 :                                 lang_GNU_Fortran () ? "do" : "for");
    3274                 :          10 :                       return false;
    3275                 :             :                     }
    3276                 :             :                   return true;
    3277                 :             :                 }
    3278                 :             :             }
    3279                 :        1372 :           else if (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
    3280                 :        1329 :                    || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE
    3281                 :        2658 :                    || gimple_code (stmt) == GIMPLE_OMP_SCAN)
    3282                 :             :             return true;
    3283                 :         140 :           else if (gimple_code (stmt) == GIMPLE_OMP_FOR
    3284                 :         140 :                    && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
    3285                 :             :             return true;
    3286                 :          72 :           error_at (gimple_location (stmt),
    3287                 :             :                     "OpenMP constructs other than "
    3288                 :             :                     "%<ordered simd%>, %<simd%>, %<loop%> or %<atomic%> may "
    3289                 :             :                     "not be nested inside %<simd%> region");
    3290                 :          72 :           return false;
    3291                 :             :         }
    3292                 :       83879 :       else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
    3293                 :             :         {
    3294                 :        6044 :           if ((gimple_code (stmt) != GIMPLE_OMP_FOR
    3295                 :        5747 :                || (gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_DISTRIBUTE
    3296                 :          31 :                    && omp_find_clause (gimple_omp_for_clauses (stmt),
    3297                 :             :                                        OMP_CLAUSE_BIND) == NULL_TREE))
    3298                 :        6064 :               && gimple_code (stmt) != GIMPLE_OMP_PARALLEL)
    3299                 :             :             {
    3300                 :         163 :               error_at (gimple_location (stmt),
    3301                 :             :                         "only %<distribute%>, %<parallel%> or %<loop%> "
    3302                 :             :                         "regions are allowed to be strictly nested inside "
    3303                 :             :                         "%<teams%> region");
    3304                 :         163 :               return false;
    3305                 :             :             }
    3306                 :             :         }
    3307                 :       77835 :       else if (ctx->order_concurrent
    3308                 :        2216 :                && gimple_code (stmt) != GIMPLE_OMP_PARALLEL
    3309                 :        1680 :                && (gimple_code (stmt) != GIMPLE_OMP_FOR
    3310                 :        1356 :                    || gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_SIMD)
    3311                 :       78177 :                && gimple_code (stmt) != GIMPLE_OMP_SCAN)
    3312                 :             :         {
    3313                 :         342 :           if (ctx->loop_p)
    3314                 :         162 :             error_at (gimple_location (stmt),
    3315                 :             :                       "OpenMP constructs other than %<parallel%>, %<loop%> or "
    3316                 :             :                       "%<simd%> may not be nested inside a %<loop%> region");
    3317                 :             :           else
    3318                 :         180 :             error_at (gimple_location (stmt),
    3319                 :             :                       "OpenMP constructs other than %<parallel%>, %<loop%> or "
    3320                 :             :                       "%<simd%> may not be nested inside a region with "
    3321                 :             :                       "the %<order(concurrent)%> clause");
    3322                 :         342 :           return false;
    3323                 :             :         }
    3324                 :             :     }
    3325                 :      155912 :   switch (gimple_code (stmt))
    3326                 :             :     {
    3327                 :       53557 :     case GIMPLE_OMP_FOR:
    3328                 :       53557 :       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD)
    3329                 :             :         return true;
    3330                 :       42024 :       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
    3331                 :             :         {
    3332                 :        8494 :           if (ctx != NULL && gimple_code (ctx->stmt) != GIMPLE_OMP_TEAMS)
    3333                 :             :             {
    3334                 :           0 :               error_at (gimple_location (stmt),
    3335                 :             :                         "%<distribute%> region must be strictly nested "
    3336                 :             :                         "inside %<teams%> construct");
    3337                 :           0 :               return false;
    3338                 :             :             }
    3339                 :             :           return true;
    3340                 :             :         }
    3341                 :             :       /* We split taskloop into task and nested taskloop in it.  */
    3342                 :       33530 :       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_TASKLOOP)
    3343                 :             :         return true;
    3344                 :             :       /* For now, hope this will change and loop bind(parallel) will not
    3345                 :             :          be allowed in lots of contexts.  */
    3346                 :       30176 :       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR
    3347                 :       48397 :           && omp_find_clause (gimple_omp_for_clauses (stmt), OMP_CLAUSE_BIND))
    3348                 :             :         return true;
    3349                 :       29478 :       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
    3350                 :             :         {
    3351                 :       11955 :           bool ok = false;
    3352                 :             : 
    3353                 :       11955 :           if (ctx)
    3354                 :       11314 :             switch (gimple_code (ctx->stmt))
    3355                 :             :               {
    3356                 :        3575 :               case GIMPLE_OMP_FOR:
    3357                 :        3575 :                 ok = (gimple_omp_for_kind (ctx->stmt)
    3358                 :             :                       == GF_OMP_FOR_KIND_OACC_LOOP);
    3359                 :        3575 :                 break;
    3360                 :             : 
    3361                 :        7704 :               case GIMPLE_OMP_TARGET:
    3362                 :        7704 :                 switch (gimple_omp_target_kind (ctx->stmt))
    3363                 :             :                   {
    3364                 :             :                   case GF_OMP_TARGET_KIND_OACC_PARALLEL:
    3365                 :             :                   case GF_OMP_TARGET_KIND_OACC_KERNELS:
    3366                 :             :                   case GF_OMP_TARGET_KIND_OACC_SERIAL:
    3367                 :             :                   case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
    3368                 :             :                   case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
    3369                 :             :                     ok = true;
    3370                 :             :                     break;
    3371                 :             : 
    3372                 :             :                   default:
    3373                 :             :                     break;
    3374                 :             :                   }
    3375                 :             : 
    3376                 :             :               default:
    3377                 :             :                 break;
    3378                 :             :               }
    3379                 :         641 :           else if (oacc_get_fn_attrib (current_function_decl))
    3380                 :             :             ok = true;
    3381                 :        3575 :           if (!ok)
    3382                 :             :             {
    3383                 :          80 :               error_at (gimple_location (stmt),
    3384                 :             :                         "OpenACC loop directive must be associated with"
    3385                 :             :                         " an OpenACC compute region");
    3386                 :          80 :               return false;
    3387                 :             :             }
    3388                 :             :         }
    3389                 :             :       /* FALLTHRU */
    3390                 :       34142 :     case GIMPLE_CALL:
    3391                 :       34142 :       if (is_gimple_call (stmt)
    3392                 :       34142 :           && (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3393                 :             :               == BUILT_IN_GOMP_CANCEL
    3394                 :        3459 :               || DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3395                 :             :                  == BUILT_IN_GOMP_CANCELLATION_POINT))
    3396                 :             :         {
    3397                 :        2240 :           const char *bad = NULL;
    3398                 :        2240 :           const char *kind = NULL;
    3399                 :        2240 :           const char *construct
    3400                 :        2240 :             = (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3401                 :             :                == BUILT_IN_GOMP_CANCEL)
    3402                 :        2240 :               ? "cancel"
    3403                 :        2240 :               : "cancellation point";
    3404                 :        2240 :           if (ctx == NULL)
    3405                 :             :             {
    3406                 :          49 :               error_at (gimple_location (stmt), "orphaned %qs construct",
    3407                 :             :                         construct);
    3408                 :          49 :               return false;
    3409                 :             :             }
    3410                 :        2191 :           switch (tree_fits_shwi_p (gimple_call_arg (stmt, 0))
    3411                 :        2191 :                   ? tree_to_shwi (gimple_call_arg (stmt, 0))
    3412                 :             :                   : 0)
    3413                 :             :             {
    3414                 :         614 :             case 1:
    3415                 :         614 :               if (gimple_code (ctx->stmt) != GIMPLE_OMP_PARALLEL)
    3416                 :             :                 bad = "parallel";
    3417                 :         230 :               else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3418                 :             :                        == BUILT_IN_GOMP_CANCEL
    3419                 :         230 :                        && !integer_zerop (gimple_call_arg (stmt, 1)))
    3420                 :         184 :                 ctx->cancellable = true;
    3421                 :         184 :               kind = "parallel";
    3422                 :         184 :               break;
    3423                 :         498 :             case 2:
    3424                 :         498 :               if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
    3425                 :         498 :                   || gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR)
    3426                 :             :                 bad = "for";
    3427                 :         126 :               else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3428                 :             :                        == BUILT_IN_GOMP_CANCEL
    3429                 :         126 :                        && !integer_zerop (gimple_call_arg (stmt, 1)))
    3430                 :             :                 {
    3431                 :         113 :                   ctx->cancellable = true;
    3432                 :         113 :                   if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    3433                 :             :                                        OMP_CLAUSE_NOWAIT))
    3434                 :           6 :                     warning_at (gimple_location (stmt), OPT_Wopenmp,
    3435                 :             :                                 "%<cancel for%> inside "
    3436                 :             :                                 "%<nowait%> for construct");
    3437                 :         113 :                   if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    3438                 :             :                                        OMP_CLAUSE_ORDERED))
    3439                 :           6 :                     warning_at (gimple_location (stmt), OPT_Wopenmp,
    3440                 :             :                                 "%<cancel for%> inside "
    3441                 :             :                                 "%<ordered%> for construct");
    3442                 :             :                 }
    3443                 :           6 :               kind = "for";
    3444                 :           6 :               break;
    3445                 :         453 :             case 4:
    3446                 :         453 :               if (gimple_code (ctx->stmt) != GIMPLE_OMP_SECTIONS
    3447                 :         453 :                   && gimple_code (ctx->stmt) != GIMPLE_OMP_SECTION)
    3448                 :             :                 bad = "sections";
    3449                 :         105 :               else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3450                 :             :                        == BUILT_IN_GOMP_CANCEL
    3451                 :         105 :                        && !integer_zerop (gimple_call_arg (stmt, 1)))
    3452                 :             :                 {
    3453                 :          81 :                   if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
    3454                 :             :                     {
    3455                 :           0 :                       ctx->cancellable = true;
    3456                 :           0 :                       if (omp_find_clause (gimple_omp_sections_clauses
    3457                 :           0 :                                                                 (ctx->stmt),
    3458                 :             :                                            OMP_CLAUSE_NOWAIT))
    3459                 :           0 :                         warning_at (gimple_location (stmt), OPT_Wopenmp,
    3460                 :             :                                     "%<cancel sections%> inside "
    3461                 :             :                                     "%<nowait%> sections construct");
    3462                 :             :                     }
    3463                 :             :                   else
    3464                 :             :                     {
    3465                 :          81 :                       gcc_assert (ctx->outer
    3466                 :             :                                   && gimple_code (ctx->outer->stmt)
    3467                 :             :                                      == GIMPLE_OMP_SECTIONS);
    3468                 :          81 :                       ctx->outer->cancellable = true;
    3469                 :          81 :                       if (omp_find_clause (gimple_omp_sections_clauses
    3470                 :          81 :                                                         (ctx->outer->stmt),
    3471                 :             :                                            OMP_CLAUSE_NOWAIT))
    3472                 :          12 :                         warning_at (gimple_location (stmt), OPT_Wopenmp,
    3473                 :             :                                     "%<cancel sections%> inside "
    3474                 :             :                                     "%<nowait%> sections construct");
    3475                 :             :                     }
    3476                 :             :                 }
    3477                 :          12 :               kind = "sections";
    3478                 :          12 :               break;
    3479                 :         626 :             case 8:
    3480                 :         626 :               if (!is_task_ctx (ctx)
    3481                 :         626 :                   && (!is_taskloop_ctx (ctx)
    3482                 :          64 :                       || ctx->outer == NULL
    3483                 :          64 :                       || !is_task_ctx (ctx->outer)))
    3484                 :             :                 bad = "task";
    3485                 :             :               else
    3486                 :             :                 {
    3487                 :         290 :                   for (omp_context *octx = ctx->outer;
    3488                 :         519 :                        octx; octx = octx->outer)
    3489                 :             :                     {
    3490                 :         503 :                       switch (gimple_code (octx->stmt))
    3491                 :             :                         {
    3492                 :             :                         case GIMPLE_OMP_TASKGROUP:
    3493                 :             :                           break;
    3494                 :          48 :                         case GIMPLE_OMP_TARGET:
    3495                 :          48 :                           if (gimple_omp_target_kind (octx->stmt)
    3496                 :             :                               != GF_OMP_TARGET_KIND_REGION)
    3497                 :          24 :                             continue;
    3498                 :             :                           /* FALLTHRU */
    3499                 :         119 :                         case GIMPLE_OMP_PARALLEL:
    3500                 :         119 :                         case GIMPLE_OMP_TEAMS:
    3501                 :         119 :                           error_at (gimple_location (stmt),
    3502                 :             :                                     "%<%s taskgroup%> construct not closely "
    3503                 :             :                                     "nested inside of %<taskgroup%> region",
    3504                 :             :                                     construct);
    3505                 :         119 :                           return false;
    3506                 :         124 :                         case GIMPLE_OMP_TASK:
    3507                 :         124 :                           if (gimple_omp_task_taskloop_p (octx->stmt)
    3508                 :         112 :                               && octx->outer
    3509                 :         236 :                               && is_taskloop_ctx (octx->outer))
    3510                 :             :                             {
    3511                 :         112 :                               tree clauses
    3512                 :         112 :                                 = gimple_omp_for_clauses (octx->outer->stmt);
    3513                 :         112 :                               if (!omp_find_clause (clauses, OMP_CLAUSE_NOGROUP))
    3514                 :             :                                 break;
    3515                 :             :                             }
    3516                 :          72 :                           continue;
    3517                 :         133 :                         default:
    3518                 :         133 :                           continue;
    3519                 :         205 :                         }
    3520                 :             :                       break;
    3521                 :             :                     }
    3522                 :         171 :                   ctx->cancellable = true;
    3523                 :             :                 }
    3524                 :         171 :               kind = "taskgroup";
    3525                 :         171 :               break;
    3526                 :           0 :             default:
    3527                 :           0 :               error_at (gimple_location (stmt), "invalid arguments");
    3528                 :           0 :               return false;
    3529                 :             :             }
    3530                 :         373 :           if (bad)
    3531                 :             :             {
    3532                 :        1440 :               error_at (gimple_location (stmt),
    3533                 :             :                         "%<%s %s%> construct not closely nested inside of %qs",
    3534                 :             :                         construct, kind, bad);
    3535                 :        1440 :               return false;
    3536                 :             :             }
    3537                 :             :         }
    3538                 :             :       /* FALLTHRU */
    3539                 :             :     case GIMPLE_OMP_SECTIONS:
    3540                 :             :     case GIMPLE_OMP_SINGLE:
    3541                 :       54024 :       for (; ctx != NULL; ctx = ctx->outer)
    3542                 :       35840 :         switch (gimple_code (ctx->stmt))
    3543                 :             :           {
    3544                 :        5995 :           case GIMPLE_OMP_FOR:
    3545                 :        5995 :             if (gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR
    3546                 :        5995 :                 && gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
    3547                 :             :               break;
    3548                 :             :             /* FALLTHRU */
    3549                 :         824 :           case GIMPLE_OMP_SECTIONS:
    3550                 :         824 :           case GIMPLE_OMP_SINGLE:
    3551                 :         824 :           case GIMPLE_OMP_ORDERED:
    3552                 :         824 :           case GIMPLE_OMP_MASTER:
    3553                 :         824 :           case GIMPLE_OMP_MASKED:
    3554                 :         824 :           case GIMPLE_OMP_TASK:
    3555                 :         824 :           case GIMPLE_OMP_CRITICAL:
    3556                 :         824 :             if (is_gimple_call (stmt))
    3557                 :             :               {
    3558                 :         749 :                 if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
    3559                 :             :                     != BUILT_IN_GOMP_BARRIER)
    3560                 :             :                   return true;
    3561                 :          24 :                 error_at (gimple_location (stmt),
    3562                 :             :                           "barrier region may not be closely nested inside "
    3563                 :             :                           "of work-sharing, %<loop%>, %<critical%>, "
    3564                 :             :                           "%<ordered%>, %<master%>, %<masked%>, explicit "
    3565                 :             :                           "%<task%> or %<taskloop%> region");
    3566                 :          24 :                 return false;
    3567                 :             :               }
    3568                 :          75 :             error_at (gimple_location (stmt),
    3569                 :             :                       "work-sharing region may not be closely nested inside "
    3570                 :             :                       "of work-sharing, %<loop%>, %<critical%>, %<ordered%>, "
    3571                 :             :                       "%<master%>, %<masked%>, explicit %<task%> or "
    3572                 :             :                       "%<taskloop%> region");
    3573                 :          75 :             return false;
    3574                 :             :           case GIMPLE_OMP_PARALLEL:
    3575                 :             :           case GIMPLE_OMP_TEAMS:
    3576                 :             :             return true;
    3577                 :       12800 :           case GIMPLE_OMP_TARGET:
    3578                 :       12800 :             if (gimple_omp_target_kind (ctx->stmt)
    3579                 :             :                 == GF_OMP_TARGET_KIND_REGION)
    3580                 :             :               return true;
    3581                 :             :             break;
    3582                 :             :           default:
    3583                 :             :             break;
    3584                 :             :           }
    3585                 :             :       break;
    3586                 :             :     case GIMPLE_OMP_MASTER:
    3587                 :             :     case GIMPLE_OMP_MASKED:
    3588                 :        1598 :       for (; ctx != NULL; ctx = ctx->outer)
    3589                 :        1029 :         switch (gimple_code (ctx->stmt))
    3590                 :             :           {
    3591                 :          16 :           case GIMPLE_OMP_FOR:
    3592                 :          16 :             if (gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR
    3593                 :          16 :                 && gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
    3594                 :             :               break;
    3595                 :             :             /* FALLTHRU */
    3596                 :          32 :           case GIMPLE_OMP_SECTIONS:
    3597                 :          32 :           case GIMPLE_OMP_SINGLE:
    3598                 :          32 :           case GIMPLE_OMP_TASK:
    3599                 :          64 :             error_at (gimple_location (stmt),
    3600                 :             :                       "%qs region may not be closely nested inside "
    3601                 :             :                       "of work-sharing, %<loop%>, explicit %<task%> or "
    3602                 :             :                       "%<taskloop%> region",
    3603                 :          32 :                       gimple_code (stmt) == GIMPLE_OMP_MASTER
    3604                 :             :                       ? "master" : "masked");
    3605                 :          32 :             return false;
    3606                 :             :           case GIMPLE_OMP_PARALLEL:
    3607                 :             :           case GIMPLE_OMP_TEAMS:
    3608                 :             :             return true;
    3609                 :          12 :           case GIMPLE_OMP_TARGET:
    3610                 :          12 :             if (gimple_omp_target_kind (ctx->stmt)
    3611                 :             :                 == GF_OMP_TARGET_KIND_REGION)
    3612                 :             :               return true;
    3613                 :             :             break;
    3614                 :             :           default:
    3615                 :             :             break;
    3616                 :             :           }
    3617                 :             :       break;
    3618                 :             :     case GIMPLE_OMP_SCOPE:
    3619                 :         304 :       for (; ctx != NULL; ctx = ctx->outer)
    3620                 :         191 :         switch (gimple_code (ctx->stmt))
    3621                 :             :           {
    3622                 :           8 :           case GIMPLE_OMP_FOR:
    3623                 :           8 :             if (gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR
    3624                 :           8 :                 && gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
    3625                 :             :               break;
    3626                 :             :             /* FALLTHRU */
    3627                 :          26 :           case GIMPLE_OMP_SECTIONS:
    3628                 :          26 :           case GIMPLE_OMP_SINGLE:
    3629                 :          26 :           case GIMPLE_OMP_TASK:
    3630                 :          26 :           case GIMPLE_OMP_CRITICAL:
    3631                 :          26 :           case GIMPLE_OMP_ORDERED:
    3632                 :          26 :           case GIMPLE_OMP_MASTER:
    3633                 :          26 :           case GIMPLE_OMP_MASKED:
    3634                 :          26 :             error_at (gimple_location (stmt),
    3635                 :             :                       "%<scope%> region may not be closely nested inside "
    3636                 :             :                       "of work-sharing, %<loop%>, explicit %<task%>, "
    3637                 :             :                       "%<taskloop%>, %<critical%>, %<ordered%>, %<master%>, "
    3638                 :             :                       "or %<masked%> region");
    3639                 :          26 :             return false;
    3640                 :             :           case GIMPLE_OMP_PARALLEL:
    3641                 :             :           case GIMPLE_OMP_TEAMS:
    3642                 :             :             return true;
    3643                 :           6 :           case GIMPLE_OMP_TARGET:
    3644                 :           6 :             if (gimple_omp_target_kind (ctx->stmt)
    3645                 :             :                 == GF_OMP_TARGET_KIND_REGION)
    3646                 :             :               return true;
    3647                 :             :             break;
    3648                 :             :           default:
    3649                 :             :             break;
    3650                 :             :           }
    3651                 :             :       break;
    3652                 :        6093 :     case GIMPLE_OMP_TASK:
    3653                 :       23904 :       for (c = gimple_omp_task_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
    3654                 :       17816 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS)
    3655                 :             :           {
    3656                 :           5 :             enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_KIND (c);
    3657                 :           5 :             error_at (OMP_CLAUSE_LOCATION (c),
    3658                 :             :                       "%<%s(%s)%> is only allowed in %<omp ordered%>",
    3659                 :           5 :                       OMP_CLAUSE_DOACROSS_DEPEND (c) ? "depend" : "doacross",
    3660                 :             :                       kind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
    3661                 :           5 :             return false;
    3662                 :             :           }
    3663                 :             :       break;
    3664                 :        1831 :     case GIMPLE_OMP_ORDERED:
    3665                 :        3219 :       for (c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
    3666                 :        3219 :            c; c = OMP_CLAUSE_CHAIN (c))
    3667                 :             :         {
    3668                 :        1408 :           if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DOACROSS)
    3669                 :             :             {
    3670                 :         205 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
    3671                 :             :                 {
    3672                 :           5 :                   error_at (OMP_CLAUSE_LOCATION (c),
    3673                 :             :                             "invalid depend kind in omp %<ordered%> %<depend%>");
    3674                 :           5 :                   return false;
    3675                 :             :                 }
    3676                 :         200 :               gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREADS
    3677                 :             :                           || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SIMD);
    3678                 :         200 :               continue;
    3679                 :             :             }
    3680                 :             : 
    3681                 :        1203 :           tree oclause;
    3682                 :             :           /* Look for containing ordered(N) loop.  */
    3683                 :        1203 :           if (ctx == NULL
    3684                 :        1188 :               || gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
    3685                 :        1203 :               || (oclause
    3686                 :        1188 :                   = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    3687                 :             :                                      OMP_CLAUSE_ORDERED)) == NULL_TREE)
    3688                 :             :             {
    3689                 :          15 :               error_at (OMP_CLAUSE_LOCATION (c),
    3690                 :             :                         "%<ordered%> construct with %<depend%> clause "
    3691                 :             :                         "must be closely nested inside an %<ordered%> loop");
    3692                 :          15 :               return false;
    3693                 :             :             }
    3694                 :             :         }
    3695                 :        1811 :       c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
    3696                 :        1811 :       if (omp_find_clause (c, OMP_CLAUSE_SIMD))
    3697                 :             :         {
    3698                 :             :           /* ordered simd must be closely nested inside of simd region,
    3699                 :             :              and simd region must not encounter constructs other than
    3700                 :             :              ordered simd, therefore ordered simd may be either orphaned,
    3701                 :             :              or ctx->stmt must be simd.  The latter case is handled already
    3702                 :             :              earlier.  */
    3703                 :          42 :           if (ctx != NULL)
    3704                 :             :             {
    3705                 :          12 :               error_at (gimple_location (stmt),
    3706                 :             :                         "%<ordered%> %<simd%> must be closely nested inside "
    3707                 :             :                         "%<simd%> region");
    3708                 :          12 :               return false;
    3709                 :             :             }
    3710                 :             :         }
    3711                 :        1799 :       for (; ctx != NULL; ctx = ctx->outer)
    3712                 :        1638 :         switch (gimple_code (ctx->stmt))
    3713                 :             :           {
    3714                 :          45 :           case GIMPLE_OMP_CRITICAL:
    3715                 :          45 :           case GIMPLE_OMP_TASK:
    3716                 :          45 :           case GIMPLE_OMP_ORDERED:
    3717                 :          45 :           ordered_in_taskloop:
    3718                 :          45 :             error_at (gimple_location (stmt),
    3719                 :             :                       "%<ordered%> region may not be closely nested inside "
    3720                 :             :                       "of %<critical%>, %<ordered%>, explicit %<task%> or "
    3721                 :             :                       "%<taskloop%> region");
    3722                 :          45 :             return false;
    3723                 :        1569 :           case GIMPLE_OMP_FOR:
    3724                 :        1569 :             if (gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_TASKLOOP)
    3725                 :          12 :               goto ordered_in_taskloop;
    3726                 :        1557 :             tree o;
    3727                 :        1557 :             o = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    3728                 :             :                                  OMP_CLAUSE_ORDERED);
    3729                 :        1557 :             if (o == NULL)
    3730                 :             :               {
    3731                 :          27 :                 error_at (gimple_location (stmt),
    3732                 :             :                           "%<ordered%> region must be closely nested inside "
    3733                 :             :                           "a loop region with an %<ordered%> clause");
    3734                 :          27 :                 return false;
    3735                 :             :               }
    3736                 :        1530 :             if (!gimple_omp_ordered_standalone_p (stmt))
    3737                 :             :               {
    3738                 :         404 :                 if (OMP_CLAUSE_ORDERED_DOACROSS (o))
    3739                 :             :                   {
    3740                 :          12 :                     error_at (gimple_location (stmt),
    3741                 :             :                               "%<ordered%> construct without %<doacross%> or "
    3742                 :             :                               "%<depend%> clauses must not have the same "
    3743                 :             :                               "binding region as %<ordered%> construct with "
    3744                 :             :                               "those clauses");
    3745                 :          12 :                     return false;
    3746                 :             :                   }
    3747                 :         392 :                 else if (OMP_CLAUSE_ORDERED_EXPR (o))
    3748                 :             :                   {
    3749                 :          28 :                     tree co
    3750                 :          28 :                       = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    3751                 :             :                                          OMP_CLAUSE_COLLAPSE);
    3752                 :          28 :                     HOST_WIDE_INT
    3753                 :          28 :                       o_n = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (o));
    3754                 :          28 :                     HOST_WIDE_INT c_n = 1;
    3755                 :          28 :                     if (co)
    3756                 :           6 :                       c_n = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (co));
    3757                 :          28 :                     if (o_n != c_n)
    3758                 :             :                       {
    3759                 :          12 :                         error_at (gimple_location (stmt),
    3760                 :             :                                   "%<ordered%> construct without %<doacross%> "
    3761                 :             :                                   "or %<depend%> clauses binds to loop where "
    3762                 :             :                                   "%<collapse%> argument %wd is different from "
    3763                 :             :                                   "%<ordered%> argument %wd", c_n, o_n);
    3764                 :          12 :                         return false;
    3765                 :             :                       }
    3766                 :             :                   }
    3767                 :             :               }
    3768                 :             :             return true;
    3769                 :          12 :           case GIMPLE_OMP_TARGET:
    3770                 :          12 :             if (gimple_omp_target_kind (ctx->stmt)
    3771                 :             :                 != GF_OMP_TARGET_KIND_REGION)
    3772                 :             :               break;
    3773                 :             :             /* FALLTHRU */
    3774                 :          36 :           case GIMPLE_OMP_PARALLEL:
    3775                 :          36 :           case GIMPLE_OMP_TEAMS:
    3776                 :          36 :             error_at (gimple_location (stmt),
    3777                 :             :                       "%<ordered%> region must be closely nested inside "
    3778                 :             :                       "a loop region with an %<ordered%> clause");
    3779                 :          36 :             return false;
    3780                 :             :           default:
    3781                 :             :             break;
    3782                 :             :           }
    3783                 :             :       break;
    3784                 :         508 :     case GIMPLE_OMP_CRITICAL:
    3785                 :         508 :       {
    3786                 :         508 :         tree this_stmt_name
    3787                 :         508 :           = gimple_omp_critical_name (as_a <gomp_critical *> (stmt));
    3788                 :         947 :         for (; ctx != NULL; ctx = ctx->outer)
    3789                 :         445 :           if (gomp_critical *other_crit
    3790                 :         465 :                 = dyn_cast <gomp_critical *> (ctx->stmt))
    3791                 :          26 :             if (this_stmt_name == gimple_omp_critical_name (other_crit))
    3792                 :             :               {
    3793                 :           6 :                 error_at (gimple_location (stmt),
    3794                 :             :                           "%<critical%> region may not be nested inside "
    3795                 :             :                            "a %<critical%> region with the same name");
    3796                 :           6 :                 return false;
    3797                 :             :               }
    3798                 :             :       }
    3799                 :             :       break;
    3800                 :        9045 :     case GIMPLE_OMP_TEAMS:
    3801                 :        9045 :       if (ctx == NULL)
    3802                 :             :         break;
    3803                 :        6272 :       else if (gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET
    3804                 :        6272 :                || (gimple_omp_target_kind (ctx->stmt)
    3805                 :             :                    != GF_OMP_TARGET_KIND_REGION))
    3806                 :             :         {
    3807                 :             :           /* Teams construct can appear either strictly nested inside of
    3808                 :             :              target construct with no intervening stmts, or can be encountered
    3809                 :             :              only by initial task (so must not appear inside any OpenMP
    3810                 :             :              construct.  */
    3811                 :          55 :           error_at (gimple_location (stmt),
    3812                 :             :                     "%<teams%> construct must be closely nested inside of "
    3813                 :             :                     "%<target%> construct or not nested in any OpenMP "
    3814                 :             :                     "construct");
    3815                 :          55 :           return false;
    3816                 :             :         }
    3817                 :             :       break;
    3818                 :       40858 :     case GIMPLE_OMP_TARGET:
    3819                 :      180968 :       for (c = gimple_omp_target_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
    3820                 :      140115 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS)
    3821                 :             :           {
    3822                 :           5 :             enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_KIND (c);
    3823                 :           5 :             error_at (OMP_CLAUSE_LOCATION (c),
    3824                 :             :                       "%<depend(%s)%> is only allowed in %<omp ordered%>",
    3825                 :             :                       kind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
    3826                 :           5 :             return false;
    3827                 :             :           }
    3828                 :       40853 :       if (is_gimple_omp_offloaded (stmt)
    3829                 :       40853 :           && oacc_get_fn_attrib (cfun->decl) != NULL)
    3830                 :             :         {
    3831                 :           5 :           error_at (gimple_location (stmt),
    3832                 :             :                     "OpenACC region inside of OpenACC routine, nested "
    3833                 :             :                     "parallelism not supported yet");
    3834                 :           5 :           return false;
    3835                 :             :         }
    3836                 :       48323 :       for (; ctx != NULL; ctx = ctx->outer)
    3837                 :             :         {
    3838                 :        7862 :           if (gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET)
    3839                 :             :             {
    3840                 :         810 :               if (is_gimple_omp (stmt)
    3841                 :         810 :                   && is_gimple_omp_oacc (stmt)
    3842                 :         252 :                   && is_gimple_omp (ctx->stmt))
    3843                 :             :                 {
    3844                 :         252 :                   error_at (gimple_location (stmt),
    3845                 :             :                             "OpenACC construct inside of non-OpenACC region");
    3846                 :         252 :                   return false;
    3847                 :             :                 }
    3848                 :         558 :               continue;
    3849                 :             :             }
    3850                 :             : 
    3851                 :        7052 :           const char *stmt_name, *ctx_stmt_name;
    3852                 :        7052 :           switch (gimple_omp_target_kind (stmt))
    3853                 :             :             {
    3854                 :             :             case GF_OMP_TARGET_KIND_REGION: stmt_name = "target"; break;
    3855                 :         411 :             case GF_OMP_TARGET_KIND_DATA: stmt_name = "target data"; break;
    3856                 :        1694 :             case GF_OMP_TARGET_KIND_UPDATE: stmt_name = "target update"; break;
    3857                 :          13 :             case GF_OMP_TARGET_KIND_ENTER_DATA:
    3858                 :          13 :               stmt_name = "target enter data"; break;
    3859                 :          19 :             case GF_OMP_TARGET_KIND_EXIT_DATA:
    3860                 :          19 :               stmt_name = "target exit data"; break;
    3861                 :        1484 :             case GF_OMP_TARGET_KIND_OACC_PARALLEL: stmt_name = "parallel"; break;
    3862                 :        1758 :             case GF_OMP_TARGET_KIND_OACC_KERNELS: stmt_name = "kernels"; break;
    3863                 :           8 :             case GF_OMP_TARGET_KIND_OACC_SERIAL: stmt_name = "serial"; break;
    3864                 :         272 :             case GF_OMP_TARGET_KIND_OACC_DATA: stmt_name = "data"; break;
    3865                 :         258 :             case GF_OMP_TARGET_KIND_OACC_UPDATE: stmt_name = "update"; break;
    3866                 :         100 :             case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
    3867                 :         100 :               stmt_name = "enter data"; break;
    3868                 :          92 :             case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
    3869                 :          92 :               stmt_name = "exit data"; break;
    3870                 :          78 :             case GF_OMP_TARGET_KIND_OACC_DECLARE: stmt_name = "declare"; break;
    3871                 :         143 :             case GF_OMP_TARGET_KIND_OACC_HOST_DATA: stmt_name = "host_data";
    3872                 :         143 :               break;
    3873                 :             :             case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
    3874                 :             :             case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
    3875                 :             :             case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
    3876                 :             :               /* OpenACC 'kernels' decomposed parts.  */
    3877                 :        1758 :               stmt_name = "kernels"; break;
    3878                 :           0 :             default: gcc_unreachable ();
    3879                 :             :             }
    3880                 :        7052 :           switch (gimple_omp_target_kind (ctx->stmt))
    3881                 :             :             {
    3882                 :             :             case GF_OMP_TARGET_KIND_REGION: ctx_stmt_name = "target"; break;
    3883                 :        2765 :             case GF_OMP_TARGET_KIND_DATA: ctx_stmt_name = "target data"; break;
    3884                 :          35 :             case GF_OMP_TARGET_KIND_OACC_PARALLEL:
    3885                 :          35 :               ctx_stmt_name = "parallel"; break;
    3886                 :             :             case GF_OMP_TARGET_KIND_OACC_KERNELS:
    3887                 :        1209 :               ctx_stmt_name = "kernels"; break;
    3888                 :           0 :             case GF_OMP_TARGET_KIND_OACC_SERIAL:
    3889                 :           0 :               ctx_stmt_name = "serial"; break;
    3890                 :        2909 :             case GF_OMP_TARGET_KIND_OACC_DATA: ctx_stmt_name = "data"; break;
    3891                 :          10 :             case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
    3892                 :          10 :               ctx_stmt_name = "host_data"; break;
    3893                 :             :             case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
    3894                 :             :             case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
    3895                 :             :             case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
    3896                 :             :               /* OpenACC 'kernels' decomposed parts.  */
    3897                 :        1209 :               ctx_stmt_name = "kernels"; break;
    3898                 :           0 :             default: gcc_unreachable ();
    3899                 :             :             }
    3900                 :             : 
    3901                 :             :           /* OpenACC/OpenMP mismatch?  */
    3902                 :       14104 :           if (is_gimple_omp_oacc (stmt)
    3903                 :        7052 :               != is_gimple_omp_oacc (ctx->stmt))
    3904                 :             :             {
    3905                 :          60 :               error_at (gimple_location (stmt),
    3906                 :             :                         "%s %qs construct inside of %s %qs region",
    3907                 :             :                         (is_gimple_omp_oacc (stmt)
    3908                 :             :                          ? "OpenACC" : "OpenMP"), stmt_name,
    3909                 :             :                         (is_gimple_omp_oacc (ctx->stmt)
    3910                 :             :                          ? "OpenACC" : "OpenMP"), ctx_stmt_name);
    3911                 :          30 :               return false;
    3912                 :             :             }
    3913                 :        7022 :           if (is_gimple_omp_offloaded (ctx->stmt))
    3914                 :             :             {
    3915                 :             :               /* No GIMPLE_OMP_TARGET inside offloaded OpenACC CTX.  */
    3916                 :         164 :               if (is_gimple_omp_oacc (ctx->stmt))
    3917                 :             :                 {
    3918                 :          70 :                   error_at (gimple_location (stmt),
    3919                 :             :                             "%qs construct inside of %qs region",
    3920                 :             :                             stmt_name, ctx_stmt_name);
    3921                 :          70 :                   return false;
    3922                 :             :                 }
    3923                 :             :               else
    3924                 :             :                 {
    3925                 :          94 :                   if ((gimple_omp_target_kind (ctx->stmt)
    3926                 :             :                        == GF_OMP_TARGET_KIND_REGION)
    3927                 :          94 :                       && (gimple_omp_target_kind (stmt)
    3928                 :             :                           == GF_OMP_TARGET_KIND_REGION))
    3929                 :             :                     {
    3930                 :          68 :                       c = omp_find_clause (gimple_omp_target_clauses (stmt),
    3931                 :             :                                            OMP_CLAUSE_DEVICE);
    3932                 :          68 :                       if (c && OMP_CLAUSE_DEVICE_ANCESTOR (c))
    3933                 :             :                         break;
    3934                 :             :                     }
    3935                 :          59 :                   warning_at (gimple_location (stmt), OPT_Wopenmp,
    3936                 :             :                               "%qs construct inside of %qs region",
    3937                 :             :                               stmt_name, ctx_stmt_name);
    3938                 :             :                 }
    3939                 :             :             }
    3940                 :             :         }
    3941                 :             :       break;
    3942                 :             :     default:
    3943                 :             :       break;
    3944                 :             :     }
    3945                 :             :   return true;
    3946                 :             : }
    3947                 :             : 
    3948                 :             : 
    3949                 :             : /* Helper function scan_omp.
    3950                 :             : 
    3951                 :             :    Callback for walk_tree or operators in walk_gimple_stmt used to
    3952                 :             :    scan for OMP directives in TP.  */
    3953                 :             : 
    3954                 :             : static tree
    3955                 :     8187424 : scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
    3956                 :             : {
    3957                 :     8187424 :   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
    3958                 :     8187424 :   omp_context *ctx = (omp_context *) wi->info;
    3959                 :     8187424 :   tree t = *tp;
    3960                 :     8187424 :   tree tmp;
    3961                 :             : 
    3962                 :     8187424 :   switch (TREE_CODE (t))
    3963                 :             :     {
    3964                 :     3637093 :     case VAR_DECL:
    3965                 :     3637093 :     case PARM_DECL:
    3966                 :     3637093 :     case LABEL_DECL:
    3967                 :     3637093 :     case RESULT_DECL:
    3968                 :     3637093 :       if (ctx)
    3969                 :             :         {
    3970                 :     1978833 :           tmp = NULL_TREE;
    3971                 :     1978833 :           if (TREE_CODE (t) == VAR_DECL
    3972                 :     3549365 :               && (tmp = lookup_attribute ("omp allocate var",
    3973                 :     1570532 :                                           DECL_ATTRIBUTES (t))) != NULL_TREE)
    3974                 :          61 :             t = TREE_VALUE (TREE_VALUE (tmp));
    3975                 :     1978833 :           tree repl = remap_decl (t, &ctx->cb);
    3976                 :     1978833 :           gcc_checking_assert (TREE_CODE (repl) != ERROR_MARK);
    3977                 :     1978833 :           if (tmp != NULL_TREE  && t != repl)
    3978                 :          31 :             *tp = build_fold_addr_expr (repl);
    3979                 :     1978802 :           else if (tmp == NULL_TREE)
    3980                 :     1978772 :             *tp = repl;
    3981                 :             :         }
    3982                 :             :       break;
    3983                 :             : 
    3984                 :      149354 :     case INDIRECT_REF:
    3985                 :      149354 :     case MEM_REF:
    3986                 :      149354 :       if (ctx
    3987                 :       72353 :           && TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL
    3988                 :      203337 :           && ((tmp = lookup_attribute ("omp allocate var",
    3989                 :       53983 :                                        DECL_ATTRIBUTES (TREE_OPERAND (t, 0))))
    3990                 :             :                != NULL_TREE))
    3991                 :             :         {
    3992                 :         127 :           tmp = TREE_VALUE (TREE_VALUE (tmp));
    3993                 :         127 :           tree repl = remap_decl (tmp, &ctx->cb);
    3994                 :         127 :           gcc_checking_assert (TREE_CODE (repl) != ERROR_MARK);
    3995                 :         127 :           if (tmp != repl)
    3996                 :         118 :             *tp = repl;
    3997                 :             :           break;
    3998                 :             :         }
    3999                 :     4550204 :       gcc_fallthrough ();
    4000                 :             : 
    4001                 :     4550204 :     default:
    4002                 :     4550204 :       if (ctx && TYPE_P (t))
    4003                 :           0 :         *tp = remap_type (t, &ctx->cb);
    4004                 :     4550204 :       else if (!DECL_P (t))
    4005                 :             :         {
    4006                 :     3819701 :           *walk_subtrees = 1;
    4007                 :     3819701 :           if (ctx)
    4008                 :             :             {
    4009                 :     1334908 :               tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
    4010                 :     1334908 :               if (tem != TREE_TYPE (t))
    4011                 :             :                 {
    4012                 :        9653 :                   if (TREE_CODE (t) == INTEGER_CST)
    4013                 :        4041 :                     *tp = wide_int_to_tree (tem, wi::to_wide (t));
    4014                 :             :                   else
    4015                 :        5612 :                     TREE_TYPE (t) = tem;
    4016                 :             :                 }
    4017                 :             :             }
    4018                 :             :         }
    4019                 :             :       break;
    4020                 :             :     }
    4021                 :             : 
    4022                 :     8187424 :   return NULL_TREE;
    4023                 :             : }
    4024                 :             : 
    4025                 :             : /* Return true if FNDECL is a setjmp or a longjmp.  */
    4026                 :             : 
    4027                 :             : static bool
    4028                 :        3198 : setjmp_or_longjmp_p (const_tree fndecl)
    4029                 :             : {
    4030                 :        3198 :   if (fndecl_built_in_p (fndecl, BUILT_IN_SETJMP, BUILT_IN_LONGJMP))
    4031                 :             :     return true;
    4032                 :             : 
    4033                 :        3198 :   tree declname = DECL_NAME (fndecl);
    4034                 :        3198 :   if (!declname
    4035                 :        3198 :       || (DECL_CONTEXT (fndecl) != NULL_TREE
    4036                 :        2503 :           && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL)
    4037                 :        6113 :       || !TREE_PUBLIC (fndecl))
    4038                 :             :     return false;
    4039                 :             : 
    4040                 :        2729 :   const char *name = IDENTIFIER_POINTER (declname);
    4041                 :        2729 :   return !strcmp (name, "setjmp") || !strcmp (name, "longjmp");
    4042                 :             : }
    4043                 :             : 
    4044                 :             : /* Helper function for scan_omp.
    4045                 :             : 
    4046                 :             :    Callback for walk_gimple_stmt used to scan for OMP directives in
    4047                 :             :    the current statement in GSI.  */
    4048                 :             : 
    4049                 :             : static tree
    4050                 :     2911104 : scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
    4051                 :             :                  struct walk_stmt_info *wi)
    4052                 :             : {
    4053                 :     2911104 :   gimple *stmt = gsi_stmt (*gsi);
    4054                 :     2911104 :   omp_context *ctx = (omp_context *) wi->info;
    4055                 :             : 
    4056                 :     2911104 :   if (gimple_has_location (stmt))
    4057                 :     2379743 :     input_location = gimple_location (stmt);
    4058                 :             : 
    4059                 :             :   /* Check the nesting restrictions.  */
    4060                 :     2911104 :   bool remove = false;
    4061                 :     2911104 :   if (is_gimple_omp (stmt))
    4062                 :      153622 :     remove = !check_omp_nesting_restrictions (stmt, ctx);
    4063                 :     2757482 :   else if (is_gimple_call (stmt))
    4064                 :             :     {
    4065                 :      178618 :       tree fndecl = gimple_call_fndecl (stmt);
    4066                 :      178618 :       if (fndecl)
    4067                 :             :         {
    4068                 :      169220 :           if (ctx
    4069                 :       62719 :               && gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    4070                 :       14416 :               && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
    4071                 :        3198 :               && setjmp_or_longjmp_p (fndecl)
    4072                 :      169230 :               && !ctx->loop_p)
    4073                 :             :             {
    4074                 :           5 :               remove = true;
    4075                 :           5 :               error_at (gimple_location (stmt),
    4076                 :             :                         "setjmp/longjmp inside %<simd%> construct");
    4077                 :             :             }
    4078                 :      169215 :           else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
    4079                 :       47323 :             switch (DECL_FUNCTION_CODE (fndecl))
    4080                 :             :               {
    4081                 :        4817 :               case BUILT_IN_GOMP_BARRIER:
    4082                 :        4817 :               case BUILT_IN_GOMP_CANCEL:
    4083                 :        4817 :               case BUILT_IN_GOMP_CANCELLATION_POINT:
    4084                 :        4817 :               case BUILT_IN_GOMP_TASKYIELD:
    4085                 :        4817 :               case BUILT_IN_GOMP_TASKWAIT:
    4086                 :        4817 :               case BUILT_IN_GOMP_TASKGROUP_START:
    4087                 :        4817 :               case BUILT_IN_GOMP_TASKGROUP_END:
    4088                 :        4817 :                 remove = !check_omp_nesting_restrictions (stmt, ctx);
    4089                 :        4817 :                 break;
    4090                 :             :               default:
    4091                 :             :                 break;
    4092                 :             :               }
    4093                 :      121892 :           else if (ctx)
    4094                 :             :             {
    4095                 :       43233 :               omp_context *octx = ctx;
    4096                 :       43233 :               if (gimple_code (ctx->stmt) == GIMPLE_OMP_SCAN && ctx->outer)
    4097                 :       43233 :                 octx = ctx->outer;
    4098                 :       43233 :               if (octx->order_concurrent && omp_runtime_api_call (fndecl))
    4099                 :             :                 {
    4100                 :         288 :                   remove = true;
    4101                 :         288 :                   error_at (gimple_location (stmt),
    4102                 :             :                             "OpenMP runtime API call %qD in a region with "
    4103                 :             :                             "%<order(concurrent)%> clause", fndecl);
    4104                 :             :                 }
    4105                 :       43233 :               if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
    4106                 :        3323 :                   && omp_runtime_api_call (fndecl)
    4107                 :         320 :                   && ((IDENTIFIER_LENGTH (DECL_NAME (fndecl))
    4108                 :             :                        != strlen ("omp_get_num_teams"))
    4109                 :         184 :                       || strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)),
    4110                 :             :                                  "omp_get_num_teams") != 0)
    4111                 :       43387 :                   && ((IDENTIFIER_LENGTH (DECL_NAME (fndecl))
    4112                 :             :                        != strlen ("omp_get_team_num"))
    4113                 :         122 :                       || strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)),
    4114                 :             :                                  "omp_get_team_num") != 0))
    4115                 :             :                 {
    4116                 :          32 :                   remove = true;
    4117                 :          32 :                   error_at (gimple_location (stmt),
    4118                 :             :                             "OpenMP runtime API call %qD strictly nested in a "
    4119                 :             :                             "%<teams%> region", fndecl);
    4120                 :             :                 }
    4121                 :       43233 :               if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
    4122                 :       11733 :                   && (gimple_omp_target_kind (ctx->stmt)
    4123                 :             :                       == GF_OMP_TARGET_KIND_REGION)
    4124                 :       46375 :                   && omp_runtime_api_call (fndecl))
    4125                 :             :                 {
    4126                 :         404 :                   tree tgt_clauses = gimple_omp_target_clauses (ctx->stmt);
    4127                 :         404 :                   tree c = omp_find_clause (tgt_clauses, OMP_CLAUSE_DEVICE);
    4128                 :         404 :                   if (c && OMP_CLAUSE_DEVICE_ANCESTOR (c))
    4129                 :           6 :                     error_at (gimple_location (stmt),
    4130                 :             :                               "OpenMP runtime API call %qD in a region with "
    4131                 :             :                               "%<device(ancestor)%> clause", fndecl);
    4132                 :             :                 }
    4133                 :             :             }
    4134                 :             :         }
    4135                 :             :     }
    4136                 :      201677 :   if (remove)
    4137                 :             :     {
    4138                 :        3837 :       stmt = gimple_build_nop ();
    4139                 :        3837 :       gsi_replace (gsi, stmt, false);
    4140                 :             :     }
    4141                 :             : 
    4142                 :     2911104 :   *handled_ops_p = true;
    4143                 :             : 
    4144                 :     2911104 :   switch (gimple_code (stmt))
    4145                 :             :     {
    4146                 :       18175 :     case GIMPLE_OMP_PARALLEL:
    4147                 :       18175 :       taskreg_nesting_level++;
    4148                 :       18175 :       scan_omp_parallel (gsi, ctx);
    4149                 :       18175 :       taskreg_nesting_level--;
    4150                 :       18175 :       break;
    4151                 :             : 
    4152                 :        6088 :     case GIMPLE_OMP_TASK:
    4153                 :        6088 :       taskreg_nesting_level++;
    4154                 :        6088 :       scan_omp_task (gsi, ctx);
    4155                 :        6088 :       taskreg_nesting_level--;
    4156                 :        6088 :       break;
    4157                 :             : 
    4158                 :       53516 :     case GIMPLE_OMP_FOR:
    4159                 :       53516 :       if ((gimple_omp_for_kind (as_a <gomp_for *> (stmt))
    4160                 :             :            == GF_OMP_FOR_KIND_SIMD)
    4161                 :       11596 :           && gimple_omp_for_combined_into_p (stmt)
    4162                 :       61644 :           && gimple_code (ctx->stmt) != GIMPLE_OMP_SCAN)
    4163                 :             :         {
    4164                 :        7960 :           tree clauses = gimple_omp_for_clauses (as_a <gomp_for *> (stmt));
    4165                 :        7960 :           tree c = omp_find_clause (clauses, OMP_CLAUSE_REDUCTION);
    4166                 :        7960 :           if (c && OMP_CLAUSE_REDUCTION_INSCAN (c) && !seen_error ())
    4167                 :             :             {
    4168                 :          84 :               scan_omp_simd_scan (gsi, as_a <gomp_for *> (stmt), ctx);
    4169                 :          84 :               break;
    4170                 :             :             }
    4171                 :             :         }
    4172                 :       53432 :       if ((gimple_omp_for_kind (as_a <gomp_for *> (stmt))
    4173                 :             :            == GF_OMP_FOR_KIND_SIMD)
    4174                 :       11512 :           && omp_maybe_offloaded_ctx (ctx)
    4175                 :        3774 :           && omp_max_simt_vf ()
    4176                 :       53432 :           && gimple_omp_for_collapse (stmt) == 1)
    4177                 :           0 :         scan_omp_simd (gsi, as_a <gomp_for *> (stmt), ctx);
    4178                 :             :       else
    4179                 :       53432 :         scan_omp_for (as_a <gomp_for *> (stmt), ctx);
    4180                 :             :       break;
    4181                 :             : 
    4182                 :         207 :     case GIMPLE_OMP_SCOPE:
    4183                 :         207 :       ctx = new_omp_context (stmt, ctx);
    4184                 :         207 :       scan_sharing_clauses (gimple_omp_scope_clauses (stmt), ctx);
    4185                 :         207 :       scan_omp (gimple_omp_body_ptr (stmt), ctx);
    4186                 :         207 :       break;
    4187                 :             : 
    4188                 :         676 :     case GIMPLE_OMP_SECTIONS:
    4189                 :         676 :       scan_omp_sections (as_a <gomp_sections *> (stmt), ctx);
    4190                 :         676 :       break;
    4191                 :             : 
    4192                 :        1288 :     case GIMPLE_OMP_SINGLE:
    4193                 :        1288 :       scan_omp_single (as_a <gomp_single *> (stmt), ctx);
    4194                 :        1288 :       break;
    4195                 :             : 
    4196                 :        1402 :     case GIMPLE_OMP_SCAN:
    4197                 :        1402 :       if (tree clauses = gimple_omp_scan_clauses (as_a <gomp_scan *> (stmt)))
    4198                 :             :         {
    4199                 :         661 :           if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_INCLUSIVE)
    4200                 :         332 :             ctx->scan_inclusive = true;
    4201                 :         329 :           else if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_EXCLUSIVE)
    4202                 :         329 :             ctx->scan_exclusive = true;
    4203                 :             :         }
    4204                 :             :       /* FALLTHRU */
    4205                 :        6791 :     case GIMPLE_OMP_SECTION:
    4206                 :        6791 :     case GIMPLE_OMP_STRUCTURED_BLOCK:
    4207                 :        6791 :     case GIMPLE_OMP_MASTER:
    4208                 :        6791 :     case GIMPLE_OMP_ORDERED:
    4209                 :        6791 :     case GIMPLE_OMP_CRITICAL:
    4210                 :        6791 :       ctx = new_omp_context (stmt, ctx);
    4211                 :        6791 :       scan_omp (gimple_omp_body_ptr (stmt), ctx);
    4212                 :        6791 :       break;
    4213                 :             : 
    4214                 :         412 :     case GIMPLE_OMP_MASKED:
    4215                 :         412 :       ctx = new_omp_context (stmt, ctx);
    4216                 :         412 :       scan_sharing_clauses (gimple_omp_masked_clauses (stmt), ctx);
    4217                 :         412 :       scan_omp (gimple_omp_body_ptr (stmt), ctx);
    4218                 :         412 :       break;
    4219                 :             : 
    4220                 :         658 :     case GIMPLE_OMP_TASKGROUP:
    4221                 :         658 :       ctx = new_omp_context (stmt, ctx);
    4222                 :         658 :       scan_sharing_clauses (gimple_omp_taskgroup_clauses (stmt), ctx);
    4223                 :         658 :       scan_omp (gimple_omp_body_ptr (stmt), ctx);
    4224                 :         658 :       break;
    4225                 :             : 
    4226                 :       40496 :     case GIMPLE_OMP_TARGET:
    4227                 :       40496 :       if (is_gimple_omp_offloaded (stmt))
    4228                 :             :         {
    4229                 :       23717 :           taskreg_nesting_level++;
    4230                 :       23717 :           scan_omp_target (as_a <gomp_target *> (stmt), ctx);
    4231                 :       23717 :           taskreg_nesting_level--;
    4232                 :             :         }
    4233                 :             :       else
    4234                 :       16779 :         scan_omp_target (as_a <gomp_target *> (stmt), ctx);
    4235                 :             :       break;
    4236                 :             : 
    4237                 :        8990 :     case GIMPLE_OMP_TEAMS:
    4238                 :        8990 :       if (gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
    4239                 :             :         {
    4240                 :        2773 :           taskreg_nesting_level++;
    4241                 :        2773 :           scan_omp_teams (as_a <gomp_teams *> (stmt), ctx);
    4242                 :        2773 :           taskreg_nesting_level--;
    4243                 :             :         }
    4244                 :             :       else
    4245                 :        6217 :         scan_omp_teams (as_a <gomp_teams *> (stmt), ctx);
    4246                 :             :       break;
    4247                 :             : 
    4248                 :      249244 :     case GIMPLE_BIND:
    4249                 :      249244 :       {
    4250                 :      249244 :         tree var;
    4251                 :             : 
    4252                 :      249244 :         *handled_ops_p = false;
    4253                 :      249244 :         if (ctx)
    4254                 :      147912 :           for (var = gimple_bind_vars (as_a <gbind *> (stmt));
    4255                 :      544459 :                var ;
    4256                 :      396547 :                var = DECL_CHAIN (var))
    4257                 :      396547 :             insert_decl_map (&ctx->cb, var, var);
    4258                 :             :       }
    4259                 :             :       break;
    4260                 :     2524563 :     default:
    4261                 :     2524563 :       *handled_ops_p = false;
    4262                 :     2524563 :       break;
    4263                 :             :     }
    4264                 :             : 
    4265                 :     2911104 :   return NULL_TREE;
    4266                 :             : }
    4267                 :             : 
    4268                 :             : 
    4269                 :             : /* Scan all the statements starting at the current statement.  CTX
    4270                 :             :    contains context information about the OMP directives and
    4271                 :             :    clauses found during the scan.  */
    4272                 :             : 
    4273                 :             : static void
    4274                 :      245938 : scan_omp (gimple_seq *body_p, omp_context *ctx)
    4275                 :             : {
    4276                 :      245938 :   location_t saved_location;
    4277                 :      245938 :   struct walk_stmt_info wi;
    4278                 :             : 
    4279                 :      245938 :   memset (&wi, 0, sizeof (wi));
    4280                 :      245938 :   wi.info = ctx;
    4281                 :      245938 :   wi.want_locations = true;
    4282                 :             : 
    4283                 :      245938 :   saved_location = input_location;
    4284                 :      245938 :   walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
    4285                 :      245938 :   input_location = saved_location;
    4286                 :      245938 : }
    4287                 :             : 
    4288                 :             : /* Re-gimplification and code generation routines.  */
    4289                 :             : 
    4290                 :             : /* Remove omp_member_access_dummy_var variables from gimple_bind_vars
    4291                 :             :    of BIND if in a method.  */
    4292                 :             : 
    4293                 :             : static void
    4294                 :      248262 : maybe_remove_omp_member_access_dummy_vars (gbind *bind)
    4295                 :             : {
    4296                 :      248262 :   if (DECL_ARGUMENTS (current_function_decl)
    4297                 :       93851 :       && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl))
    4298                 :      257717 :       && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl)))
    4299                 :             :           == POINTER_TYPE))
    4300                 :             :     {
    4301                 :        3730 :       tree vars = gimple_bind_vars (bind);
    4302                 :       20253 :       for (tree *pvar = &vars; *pvar; )
    4303                 :       16523 :         if (omp_member_access_dummy_var (*pvar))
    4304                 :         850 :           *pvar = DECL_CHAIN (*pvar);
    4305                 :             :         else
    4306                 :       15673 :           pvar = &DECL_CHAIN (*pvar);
    4307                 :        3730 :       gimple_bind_set_vars (bind, vars);
    4308                 :             :     }
    4309                 :      248262 : }
    4310                 :             : 
    4311                 :             : /* Remove omp_member_access_dummy_var variables from BLOCK_VARS of
    4312                 :             :    block and its subblocks.  */
    4313                 :             : 
    4314                 :             : static void
    4315                 :        6432 : remove_member_access_dummy_vars (tree block)
    4316                 :             : {
    4317                 :       13680 :   for (tree *pvar = &BLOCK_VARS (block); *pvar; )
    4318                 :        7248 :     if (omp_member_access_dummy_var (*pvar))
    4319                 :         119 :       *pvar = DECL_CHAIN (*pvar);
    4320                 :             :     else
    4321                 :        7129 :       pvar = &DECL_CHAIN (*pvar);
    4322                 :             : 
    4323                 :        9745 :   for (block = BLOCK_SUBBLOCKS (block); block; block = BLOCK_CHAIN (block))
    4324                 :        3313 :     remove_member_access_dummy_vars (block);
    4325                 :        6432 : }
    4326                 :             : 
    4327                 :             : /* If a context was created for STMT when it was scanned, return it.  */
    4328                 :             : 
    4329                 :             : static omp_context *
    4330                 :      119060 : maybe_lookup_ctx (gimple *stmt)
    4331                 :             : {
    4332                 :      119060 :   splay_tree_node n;
    4333                 :      119060 :   n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
    4334                 :      119060 :   return n ? (omp_context *) n->value : NULL;
    4335                 :             : }
    4336                 :             : 
    4337                 :             : 
    4338                 :             : /* Find the mapping for DECL in CTX or the immediately enclosing
    4339                 :             :    context that has a mapping for DECL.
    4340                 :             : 
    4341                 :             :    If CTX is a nested parallel directive, we may have to use the decl
    4342                 :             :    mappings created in CTX's parent context.  Suppose that we have the
    4343                 :             :    following parallel nesting (variable UIDs showed for clarity):
    4344                 :             : 
    4345                 :             :         iD.1562 = 0;
    4346                 :             :         #omp parallel shared(iD.1562)           -> outer parallel
    4347                 :             :           iD.1562 = iD.1562 + 1;
    4348                 :             : 
    4349                 :             :           #omp parallel shared (iD.1562)        -> inner parallel
    4350                 :             :              iD.1562 = iD.1562 - 1;
    4351                 :             : 
    4352                 :             :    Each parallel structure will create a distinct .omp_data_s structure
    4353                 :             :    for copying iD.1562 in/out of the directive:
    4354                 :             : 
    4355                 :             :         outer parallel          .omp_data_s.1.i -> iD.1562
    4356                 :             :         inner parallel          .omp_data_s.2.i -> iD.1562
    4357                 :             : 
    4358                 :             :    A shared variable mapping will produce a copy-out operation before
    4359                 :             :    the parallel directive and a copy-in operation after it.  So, in
    4360                 :             :    this case we would have:
    4361                 :             : 
    4362                 :             :         iD.1562 = 0;
    4363                 :             :         .omp_data_o.1.i = iD.1562;
    4364                 :             :         #omp parallel shared(iD.1562)           -> outer parallel
    4365                 :             :           .omp_data_i.1 = &.omp_data_o.1
    4366                 :             :           .omp_data_i.1->i = .omp_data_i.1->i + 1;
    4367                 :             : 
    4368                 :             :           .omp_data_o.2.i = iD.1562;            -> **
    4369                 :             :           #omp parallel shared(iD.1562)         -> inner parallel
    4370                 :             :             .omp_data_i.2 = &.omp_data_o.2
    4371                 :             :             .omp_data_i.2->i = .omp_data_i.2->i - 1;
    4372                 :             : 
    4373                 :             : 
    4374                 :             :     ** This is a problem.  The symbol iD.1562 cannot be referenced
    4375                 :             :        inside the body of the outer parallel region.  But since we are
    4376                 :             :        emitting this copy operation while expanding the inner parallel
    4377                 :             :        directive, we need to access the CTX structure of the outer
    4378                 :             :        parallel directive to get the correct mapping:
    4379                 :             : 
    4380                 :             :           .omp_data_o.2.i = .omp_data_i.1->i
    4381                 :             : 
    4382                 :             :     Since there may be other workshare or parallel directives enclosing
    4383                 :             :     the parallel directive, it may be necessary to walk up the context
    4384                 :             :     parent chain.  This is not a problem in general because nested
    4385                 :             :     parallelism happens only rarely.  */
    4386                 :             : 
    4387                 :             : static tree
    4388                 :      122061 : lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
    4389                 :             : {
    4390                 :      122061 :   tree t;
    4391                 :      122061 :   omp_context *up;
    4392                 :             : 
    4393                 :      178169 :   for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
    4394                 :       56108 :     t = maybe_lookup_decl (decl, up);
    4395                 :             : 
    4396                 :      122061 :   gcc_assert (!ctx->is_nested || t || is_global_var (decl));
    4397                 :             : 
    4398                 :       94244 :   return t ? t : decl;
    4399                 :             : }
    4400                 :             : 
    4401                 :             : 
    4402                 :             : /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
    4403                 :             :    in outer contexts.  */
    4404                 :             : 
    4405                 :             : static tree
    4406                 :      351627 : maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
    4407                 :             : {
    4408                 :      351627 :   tree t = NULL;
    4409                 :      351627 :   omp_context *up;
    4410                 :             : 
    4411                 :      623274 :   for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
    4412                 :      271647 :     t = maybe_lookup_decl (decl, up);
    4413                 :             : 
    4414                 :      351627 :   return t ? t : decl;
    4415                 :             : }
    4416                 :             : 
    4417                 :             : 
    4418                 :             : /* Construct the initialization value for reduction operation OP.  */
    4419                 :             : 
    4420                 :             : tree
    4421                 :       13669 : omp_reduction_init_op (location_t loc, enum tree_code op, tree type)
    4422                 :             : {
    4423                 :       13669 :   switch (op)
    4424                 :             :     {
    4425                 :       11372 :     case PLUS_EXPR:
    4426                 :       11372 :     case MINUS_EXPR:
    4427                 :       11372 :     case BIT_IOR_EXPR:
    4428                 :       11372 :     case BIT_XOR_EXPR:
    4429                 :       11372 :     case TRUTH_OR_EXPR:
    4430                 :       11372 :     case TRUTH_ORIF_EXPR:
    4431                 :       11372 :     case TRUTH_XOR_EXPR:
    4432                 :       11372 :     case NE_EXPR:
    4433                 :       11372 :       return build_zero_cst (type);
    4434                 :             : 
    4435                 :        1423 :     case MULT_EXPR:
    4436                 :        1423 :     case TRUTH_AND_EXPR:
    4437                 :        1423 :     case TRUTH_ANDIF_EXPR:
    4438                 :        1423 :     case EQ_EXPR:
    4439                 :        1423 :       return fold_convert_loc (loc, type, integer_one_node);
    4440                 :             : 
    4441                 :         193 :     case BIT_AND_EXPR:
    4442                 :         193 :       return fold_convert_loc (loc, type, integer_minus_one_node);
    4443                 :             : 
    4444                 :         380 :     case MAX_EXPR:
    4445                 :         380 :       if (SCALAR_FLOAT_TYPE_P (type))
    4446                 :             :         {
    4447                 :         160 :           REAL_VALUE_TYPE min;
    4448                 :         160 :           if (HONOR_INFINITIES (type))
    4449                 :         160 :             real_arithmetic (&min, NEGATE_EXPR, &dconstinf, NULL);
    4450                 :             :           else
    4451                 :           0 :             real_maxval (&min, 1, TYPE_MODE (type));
    4452                 :         160 :           return build_real (type, min);
    4453                 :             :         }
    4454                 :         220 :       else if (POINTER_TYPE_P (type))
    4455                 :             :         {
    4456                 :           2 :           wide_int min
    4457                 :           2 :             = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    4458                 :           2 :           return wide_int_to_tree (type, min);
    4459                 :           2 :         }
    4460                 :             :       else
    4461                 :             :         {
    4462                 :         218 :           gcc_assert (INTEGRAL_TYPE_P (type));
    4463                 :         218 :           return TYPE_MIN_VALUE (type);
    4464                 :             :         }
    4465                 :             : 
    4466                 :         301 :     case MIN_EXPR:
    4467                 :         301 :       if (SCALAR_FLOAT_TYPE_P (type))
    4468                 :             :         {
    4469                 :         110 :           REAL_VALUE_TYPE max;
    4470                 :         110 :           if (HONOR_INFINITIES (type))
    4471                 :         110 :             max = dconstinf;
    4472                 :             :           else
    4473                 :           0 :             real_maxval (&max, 0, TYPE_MODE (type));
    4474                 :         110 :           return build_real (type, max);
    4475                 :             :         }
    4476                 :         191 :       else if (POINTER_TYPE_P (type))
    4477                 :             :         {
    4478                 :           2 :           wide_int max
    4479                 :           2 :             = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    4480                 :           2 :           return wide_int_to_tree (type, max);
    4481                 :           2 :         }
    4482                 :             :       else
    4483                 :             :         {
    4484                 :         189 :           gcc_assert (INTEGRAL_TYPE_P (type));
    4485                 :         189 :           return TYPE_MAX_VALUE (type);
    4486                 :             :         }
    4487                 :             : 
    4488                 :           0 :     default:
    4489                 :           0 :       gcc_unreachable ();
    4490                 :             :     }
    4491                 :             : }
    4492                 :             : 
    4493                 :             : /* Construct the initialization value for reduction CLAUSE.  */
    4494                 :             : 
    4495                 :             : tree
    4496                 :       11175 : omp_reduction_init (tree clause, tree type)
    4497                 :             : {
    4498                 :       11175 :   return omp_reduction_init_op (OMP_CLAUSE_LOCATION (clause),
    4499                 :       11175 :                                 OMP_CLAUSE_REDUCTION_CODE (clause), type);
    4500                 :             : }
    4501                 :             : 
    4502                 :             : /* Return alignment to be assumed for var in CLAUSE, which should be
    4503                 :             :    OMP_CLAUSE_ALIGNED.  */
    4504                 :             : 
    4505                 :             : static tree
    4506                 :         158 : omp_clause_aligned_alignment (tree clause)
    4507                 :             : {
    4508                 :         158 :   if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
    4509                 :         137 :     return OMP_CLAUSE_ALIGNED_ALIGNMENT (clause);
    4510                 :             : 
    4511                 :             :   /* Otherwise return implementation defined alignment.  */
    4512                 :          21 :   unsigned int al = 1;
    4513                 :          21 :   opt_scalar_mode mode_iter;
    4514                 :          21 :   auto_vector_modes modes;
    4515                 :          21 :   targetm.vectorize.autovectorize_vector_modes (&modes, true);
    4516                 :          21 :   static enum mode_class classes[]
    4517                 :             :     = { MODE_INT, MODE_VECTOR_INT, MODE_FLOAT, MODE_VECTOR_FLOAT };
    4518                 :          63 :   for (int i = 0; i < 4; i += 2)
    4519                 :             :     /* The for loop above dictates that we only walk through scalar classes.  */
    4520                 :         315 :     FOR_EACH_MODE_IN_CLASS (mode_iter, classes[i])
    4521                 :             :       {
    4522                 :         273 :         scalar_mode mode = mode_iter.require ();
    4523                 :         273 :         machine_mode vmode = targetm.vectorize.preferred_simd_mode (mode);
    4524                 :         273 :         if (GET_MODE_CLASS (vmode) != classes[i + 1])
    4525                 :         420 :           continue;
    4526                 :             :         machine_mode alt_vmode;
    4527                 :        1008 :         for (unsigned int j = 0; j < modes.length (); ++j)
    4528                 :         546 :           if (related_vector_mode (modes[j], mode).exists (&alt_vmode)
    4529                 :         588 :               && known_ge (GET_MODE_SIZE (alt_vmode), GET_MODE_SIZE (vmode)))
    4530                 :         126 :             vmode = alt_vmode;
    4531                 :             : 
    4532                 :         126 :         tree type = lang_hooks.types.type_for_mode (mode, 1);
    4533                 :         126 :         if (type == NULL_TREE || TYPE_MODE (type) != mode)
    4534                 :           0 :           continue;
    4535                 :         126 :         type = build_vector_type_for_mode (type, vmode);
    4536                 :         126 :         if (TYPE_MODE (type) != vmode)
    4537                 :           0 :           continue;
    4538                 :         126 :         if (TYPE_ALIGN_UNIT (type) > al)
    4539                 :          21 :           al = TYPE_ALIGN_UNIT (type);
    4540                 :             :       }
    4541                 :          21 :   return build_int_cst (integer_type_node, al);
    4542                 :          21 : }
    4543                 :             : 
    4544                 :             : 
    4545                 :             : /* This structure is part of the interface between lower_rec_simd_input_clauses
    4546                 :             :    and lower_rec_input_clauses.  */
    4547                 :             : 
    4548                 :             : class omplow_simd_context {
    4549                 :             : public:
    4550                 :       77258 :   omplow_simd_context () { memset (this, 0, sizeof (*this)); }
    4551                 :             :   tree idx;
    4552                 :             :   tree lane;
    4553                 :             :   tree lastlane;
    4554                 :             :   vec<tree, va_heap> simt_eargs;
    4555                 :             :   gimple_seq simt_dlist;
    4556                 :             :   poly_uint64 max_vf;
    4557                 :             :   bool is_simt;
    4558                 :             : };
    4559                 :             : 
    4560                 :             : /* Helper function of lower_rec_input_clauses, used for #pragma omp simd
    4561                 :             :    privatization.  */
    4562                 :             : 
    4563                 :             : static bool
    4564                 :       10658 : lower_rec_simd_input_clauses (tree new_var, omp_context *ctx,
    4565                 :             :                               omplow_simd_context *sctx, tree &ivar,
    4566                 :             :                               tree &lvar, tree *rvar = NULL,
    4567                 :             :                               tree *rvar2 = NULL)
    4568                 :             : {
    4569                 :       10658 :   if (known_eq (sctx->max_vf, 0U))
    4570                 :             :     {
    4571                 :        5020 :       sctx->max_vf = sctx->is_simt ? omp_max_simt_vf () : omp_max_vf ();
    4572                 :        5020 :       if (maybe_gt (sctx->max_vf, 1U))
    4573                 :             :         {
    4574                 :        3499 :           tree c = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    4575                 :             :                                     OMP_CLAUSE_SAFELEN);
    4576                 :        3499 :           if (c)
    4577                 :             :             {
    4578                 :          90 :               poly_uint64 safe_len;
    4579                 :          90 :               if (!poly_int_tree_p (OMP_CLAUSE_SAFELEN_EXPR (c), &safe_len)
    4580                 :          90 :                   || maybe_lt (safe_len, 1U))
    4581                 :           6 :                 sctx->max_vf = 1;
    4582                 :             :               else
    4583                 :         168 :                 sctx->max_vf = lower_bound (sctx->max_vf, safe_len);
    4584                 :             :             }
    4585                 :             :         }
    4586                 :        5020 :       if (sctx->is_simt && !known_eq (sctx->max_vf, 1U))
    4587                 :             :         {
    4588                 :           0 :           for (tree c = gimple_omp_for_clauses (ctx->stmt); c;
    4589                 :           0 :                c = OMP_CLAUSE_CHAIN (c))
    4590                 :             :             {
    4591                 :           0 :               if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
    4592                 :           0 :                 continue;
    4593                 :             : 
    4594                 :           0 :               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    4595                 :             :                 {
    4596                 :             :                   /* UDR reductions are not supported yet for SIMT, disable
    4597                 :             :                      SIMT.  */
    4598                 :           0 :                   sctx->max_vf = 1;
    4599                 :           0 :                   break;
    4600                 :             :                 }
    4601                 :             : 
    4602                 :           0 :               if (truth_value_p (OMP_CLAUSE_REDUCTION_CODE (c))
    4603                 :           0 :                   && !INTEGRAL_TYPE_P (TREE_TYPE (new_var)))
    4604                 :             :                 {
    4605                 :             :                   /* Doing boolean operations on non-integral types is
    4606                 :             :                      for conformance only, it's not worth supporting this
    4607                 :             :                      for SIMT.  */
    4608                 :           0 :                   sctx->max_vf = 1;
    4609                 :           0 :                   break;
    4610                 :             :               }
    4611                 :             :             }
    4612                 :             :         }
    4613                 :        5020 :       if (maybe_gt (sctx->max_vf, 1U))
    4614                 :             :         {
    4615                 :        3479 :           sctx->idx = create_tmp_var (unsigned_type_node);
    4616                 :        3479 :           sctx->lane = create_tmp_var (unsigned_type_node);
    4617                 :             :         }
    4618                 :             :     }
    4619                 :       10658 :   if (known_eq (sctx->max_vf, 1U))
    4620                 :             :     return false;
    4621                 :             : 
    4622                 :        7231 :   if (sctx->is_simt)
    4623                 :             :     {
    4624                 :           0 :       if (is_gimple_reg (new_var))
    4625                 :             :         {
    4626                 :           0 :           ivar = lvar = new_var;
    4627                 :           0 :           return true;
    4628                 :             :         }
    4629                 :           0 :       tree type = TREE_TYPE (new_var), ptype = build_pointer_type (type);
    4630                 :           0 :       ivar = lvar = create_tmp_var (type);
    4631                 :           0 :       TREE_ADDRESSABLE (ivar) = 1;
    4632                 :           0 :       DECL_ATTRIBUTES (ivar) = tree_cons (get_identifier ("omp simt private"),
    4633                 :           0 :                                           NULL, DECL_ATTRIBUTES (ivar));
    4634                 :           0 :       sctx->simt_eargs.safe_push (build1 (ADDR_EXPR, ptype, ivar));
    4635                 :           0 :       tree clobber = build_clobber (type);
    4636                 :           0 :       gimple *g = gimple_build_assign (ivar, clobber);
    4637                 :           0 :       gimple_seq_add_stmt (&sctx->simt_dlist, g);
    4638                 :             :     }
    4639                 :             :   else
    4640                 :             :     {
    4641                 :        7231 :       tree atype = build_array_type_nelts (TREE_TYPE (new_var), sctx->max_vf);
    4642                 :        7231 :       tree avar = create_tmp_var_raw (atype);
    4643                 :        7231 :       if (TREE_ADDRESSABLE (new_var))
    4644                 :         899 :         TREE_ADDRESSABLE (avar) = 1;
    4645                 :        7231 :       DECL_ATTRIBUTES (avar)
    4646                 :        7231 :         = tree_cons (get_identifier ("omp simd array"), NULL,
    4647                 :        7231 :                      DECL_ATTRIBUTES (avar));
    4648                 :        7231 :       gimple_add_tmp_var (avar);
    4649                 :        7231 :       tree iavar = avar;
    4650                 :        7231 :       if (rvar && !ctx->for_simd_scan_phase)
    4651                 :             :         {
    4652                 :             :           /* For inscan reductions, create another array temporary,
    4653                 :             :              which will hold the reduced value.  */
    4654                 :         250 :           iavar = create_tmp_var_raw (atype);
    4655                 :         250 :           if (TREE_ADDRESSABLE (new_var))
    4656                 :          21 :             TREE_ADDRESSABLE (iavar) = 1;
    4657                 :         250 :           DECL_ATTRIBUTES (iavar)
    4658                 :         250 :             = tree_cons (get_identifier ("omp simd array"), NULL,
    4659                 :             :                          tree_cons (get_identifier ("omp simd inscan"), NULL,
    4660                 :         250 :                                     DECL_ATTRIBUTES (iavar)));
    4661                 :         250 :           gimple_add_tmp_var (iavar);
    4662                 :         250 :           ctx->cb.decl_map->put (avar, iavar);
    4663                 :         250 :           if (sctx->lastlane == NULL_TREE)
    4664                 :         202 :             sctx->lastlane = create_tmp_var (unsigned_type_node);
    4665                 :         250 :           *rvar = build4 (ARRAY_REF, TREE_TYPE (new_var), iavar,
    4666                 :             :                           sctx->lastlane, NULL_TREE, NULL_TREE);
    4667                 :         250 :           TREE_THIS_NOTRAP (*rvar) = 1;
    4668                 :             : 
    4669                 :         250 :           if (ctx->scan_exclusive)
    4670                 :             :             {
    4671                 :             :               /* And for exclusive scan yet another one, which will
    4672                 :             :                  hold the value during the scan phase.  */
    4673                 :         122 :               tree savar = create_tmp_var_raw (atype);
    4674                 :         122 :               if (TREE_ADDRESSABLE (new_var))
    4675                 :          11 :                 TREE_ADDRESSABLE (savar) = 1;
    4676                 :         122 :               DECL_ATTRIBUTES (savar)
    4677                 :         122 :                 = tree_cons (get_identifier ("omp simd array"), NULL,
    4678                 :             :                              tree_cons (get_identifier ("omp simd inscan "
    4679                 :             :                                                         "exclusive"), NULL,
    4680                 :         122 :                                         DECL_ATTRIBUTES (savar)));
    4681                 :         122 :               gimple_add_tmp_var (savar);
    4682                 :         122 :               ctx->cb.decl_map->put (iavar, savar);
    4683                 :         122 :               *rvar2 = build4 (ARRAY_REF, TREE_TYPE (new_var), savar,
    4684                 :             :                                sctx->idx, NULL_TREE, NULL_TREE);
    4685                 :         122 :               TREE_THIS_NOTRAP (*rvar2) = 1;
    4686                 :             :             }
    4687                 :             :         }
    4688                 :        7231 :       ivar = build4 (ARRAY_REF, TREE_TYPE (new_var), iavar, sctx->idx,
    4689                 :             :                      NULL_TREE, NULL_TREE);
    4690                 :        7231 :       lvar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, sctx->lane,
    4691                 :             :                      NULL_TREE, NULL_TREE);
    4692                 :        7231 :       TREE_THIS_NOTRAP (ivar) = 1;
    4693                 :        7231 :       TREE_THIS_NOTRAP (lvar) = 1;
    4694                 :             :     }
    4695                 :        7231 :   if (DECL_P (new_var))
    4696                 :             :     {
    4697                 :        7036 :       SET_DECL_VALUE_EXPR (new_var, lvar);
    4698                 :        7036 :       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    4699                 :             :     }
    4700                 :             :   return true;
    4701                 :             : }
    4702                 :             : 
    4703                 :             : /* Helper function of lower_rec_input_clauses.  For a reference
    4704                 :             :    in simd reduction, add an underlying variable it will reference.  */
    4705                 :             : 
    4706                 :             : static void
    4707                 :         101 : handle_simd_reference (location_t loc, tree new_vard, gimple_seq *ilist)
    4708                 :             : {
    4709                 :         101 :   tree z = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
    4710                 :         101 :   if (TREE_CONSTANT (z))
    4711                 :             :     {
    4712                 :         101 :       z = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_vard)),
    4713                 :             :                               get_name (new_vard));
    4714                 :         101 :       gimple_add_tmp_var (z);
    4715                 :         101 :       TREE_ADDRESSABLE (z) = 1;
    4716                 :         101 :       z = build_fold_addr_expr_loc (loc, z);
    4717                 :         101 :       gimplify_assign (new_vard, z, ilist);
    4718                 :             :     }
    4719                 :         101 : }
    4720                 :             : 
    4721                 :             : /* Helper function for lower_rec_input_clauses.  Emit into ilist sequence
    4722                 :             :    code to emit (type) (tskred_temp[idx]).  */
    4723                 :             : 
    4724                 :             : static tree
    4725                 :        1199 : task_reduction_read (gimple_seq *ilist, tree tskred_temp, tree type,
    4726                 :             :                      unsigned idx)
    4727                 :             : {
    4728                 :        1199 :   unsigned HOST_WIDE_INT sz
    4729                 :        1199 :     = tree_to_uhwi (TYPE_SIZE_UNIT (pointer_sized_int_node));
    4730                 :        1199 :   tree r = build2 (MEM_REF, pointer_sized_int_node,
    4731                 :        1199 :                    tskred_temp, build_int_cst (TREE_TYPE (tskred_temp),
    4732                 :        1199 :                                                idx * sz));
    4733                 :        1199 :   tree v = create_tmp_var (pointer_sized_int_node);
    4734                 :        1199 :   gimple *g = gimple_build_assign (v, r);
    4735                 :        1199 :   gimple_seq_add_stmt (ilist, g);
    4736                 :        1199 :   if (!useless_type_conversion_p (type, pointer_sized_int_node))
    4737                 :             :     {
    4738                 :         951 :       v = create_tmp_var (type);
    4739                 :         951 :       g = gimple_build_assign (v, NOP_EXPR, gimple_assign_lhs (g));
    4740                 :         951 :       gimple_seq_add_stmt (ilist, g);
    4741                 :             :     }
    4742                 :        1199 :   return v;
    4743                 :             : }
    4744                 :             : 
    4745                 :             : /* Lower early initialization of privatized variable NEW_VAR
    4746                 :             :    if it needs an allocator (has allocate clause).  */
    4747                 :             : 
    4748                 :             : static bool
    4749                 :      132404 : lower_private_allocate (tree var, tree new_var, tree &allocator,
    4750                 :             :                         tree &allocate_ptr, gimple_seq *ilist,
    4751                 :             :                         omp_context *ctx, bool is_ref, tree size)
    4752                 :             : {
    4753                 :      132404 :   if (allocator)
    4754                 :             :     return false;
    4755                 :      132292 :   gcc_assert (allocate_ptr == NULL_TREE);
    4756                 :      132292 :   if (ctx->allocate_map
    4757                 :        3398 :       && (DECL_P (new_var) || (TYPE_P (new_var) && size)))
    4758                 :        3395 :     if (tree *allocatorp = ctx->allocate_map->get (var))
    4759                 :        1261 :       allocator = *allocatorp;
    4760                 :      132292 :   if (allocator == NULL_TREE)
    4761                 :             :     return false;
    4762                 :        1261 :   if (!is_ref && omp_privatize_by_reference (var))
    4763                 :             :     {
    4764                 :           0 :       allocator = NULL_TREE;
    4765                 :           0 :       return false;
    4766                 :             :     }
    4767                 :             : 
    4768                 :        1261 :   unsigned HOST_WIDE_INT ialign = 0;
    4769                 :        1261 :   if (TREE_CODE (allocator) == TREE_LIST)
    4770                 :             :     {
    4771                 :         149 :       ialign = tree_to_uhwi (TREE_VALUE (allocator));
    4772                 :         149 :       allocator = TREE_PURPOSE (allocator);
    4773                 :             :     }
    4774                 :        1261 :   if (TREE_CODE (allocator) != INTEGER_CST)
    4775                 :         442 :     allocator = build_outer_var_ref (allocator, ctx, OMP_CLAUSE_ALLOCATE);
    4776                 :        1261 :   allocator = fold_convert (pointer_sized_int_node, allocator);
    4777                 :        1261 :   if (TREE_CODE (allocator) != INTEGER_CST)
    4778                 :             :     {
    4779                 :         442 :       tree var = create_tmp_var (TREE_TYPE (allocator));
    4780                 :         442 :       gimplify_assign (var, allocator, ilist);
    4781                 :         442 :       allocator = var;
    4782                 :             :     }
    4783                 :             : 
    4784                 :        1261 :   tree ptr_type, align, sz = size;
    4785                 :        1261 :   if (TYPE_P (new_var))
    4786                 :             :     {
    4787                 :         390 :       ptr_type = build_pointer_type (new_var);
    4788                 :         390 :       ialign = MAX (ialign, TYPE_ALIGN_UNIT (new_var));
    4789                 :             :     }
    4790                 :         871 :   else if (is_ref)
    4791                 :             :     {
    4792                 :         104 :       ptr_type = build_pointer_type (TREE_TYPE (TREE_TYPE (new_var)));
    4793                 :         104 :       ialign = MAX (ialign, TYPE_ALIGN_UNIT (TREE_TYPE (ptr_type)));
    4794                 :             :     }
    4795                 :             :   else
    4796                 :             :     {
    4797                 :         767 :       ptr_type = build_pointer_type (TREE_TYPE (new_var));
    4798                 :         767 :       ialign = MAX (ialign, DECL_ALIGN_UNIT (new_var));
    4799                 :         767 :       if (sz == NULL_TREE)
    4800                 :         759 :         sz = fold_convert (size_type_node, DECL_SIZE_UNIT (new_var));
    4801                 :             :     }
    4802                 :        1261 :   align = build_int_cst (size_type_node, ialign);
    4803                 :        1261 :   if (TREE_CODE (sz) != INTEGER_CST)
    4804                 :             :     {
    4805                 :          27 :       tree szvar = create_tmp_var (size_type_node);
    4806                 :          27 :       gimplify_assign (szvar, sz, ilist);
    4807                 :          27 :       sz = szvar;
    4808                 :             :     }
    4809                 :        1261 :   allocate_ptr = create_tmp_var (ptr_type);
    4810                 :        1261 :   tree a = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
    4811                 :        1261 :   gimple *g = gimple_build_call (a, 3, align, sz, allocator);
    4812                 :        1261 :   gimple_call_set_lhs (g, allocate_ptr);
    4813                 :        1261 :   gimple_seq_add_stmt (ilist, g);
    4814                 :        1261 :   if (!is_ref)
    4815                 :             :     {
    4816                 :         767 :       tree x = build_simple_mem_ref (allocate_ptr);
    4817                 :         767 :       TREE_THIS_NOTRAP (x) = 1;
    4818                 :         767 :       SET_DECL_VALUE_EXPR (new_var, x);
    4819                 :         767 :       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    4820                 :             :     }
    4821                 :             :   return true;
    4822                 :             : }
    4823                 :             : 
    4824                 :             : /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
    4825                 :             :    from the receiver (aka child) side and initializers for REFERENCE_TYPE
    4826                 :             :    private variables.  Initialization statements go in ILIST, while calls
    4827                 :             :    to destructors go in DLIST.  */
    4828                 :             : 
    4829                 :             : static void
    4830                 :       77258 : lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
    4831                 :             :                          omp_context *ctx, struct omp_for_data *fd)
    4832                 :             : {
    4833                 :       77258 :   tree c, copyin_seq, x, ptr;
    4834                 :       77258 :   bool copyin_by_ref = false;
    4835                 :       77258 :   bool lastprivate_firstprivate = false;
    4836                 :       77258 :   bool reduction_omp_orig_ref = false;
    4837                 :       77258 :   int pass;
    4838                 :       77258 :   bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    4839                 :       77258 :                   && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD);
    4840                 :       77258 :   omplow_simd_context sctx = omplow_simd_context ();
    4841                 :       77258 :   tree simt_lane = NULL_TREE, simtrec = NULL_TREE;
    4842                 :       77258 :   tree ivar = NULL_TREE, lvar = NULL_TREE, uid = NULL_TREE;
    4843                 :       77258 :   gimple_seq llist[4] = { };
    4844                 :       77258 :   tree nonconst_simd_if = NULL_TREE;
    4845                 :             : 
    4846                 :       77258 :   copyin_seq = NULL;
    4847                 :       77258 :   sctx.is_simt = is_simd && omp_find_clause (clauses, OMP_CLAUSE__SIMT_);
    4848                 :             : 
    4849                 :             :   /* Set max_vf=1 (which will later enforce safelen=1) in simd loops
    4850                 :             :      with data sharing clauses referencing variable sized vars.  That
    4851                 :             :      is unnecessarily hard to support and very unlikely to result in
    4852                 :             :      vectorized code anyway.  */
    4853                 :       77258 :   if (is_simd)
    4854                 :       64153 :     for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    4855                 :       54308 :       switch (OMP_CLAUSE_CODE (c))
    4856                 :             :         {
    4857                 :        8077 :         case OMP_CLAUSE_LINEAR:
    4858                 :        8077 :           if (OMP_CLAUSE_LINEAR_ARRAY (c))
    4859                 :         216 :             sctx.max_vf = 1;
    4860                 :             :           /* FALLTHRU */
    4861                 :       25924 :         case OMP_CLAUSE_PRIVATE:
    4862                 :       25924 :         case OMP_CLAUSE_FIRSTPRIVATE:
    4863                 :       25924 :         case OMP_CLAUSE_LASTPRIVATE:
    4864                 :       25924 :           if (is_variable_sized (OMP_CLAUSE_DECL (c)))
    4865                 :           0 :             sctx.max_vf = 1;
    4866                 :       25924 :           else if (omp_privatize_by_reference (OMP_CLAUSE_DECL (c)))
    4867                 :             :             {
    4868                 :         297 :               tree rtype = TREE_TYPE (TREE_TYPE (OMP_CLAUSE_DECL (c)));
    4869                 :         297 :               if (!TREE_CONSTANT (TYPE_SIZE_UNIT (rtype)))
    4870                 :          96 :                 sctx.max_vf = 1;
    4871                 :             :             }
    4872                 :             :           break;
    4873                 :        2821 :         case OMP_CLAUSE_REDUCTION:
    4874                 :        2821 :         case OMP_CLAUSE_IN_REDUCTION:
    4875                 :        2821 :           if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
    4876                 :        2821 :               || is_variable_sized (OMP_CLAUSE_DECL (c)))
    4877                 :         225 :             sctx.max_vf = 1;
    4878                 :        2596 :           else if (omp_privatize_by_reference (OMP_CLAUSE_DECL (c)))
    4879                 :             :             {
    4880                 :         216 :               tree rtype = TREE_TYPE (TREE_TYPE (OMP_CLAUSE_DECL (c)));
    4881                 :         216 :               if (!TREE_CONSTANT (TYPE_SIZE_UNIT (rtype)))
    4882                 :           0 :                 sctx.max_vf = 1;
    4883                 :             :             }
    4884                 :             :           break;
    4885                 :         849 :         case OMP_CLAUSE_IF:
    4886                 :         849 :           if (integer_zerop (OMP_CLAUSE_IF_EXPR (c)))
    4887                 :         136 :             sctx.max_vf = 1;
    4888                 :         713 :           else if (TREE_CODE (OMP_CLAUSE_IF_EXPR (c)) != INTEGER_CST)
    4889                 :         702 :             nonconst_simd_if = OMP_CLAUSE_IF_EXPR (c);
    4890                 :             :           break;
    4891                 :         697 :         case OMP_CLAUSE_SIMDLEN:
    4892                 :         697 :           if (integer_onep (OMP_CLAUSE_SIMDLEN_EXPR (c)))
    4893                 :         122 :             sctx.max_vf = 1;
    4894                 :             :           break;
    4895                 :         190 :         case OMP_CLAUSE__CONDTEMP_:
    4896                 :             :           /* FIXME: lastprivate(conditional:) not handled for SIMT yet.  */
    4897                 :         190 :           if (sctx.is_simt)
    4898                 :           0 :             sctx.max_vf = 1;
    4899                 :             :           break;
    4900                 :       23827 :         default:
    4901                 :       23827 :           continue;
    4902                 :       23827 :         }
    4903                 :             : 
    4904                 :             :   /* Add a placeholder for simduid.  */
    4905                 :       77258 :   if (sctx.is_simt && maybe_ne (sctx.max_vf, 1U))
    4906                 :           0 :     sctx.simt_eargs.safe_push (NULL_TREE);
    4907                 :             : 
    4908                 :             :   unsigned task_reduction_cnt = 0;
    4909                 :             :   unsigned task_reduction_cntorig = 0;
    4910                 :             :   unsigned task_reduction_cnt_full = 0;
    4911                 :             :   unsigned task_reduction_cntorig_full = 0;
    4912                 :             :   unsigned task_reduction_other_cnt = 0;
    4913                 :      235061 :   tree tskred_atype = NULL_TREE, tskred_avar = NULL_TREE;
    4914                 :             :   tree tskred_base = NULL_TREE, tskred_temp = NULL_TREE;
    4915                 :             :   /* Do all the fixed sized types in the first pass, and the variable sized
    4916                 :             :      types in the second pass.  This makes sure that the scalar arguments to
    4917                 :             :      the variable sized types are processed before we use them in the
    4918                 :             :      variable sized operations.  For task reductions we use 4 passes, in the
    4919                 :             :      first two we ignore them, in the third one gather arguments for
    4920                 :             :      GOMP_task_reduction_remap call and in the last pass actually handle
    4921                 :             :      the task reductions.  */
    4922                 :      392864 :   for (pass = 0; pass < ((task_reduction_cnt || task_reduction_other_cnt)
    4923                 :      235061 :                          ? 4 : 2); ++pass)
    4924                 :             :     {
    4925                 :      157807 :       if (pass == 2 && task_reduction_cnt)
    4926                 :             :         {
    4927                 :         923 :           tskred_atype
    4928                 :         923 :             = build_array_type_nelts (ptr_type_node, task_reduction_cnt
    4929                 :         923 :                                                      + task_reduction_cntorig);
    4930                 :         923 :           tskred_avar = create_tmp_var_raw (tskred_atype);
    4931                 :         923 :           gimple_add_tmp_var (tskred_avar);
    4932                 :         923 :           TREE_ADDRESSABLE (tskred_avar) = 1;
    4933                 :         923 :           task_reduction_cnt_full = task_reduction_cnt;
    4934                 :         923 :           task_reduction_cntorig_full = task_reduction_cntorig;
    4935                 :             :         }
    4936                 :      156884 :       else if (pass == 3 && task_reduction_cnt)
    4937                 :             :         {
    4938                 :         923 :           x = builtin_decl_explicit (BUILT_IN_GOMP_TASK_REDUCTION_REMAP);
    4939                 :         923 :           gimple *g
    4940                 :         923 :             = gimple_build_call (x, 3, size_int (task_reduction_cnt),
    4941                 :             :                                  size_int (task_reduction_cntorig),
    4942                 :             :                                  build_fold_addr_expr (tskred_avar));
    4943                 :         923 :           gimple_seq_add_stmt (ilist, g);
    4944                 :             :         }
    4945                 :      157807 :       if (pass == 3 && task_reduction_other_cnt)
    4946                 :             :         {
    4947                 :             :           /* For reduction clauses, build
    4948                 :             :              tskred_base = (void *) tskred_temp[2]
    4949                 :             :                            + omp_get_thread_num () * tskred_temp[1]
    4950                 :             :              or if tskred_temp[1] is known to be constant, that constant
    4951                 :             :              directly.  This is the start of the private reduction copy block
    4952                 :             :              for the current thread.  */
    4953                 :         914 :           tree v = create_tmp_var (integer_type_node);
    4954                 :         914 :           x = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
    4955                 :         914 :           gimple *g = gimple_build_call (x, 0);
    4956                 :         914 :           gimple_call_set_lhs (g, v);
    4957                 :         914 :           gimple_seq_add_stmt (ilist, g);
    4958                 :         914 :           c = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
    4959                 :         914 :           tskred_temp = OMP_CLAUSE_DECL (c);
    4960                 :         914 :           if (is_taskreg_ctx (ctx))
    4961                 :         624 :             tskred_temp = lookup_decl (tskred_temp, ctx);
    4962                 :         914 :           tree v2 = create_tmp_var (sizetype);
    4963                 :         914 :           g = gimple_build_assign (v2, NOP_EXPR, v);
    4964                 :         914 :           gimple_seq_add_stmt (ilist, g);
    4965                 :         914 :           if (ctx->task_reductions[0])
    4966                 :         897 :             v = fold_convert (sizetype, ctx->task_reductions[0]);
    4967                 :             :           else
    4968                 :          17 :             v = task_reduction_read (ilist, tskred_temp, sizetype, 1);
    4969                 :         914 :           tree v3 = create_tmp_var (sizetype);
    4970                 :         914 :           g = gimple_build_assign (v3, MULT_EXPR, v2, v);
    4971                 :         914 :           gimple_seq_add_stmt (ilist, g);
    4972                 :         914 :           v = task_reduction_read (ilist, tskred_temp, ptr_type_node, 2);
    4973                 :         914 :           tskred_base = create_tmp_var (ptr_type_node);
    4974                 :         914 :           g = gimple_build_assign (tskred_base, POINTER_PLUS_EXPR, v, v3);
    4975                 :         914 :           gimple_seq_add_stmt (ilist, g);
    4976                 :             :         }
    4977                 :      157807 :       task_reduction_cnt = 0;
    4978                 :      157807 :       task_reduction_cntorig = 0;
    4979                 :      157807 :       task_reduction_other_cnt = 0;
    4980                 :      767364 :       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    4981                 :             :         {
    4982                 :      609561 :           enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
    4983                 :      609561 :           tree var, new_var;
    4984                 :      609561 :           bool by_ref;
    4985                 :      609561 :           location_t clause_loc = OMP_CLAUSE_LOCATION (c);
    4986                 :      609561 :           bool task_reduction_p = false;
    4987                 :      609561 :           bool task_reduction_needs_orig_p = false;
    4988                 :      609561 :           tree cond = NULL_TREE;
    4989                 :      609561 :           tree allocator, allocate_ptr;
    4990                 :             : 
    4991                 :      609561 :           switch (c_kind)
    4992                 :             :             {
    4993                 :      134662 :             case OMP_CLAUSE_PRIVATE:
    4994                 :      134662 :               if (OMP_CLAUSE_PRIVATE_DEBUG (c))
    4995                 :      442707 :                 continue;
    4996                 :             :               break;
    4997                 :       59132 :             case OMP_CLAUSE_SHARED:
    4998                 :             :               /* Ignore shared directives in teams construct inside
    4999                 :             :                  of target construct.  */
    5000                 :       59132 :               if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
    5001                 :       59132 :                   && !is_host_teams_ctx (ctx))
    5002                 :       23478 :                 continue;
    5003                 :       35654 :               if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
    5004                 :             :                 {
    5005                 :       12294 :                   gcc_assert (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c)
    5006                 :             :                               || is_global_var (OMP_CLAUSE_DECL (c)));
    5007                 :       12294 :                   continue;
    5008                 :             :                 }
    5009                 :             :             case OMP_CLAUSE_FIRSTPRIVATE:
    5010                 :             :             case OMP_CLAUSE_COPYIN:
    5011                 :             :               break;
    5012                 :       16638 :             case OMP_CLAUSE_LINEAR:
    5013                 :       16638 :               if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
    5014                 :       16638 :                   && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
    5015                 :             :                 lastprivate_firstprivate = true;
    5016                 :             :               break;
    5017                 :       37800 :             case OMP_CLAUSE_REDUCTION:
    5018                 :       37800 :             case OMP_CLAUSE_IN_REDUCTION:
    5019                 :       37800 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
    5020                 :       29332 :                   || is_task_ctx (ctx)
    5021                 :       64544 :                   || OMP_CLAUSE_REDUCTION_TASK (c))
    5022                 :             :                 {
    5023                 :       13316 :                   task_reduction_p = true;
    5024                 :       13316 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
    5025                 :             :                     {
    5026                 :        4848 :                       task_reduction_other_cnt++;
    5027                 :        4848 :                       if (pass == 2)
    5028                 :        1212 :                         continue;
    5029                 :             :                     }
    5030                 :             :                   else
    5031                 :        8468 :                     task_reduction_cnt++;
    5032                 :       12104 :                   if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
    5033                 :             :                     {
    5034                 :         696 :                       var = OMP_CLAUSE_DECL (c);
    5035                 :             :                       /* If var is a global variable that isn't privatized
    5036                 :             :                          in outer contexts, we don't need to look up the
    5037                 :             :                          original address, it is always the address of the
    5038                 :             :                          global variable itself.  */
    5039                 :         696 :                       if (!DECL_P (var)
    5040                 :         272 :                           || omp_privatize_by_reference (var)
    5041                 :         874 :                           || !is_global_var
    5042                 :         178 :                                 (maybe_lookup_decl_in_outer_ctx (var, ctx)))
    5043                 :             :                         {
    5044                 :         623 :                           task_reduction_needs_orig_p = true;
    5045                 :         623 :                           if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
    5046                 :         512 :                             task_reduction_cntorig++;
    5047                 :             :                         }
    5048                 :             :                     }
    5049                 :             :                 }
    5050                 :       24484 :               else if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
    5051                 :      356068 :                 reduction_omp_orig_ref = true;
    5052                 :             :               break;
    5053                 :        3656 :             case OMP_CLAUSE__REDUCTEMP_:
    5054                 :        3656 :               if (!is_taskreg_ctx (ctx))
    5055                 :        1160 :                 continue;
    5056                 :             :               /* FALLTHRU */
    5057                 :      114394 :             case OMP_CLAUSE__LOOPTEMP_:
    5058                 :             :               /* Handle _looptemp_/_reductemp_ clauses only on
    5059                 :             :                  parallel/task.  */
    5060                 :      114394 :               if (fd)
    5061                 :       71012 :                 continue;
    5062                 :             :               break;
    5063                 :       45184 :             case OMP_CLAUSE_LASTPRIVATE:
    5064                 :       45184 :               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
    5065                 :             :                 {
    5066                 :        2200 :                   lastprivate_firstprivate = true;
    5067                 :        2200 :                   if (pass != 0 || is_taskloop_ctx (ctx))
    5068                 :        1445 :                     continue;
    5069                 :             :                 }
    5070                 :             :               /* Even without corresponding firstprivate, if
    5071                 :             :                  decl is Fortran allocatable, it needs outer var
    5072                 :             :                  reference.  */
    5073                 :       42984 :               else if (pass == 0
    5074                 :       64440 :                        && lang_hooks.decls.omp_private_outer_ref
    5075                 :       21456 :                                                         (OMP_CLAUSE_DECL (c)))
    5076                 :             :                 lastprivate_firstprivate = true;
    5077                 :             :               break;
    5078                 :         316 :             case OMP_CLAUSE_ALIGNED:
    5079                 :         316 :               if (pass != 1)
    5080                 :         158 :                 continue;
    5081                 :         158 :               var = OMP_CLAUSE_DECL (c);
    5082                 :         158 :               if (TREE_CODE (TREE_TYPE (var)) == POINTER_TYPE
    5083                 :         158 :                   && !is_global_var (var))
    5084                 :             :                 {
    5085                 :          87 :                   new_var = maybe_lookup_decl (var, ctx);
    5086                 :          87 :                   if (new_var == NULL_TREE)
    5087                 :           6 :                     new_var = maybe_lookup_decl_in_outer_ctx (var, ctx);
    5088                 :          87 :                   x = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
    5089                 :          87 :                   tree alarg = omp_clause_aligned_alignment (c);
    5090                 :          87 :                   alarg = fold_convert_loc (clause_loc, size_type_node, alarg);
    5091                 :          87 :                   x = build_call_expr_loc (clause_loc, x, 2, new_var, alarg);
    5092                 :          87 :                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
    5093                 :          87 :                   x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
    5094                 :          87 :                   gimplify_and_add (x, ilist);
    5095                 :             :                 }
    5096                 :          71 :               else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
    5097                 :          71 :                        && is_global_var (var))
    5098                 :             :                 {
    5099                 :          71 :                   tree ptype = build_pointer_type (TREE_TYPE (var)), t, t2;
    5100                 :          71 :                   new_var = lookup_decl (var, ctx);
    5101                 :          71 :                   t = maybe_lookup_decl_in_outer_ctx (var, ctx);
    5102                 :          71 :                   t = build_fold_addr_expr_loc (clause_loc, t);
    5103                 :          71 :                   t2 = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
    5104                 :          71 :                   tree alarg = omp_clause_aligned_alignment (c);
    5105                 :          71 :                   alarg = fold_convert_loc (clause_loc, size_type_node, alarg);
    5106                 :          71 :                   t = build_call_expr_loc (clause_loc, t2, 2, t, alarg);
    5107                 :          71 :                   t = fold_convert_loc (clause_loc, ptype, t);
    5108                 :          71 :                   x = create_tmp_var (ptype);
    5109                 :          71 :                   t = build2 (MODIFY_EXPR, ptype, x, t);
    5110                 :          71 :                   gimplify_and_add (t, ilist);
    5111                 :          71 :                   t = build_simple_mem_ref_loc (clause_loc, x);
    5112                 :          71 :                   SET_DECL_VALUE_EXPR (new_var, t);
    5113                 :          71 :                   DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    5114                 :             :                 }
    5115                 :         158 :               continue;
    5116                 :        1568 :             case OMP_CLAUSE__CONDTEMP_:
    5117                 :        1568 :               if (is_parallel_ctx (ctx)
    5118                 :        1568 :                   || (is_simd && !OMP_CLAUSE__CONDTEMP__ITER (c)))
    5119                 :             :                 break;
    5120                 :        1132 :               continue;
    5121                 :      140448 :             default:
    5122                 :      140448 :               continue;
    5123                 :      141738 :             }
    5124                 :             : 
    5125                 :      356068 :           if (task_reduction_p != (pass >= 2))
    5126                 :       16644 :             continue;
    5127                 :             : 
    5128                 :      339424 :           allocator = NULL_TREE;
    5129                 :      339424 :           allocate_ptr = NULL_TREE;
    5130                 :      339424 :           new_var = var = OMP_CLAUSE_DECL (c);
    5131                 :      339424 :           if ((c_kind == OMP_CLAUSE_REDUCTION
    5132                 :      339424 :                || c_kind == OMP_CLAUSE_IN_REDUCTION)
    5133                 :       29876 :               && TREE_CODE (var) == MEM_REF)
    5134                 :             :             {
    5135                 :        4946 :               var = TREE_OPERAND (var, 0);
    5136                 :        4946 :               if (TREE_CODE (var) == POINTER_PLUS_EXPR)
    5137                 :         777 :                 var = TREE_OPERAND (var, 0);
    5138                 :        4946 :               if (TREE_CODE (var) == INDIRECT_REF
    5139                 :        4596 :                   || TREE_CODE (var) == ADDR_EXPR)
    5140                 :        2580 :                 var = TREE_OPERAND (var, 0);
    5141                 :        4946 :               if (is_variable_sized (var))
    5142                 :             :                 {
    5143                 :         183 :                   gcc_assert (DECL_HAS_VALUE_EXPR_P (var));
    5144                 :         183 :                   var = DECL_VALUE_EXPR (var);
    5145                 :         183 :                   gcc_assert (TREE_CODE (var) == INDIRECT_REF);
    5146                 :         183 :                   var = TREE_OPERAND (var, 0);
    5147                 :         183 :                   gcc_assert (DECL_P (var));
    5148                 :             :                 }
    5149                 :        4946 :               new_var = var;
    5150                 :             :             }
    5151                 :       29876 :           if (c_kind == OMP_CLAUSE_IN_REDUCTION && is_omp_target (ctx->stmt))
    5152                 :             :             {
    5153                 :         904 :               splay_tree_key key = (splay_tree_key) &DECL_CONTEXT (var);
    5154                 :         904 :               new_var = (tree) splay_tree_lookup (ctx->field_map, key)->value;
    5155                 :             :             }
    5156                 :      338520 :           else if (c_kind != OMP_CLAUSE_COPYIN)
    5157                 :      337420 :             new_var = lookup_decl (var, ctx);
    5158                 :             : 
    5159                 :      339424 :           if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
    5160                 :             :             {
    5161                 :       23722 :               if (pass != 0)
    5162                 :       11860 :                 continue;
    5163                 :             :             }
    5164                 :             :           /* C/C++ array section reductions.  */
    5165                 :      315702 :           else if ((c_kind == OMP_CLAUSE_REDUCTION
    5166                 :             :                     || c_kind == OMP_CLAUSE_IN_REDUCTION)
    5167                 :      315702 :                    && var != OMP_CLAUSE_DECL (c))
    5168                 :             :             {
    5169                 :        4946 :               if (pass == 0)
    5170                 :        1160 :                 continue;
    5171                 :             : 
    5172                 :        3786 :               tree bias = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
    5173                 :        3786 :               tree orig_var = TREE_OPERAND (OMP_CLAUSE_DECL (c), 0);
    5174                 :             : 
    5175                 :        3786 :               if (TREE_CODE (orig_var) == POINTER_PLUS_EXPR)
    5176                 :             :                 {
    5177                 :         725 :                   tree b = TREE_OPERAND (orig_var, 1);
    5178                 :         725 :                   if (is_omp_target (ctx->stmt))
    5179                 :             :                     b = NULL_TREE;
    5180                 :             :                   else
    5181                 :         725 :                     b = maybe_lookup_decl (b, ctx);
    5182                 :         725 :                   if (b == NULL)
    5183                 :             :                     {
    5184                 :          17 :                       b = TREE_OPERAND (orig_var, 1);
    5185                 :          17 :                       b = maybe_lookup_decl_in_outer_ctx (b, ctx);
    5186                 :             :                     }
    5187                 :         725 :                   if (integer_zerop (bias))
    5188                 :             :                     bias = b;
    5189                 :             :                   else
    5190                 :             :                     {
    5191                 :           0 :                       bias = fold_convert_loc (clause_loc,
    5192                 :           0 :                                                TREE_TYPE (b), bias);
    5193                 :           0 :                       bias = fold_build2_loc (clause_loc, PLUS_EXPR,
    5194                 :           0 :                                               TREE_TYPE (b), b, bias);
    5195                 :             :                     }
    5196                 :         725 :                   orig_var = TREE_OPERAND (orig_var, 0);
    5197                 :             :                 }
    5198                 :        3786 :               if (pass == 2)
    5199                 :             :                 {
    5200                 :        1151 :                   tree out = maybe_lookup_decl_in_outer_ctx (var, ctx);
    5201                 :        1151 :                   if (is_global_var (out)
    5202                 :         241 :                       && TREE_CODE (TREE_TYPE (out)) != POINTER_TYPE
    5203                 :        1356 :                       && (TREE_CODE (TREE_TYPE (out)) != REFERENCE_TYPE
    5204                 :          81 :                           || (TREE_CODE (TREE_TYPE (TREE_TYPE (out)))
    5205                 :             :                               != POINTER_TYPE)))
    5206                 :             :                     x = var;
    5207                 :         964 :                   else if (is_omp_target (ctx->stmt))
    5208                 :             :                     x = out;
    5209                 :             :                   else
    5210                 :             :                     {
    5211                 :         868 :                       bool by_ref = use_pointer_for_field (var, NULL);
    5212                 :         868 :                       x = build_receiver_ref (var, by_ref, ctx);
    5213                 :         868 :                       if (TREE_CODE (TREE_TYPE (var)) == REFERENCE_TYPE
    5214                 :         868 :                           && (TREE_CODE (TREE_TYPE (TREE_TYPE (var)))
    5215                 :             :                               == POINTER_TYPE))
    5216                 :          72 :                         x = build_fold_addr_expr (x);
    5217                 :             :                     }
    5218                 :        1151 :                   if (TREE_CODE (orig_var) == INDIRECT_REF)
    5219                 :          80 :                     x = build_simple_mem_ref (x);
    5220                 :        1071 :                   else if (TREE_CODE (orig_var) == ADDR_EXPR)
    5221                 :             :                     {
    5222                 :         508 :                       if (var == TREE_OPERAND (orig_var, 0))
    5223                 :         445 :                         x = build_fold_addr_expr (x);
    5224                 :             :                     }
    5225                 :        1151 :                   bias = fold_convert (sizetype, bias);
    5226                 :        1151 :                   x = fold_convert (ptr_type_node, x);
    5227                 :        1151 :                   x = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
    5228                 :        1151 :                                        TREE_TYPE (x), x, bias);
    5229                 :        1151 :                   unsigned cnt = task_reduction_cnt - 1;
    5230                 :        1151 :                   if (!task_reduction_needs_orig_p)
    5231                 :        1063 :                     cnt += (task_reduction_cntorig_full
    5232                 :        1063 :                             - task_reduction_cntorig);
    5233                 :             :                   else
    5234                 :          88 :                     cnt = task_reduction_cntorig - 1;
    5235                 :        1151 :                   tree r = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
    5236                 :             :                                    size_int (cnt), NULL_TREE, NULL_TREE);
    5237                 :        1151 :                   gimplify_assign (r, x, ilist);
    5238                 :        1151 :                   continue;
    5239                 :        1151 :                 }
    5240                 :             : 
    5241                 :        2635 :               if (TREE_CODE (orig_var) == INDIRECT_REF
    5242                 :        2455 :                   || TREE_CODE (orig_var) == ADDR_EXPR)
    5243                 :        1390 :                 orig_var = TREE_OPERAND (orig_var, 0);
    5244                 :        2635 :               tree d = OMP_CLAUSE_DECL (c);
    5245                 :        2635 :               tree type = TREE_TYPE (d);
    5246                 :        2635 :               gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
    5247                 :        2635 :               tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
    5248                 :        2635 :               tree sz = v;
    5249                 :        2635 :               const char *name = get_name (orig_var);
    5250                 :        2635 :               if (pass != 3 && !TREE_CONSTANT (v))
    5251                 :             :                 {
    5252                 :          96 :                   tree t;
    5253                 :          96 :                   if (is_omp_target (ctx->stmt))
    5254                 :             :                     t = NULL_TREE;
    5255                 :             :                   else
    5256                 :          96 :                     t = maybe_lookup_decl (v, ctx);
    5257                 :          96 :                   if (t)
    5258                 :          91 :                     v = t;
    5259                 :             :                   else
    5260                 :           5 :                     v = maybe_lookup_decl_in_outer_ctx (v, ctx);
    5261                 :          96 :                   gimplify_expr (&v, ilist, NULL, is_gimple_val, fb_rvalue);
    5262                 :         192 :                   t = fold_build2_loc (clause_loc, PLUS_EXPR,
    5263                 :          96 :                                        TREE_TYPE (v), v,
    5264                 :          96 :                                        build_int_cst (TREE_TYPE (v), 1));
    5265                 :          96 :                   sz = fold_build2_loc (clause_loc, MULT_EXPR,
    5266                 :          96 :                                         TREE_TYPE (v), t,
    5267                 :          96 :                                         TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5268                 :             :                 }
    5269                 :        2635 :               if (pass == 3)
    5270                 :             :                 {
    5271                 :        1475 :                   tree xv = create_tmp_var (ptr_type_node);
    5272                 :        1475 :                   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
    5273                 :             :                     {
    5274                 :        1151 :                       unsigned cnt = task_reduction_cnt - 1;
    5275                 :        1151 :                       if (!task_reduction_needs_orig_p)
    5276                 :        1063 :                         cnt += (task_reduction_cntorig_full
    5277                 :        1063 :                                 - task_reduction_cntorig);
    5278                 :             :                       else
    5279                 :          88 :                         cnt = task_reduction_cntorig - 1;
    5280                 :        1151 :                       x = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
    5281                 :             :                                   size_int (cnt), NULL_TREE, NULL_TREE);
    5282                 :             : 
    5283                 :        1151 :                       gimple *g = gimple_build_assign (xv, x);
    5284                 :        1151 :                       gimple_seq_add_stmt (ilist, g);
    5285                 :             :                     }
    5286                 :             :                   else
    5287                 :             :                     {
    5288                 :         324 :                       unsigned int idx = *ctx->task_reduction_map->get (c);
    5289                 :         324 :                       tree off;
    5290                 :         324 :                       if (ctx->task_reductions[1 + idx])
    5291                 :          93 :                         off = fold_convert (sizetype,
    5292                 :             :                                             ctx->task_reductions[1 + idx]);
    5293                 :             :                       else
    5294                 :         231 :                         off = task_reduction_read (ilist, tskred_temp, sizetype,
    5295                 :         231 :                                                    7 + 3 * idx + 1);
    5296                 :         324 :                       gimple *g = gimple_build_assign (xv, POINTER_PLUS_EXPR,
    5297                 :             :                                                        tskred_base, off);
    5298                 :         324 :                       gimple_seq_add_stmt (ilist, g);
    5299                 :             :                     }
    5300                 :        1475 :                   x = fold_convert (build_pointer_type (boolean_type_node),
    5301                 :             :                                     xv);
    5302                 :        1475 :                   if (TREE_CONSTANT (v))
    5303                 :        1079 :                     x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (x), x,
    5304                 :             :                                      TYPE_SIZE_UNIT (type));
    5305                 :             :                   else
    5306                 :             :                     {
    5307                 :         396 :                       tree t;
    5308                 :         396 :                       if (is_omp_target (ctx->stmt))
    5309                 :             :                         t = NULL_TREE;
    5310                 :             :                       else
    5311                 :         336 :                         t = maybe_lookup_decl (v, ctx);
    5312                 :         336 :                       if (t)
    5313                 :         316 :                         v = t;
    5314                 :             :                       else
    5315                 :          80 :                         v = maybe_lookup_decl_in_outer_ctx (v, ctx);
    5316                 :         396 :                       gimplify_expr (&v, ilist, NULL, is_gimple_val,
    5317                 :             :                                      fb_rvalue);
    5318                 :         792 :                       t = fold_build2_loc (clause_loc, PLUS_EXPR,
    5319                 :         396 :                                            TREE_TYPE (v), v,
    5320                 :         396 :                                            build_int_cst (TREE_TYPE (v), 1));
    5321                 :         396 :                       t = fold_build2_loc (clause_loc, MULT_EXPR,
    5322                 :         396 :                                            TREE_TYPE (v), t,
    5323                 :         396 :                                            TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5324                 :         396 :                       x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (x), x, t);
    5325                 :             :                     }
    5326                 :        1475 :                   cond = create_tmp_var (TREE_TYPE (x));
    5327                 :        1475 :                   gimplify_assign (cond, x, ilist);
    5328                 :        1475 :                   x = xv;
    5329                 :             :                 }
    5330                 :        1160 :               else if (lower_private_allocate (var, type, allocator,
    5331                 :             :                                                allocate_ptr, ilist, ctx,
    5332                 :             :                                                true,
    5333                 :        1160 :                                                TREE_CONSTANT (v)
    5334                 :        1064 :                                                ? TYPE_SIZE_UNIT (type)
    5335                 :             :                                                : sz))
    5336                 :         390 :                 x = allocate_ptr;
    5337                 :         770 :               else if (TREE_CONSTANT (v))
    5338                 :             :                 {
    5339                 :         679 :                   x = create_tmp_var_raw (type, name);
    5340                 :         679 :                   gimple_add_tmp_var (x);
    5341                 :         679 :                   TREE_ADDRESSABLE (x) = 1;
    5342                 :         679 :                   x = build_fold_addr_expr_loc (clause_loc, x);
    5343                 :             :                 }
    5344                 :             :               else
    5345                 :             :                 {
    5346                 :          91 :                   tree atmp
    5347                 :          91 :                     = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
    5348                 :          91 :                   tree al = size_int (TYPE_ALIGN (TREE_TYPE (type)));
    5349                 :          91 :                   x = build_call_expr_loc (clause_loc, atmp, 2, sz, al);
    5350                 :             :                 }
    5351                 :             : 
    5352                 :        2635 :               tree ptype = build_pointer_type (TREE_TYPE (type));
    5353                 :        2635 :               x = fold_convert_loc (clause_loc, ptype, x);
    5354                 :        2635 :               tree y = create_tmp_var (ptype, name);
    5355                 :        2635 :               gimplify_assign (y, x, ilist);
    5356                 :        2635 :               x = y;
    5357                 :        2635 :               tree yb = y;
    5358                 :             : 
    5359                 :        2635 :               if (!integer_zerop (bias))
    5360                 :             :                 {
    5361                 :        1689 :                   bias = fold_convert_loc (clause_loc, pointer_sized_int_node,
    5362                 :             :                                            bias);
    5363                 :        1689 :                   yb = fold_convert_loc (clause_loc, pointer_sized_int_node,
    5364                 :             :                                          x);
    5365                 :        1689 :                   yb = fold_build2_loc (clause_loc, MINUS_EXPR,
    5366                 :             :                                         pointer_sized_int_node, yb, bias);
    5367                 :        1689 :                   x = fold_convert_loc (clause_loc, TREE_TYPE (x), yb);
    5368                 :        1689 :                   yb = create_tmp_var (ptype, name);
    5369                 :        1689 :                   gimplify_assign (yb, x, ilist);
    5370                 :        1689 :                   x = yb;
    5371                 :             :                 }
    5372                 :             : 
    5373                 :        2635 :               d = TREE_OPERAND (d, 0);
    5374                 :        2635 :               if (TREE_CODE (d) == POINTER_PLUS_EXPR)
    5375                 :         422 :                 d = TREE_OPERAND (d, 0);
    5376                 :        2635 :               if (TREE_CODE (d) == ADDR_EXPR)
    5377                 :             :                 {
    5378                 :        1210 :                   if (orig_var != var)
    5379                 :             :                     {
    5380                 :          93 :                       gcc_assert (is_variable_sized (orig_var));
    5381                 :          93 :                       x = fold_convert_loc (clause_loc, TREE_TYPE (new_var),
    5382                 :             :                                             x);
    5383                 :          93 :                       gimplify_assign (new_var, x, ilist);
    5384                 :          93 :                       tree new_orig_var = lookup_decl (orig_var, ctx);
    5385                 :          93 :                       tree t = build_fold_indirect_ref (new_var);
    5386                 :          93 :                       DECL_IGNORED_P (new_var) = 0;
    5387                 :          93 :                       TREE_THIS_NOTRAP (t) = 1;
    5388                 :          93 :                       SET_DECL_VALUE_EXPR (new_orig_var, t);
    5389                 :          93 :                       DECL_HAS_VALUE_EXPR_P (new_orig_var) = 1;
    5390                 :             :                     }
    5391                 :             :                   else
    5392                 :             :                     {
    5393                 :        1117 :                       x = build2 (MEM_REF, TREE_TYPE (new_var), x,
    5394                 :        1117 :                                   build_int_cst (ptype, 0));
    5395                 :        1117 :                       SET_DECL_VALUE_EXPR (new_var, x);
    5396                 :        1117 :                       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    5397                 :             :                     }
    5398                 :             :                 }
    5399                 :             :               else
    5400                 :             :                 {
    5401                 :        1425 :                   gcc_assert (orig_var == var);
    5402                 :        1425 :                   if (TREE_CODE (d) == INDIRECT_REF)
    5403                 :             :                     {
    5404                 :         180 :                       x = create_tmp_var (ptype, name);
    5405                 :         180 :                       TREE_ADDRESSABLE (x) = 1;
    5406                 :         180 :                       gimplify_assign (x, yb, ilist);
    5407                 :         180 :                       x = build_fold_addr_expr_loc (clause_loc, x);
    5408                 :             :                     }
    5409                 :        1425 :                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
    5410                 :        1425 :                   gimplify_assign (new_var, x, ilist);
    5411                 :             :                 }
    5412                 :             :               /* GOMP_taskgroup_reduction_register memsets the whole
    5413                 :             :                  array to zero.  If the initializer is zero, we don't
    5414                 :             :                  need to initialize it again, just mark it as ever
    5415                 :             :                  used unconditionally, i.e. cond = true.  */
    5416                 :        2635 :               if (cond
    5417                 :        1475 :                   && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == NULL_TREE
    5418                 :        3580 :                   && initializer_zerop (omp_reduction_init (c,
    5419                 :         945 :                                                             TREE_TYPE (type))))
    5420                 :             :                 {
    5421                 :         634 :                   gimple *g = gimple_build_assign (build_simple_mem_ref (cond),
    5422                 :             :                                                    boolean_true_node);
    5423                 :         634 :                   gimple_seq_add_stmt (ilist, g);
    5424                 :         634 :                   continue;
    5425                 :         634 :                 }
    5426                 :        2001 :               tree end = create_artificial_label (UNKNOWN_LOCATION);
    5427                 :        2001 :               if (cond)
    5428                 :             :                 {
    5429                 :         841 :                   gimple *g;
    5430                 :         841 :                   if (!is_parallel_ctx (ctx))
    5431                 :             :                     {
    5432                 :         790 :                       tree condv = create_tmp_var (boolean_type_node);
    5433                 :         790 :                       g = gimple_build_assign (condv,
    5434                 :             :                                                build_simple_mem_ref (cond));
    5435                 :         790 :                       gimple_seq_add_stmt (ilist, g);
    5436                 :         790 :                       tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
    5437                 :         790 :                       g = gimple_build_cond (NE_EXPR, condv,
    5438                 :             :                                              boolean_false_node, end, lab1);
    5439                 :         790 :                       gimple_seq_add_stmt (ilist, g);
    5440                 :         790 :                       gimple_seq_add_stmt (ilist, gimple_build_label (lab1));
    5441                 :             :                     }
    5442                 :         841 :                   g = gimple_build_assign (build_simple_mem_ref (cond),
    5443                 :             :                                            boolean_true_node);
    5444                 :         841 :                   gimple_seq_add_stmt (ilist, g);
    5445                 :             :                 }
    5446                 :             : 
    5447                 :        2001 :               tree y1 = create_tmp_var (ptype);
    5448                 :        2001 :               gimplify_assign (y1, y, ilist);
    5449                 :        2001 :               tree i2 = NULL_TREE, y2 = NULL_TREE;
    5450                 :        2001 :               tree body2 = NULL_TREE, end2 = NULL_TREE;
    5451                 :        2001 :               tree y3 = NULL_TREE, y4 = NULL_TREE;
    5452                 :        2001 :               if (task_reduction_needs_orig_p)
    5453                 :             :                 {
    5454                 :         112 :                   y3 = create_tmp_var (ptype);
    5455                 :         112 :                   tree ref;
    5456                 :         112 :                   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
    5457                 :          88 :                     ref = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
    5458                 :          88 :                                   size_int (task_reduction_cnt_full
    5459                 :             :                                             + task_reduction_cntorig - 1),
    5460                 :             :                                   NULL_TREE, NULL_TREE);
    5461                 :             :                   else
    5462                 :             :                     {
    5463                 :          24 :                       unsigned int idx = *ctx->task_reduction_map->get (c);
    5464                 :          24 :                       ref = task_reduction_read (ilist, tskred_temp, ptype,
    5465                 :          24 :                                                  7 + 3 * idx);
    5466                 :             :                     }
    5467                 :         112 :                   gimplify_assign (y3, ref, ilist);
    5468                 :             :                 }
    5469                 :        1889 :               else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) || is_simd)
    5470                 :             :                 {
    5471                 :         715 :                   if (pass != 3)
    5472                 :             :                     {
    5473                 :         297 :                       y2 = create_tmp_var (ptype);
    5474                 :         297 :                       gimplify_assign (y2, y, ilist);
    5475                 :             :                     }
    5476                 :         715 :                   if (is_simd || OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
    5477                 :             :                     {
    5478                 :         233 :                       tree ref = build_outer_var_ref (var, ctx);
    5479                 :             :                       /* For ref build_outer_var_ref already performs this.  */
    5480                 :         233 :                       if (TREE_CODE (d) == INDIRECT_REF)
    5481                 :           0 :                         gcc_assert (omp_privatize_by_reference (var));
    5482                 :         233 :                       else if (TREE_CODE (d) == ADDR_EXPR)
    5483                 :         120 :                         ref = build_fold_addr_expr (ref);
    5484                 :         113 :                       else if (omp_privatize_by_reference (var))
    5485                 :           8 :                         ref = build_fold_addr_expr (ref);
    5486                 :         233 :                       ref = fold_convert_loc (clause_loc, ptype, ref);
    5487                 :         233 :                       if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
    5488                 :         233 :                           && OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
    5489                 :             :                         {
    5490                 :           8 :                           y3 = create_tmp_var (ptype);
    5491                 :           8 :                           gimplify_assign (y3, unshare_expr (ref), ilist);
    5492                 :             :                         }
    5493                 :         233 :                       if (is_simd)
    5494                 :             :                         {
    5495                 :         225 :                           y4 = create_tmp_var (ptype);
    5496                 :         225 :                           gimplify_assign (y4, ref, dlist);
    5497                 :             :                         }
    5498                 :             :                     }
    5499                 :             :                 }
    5500                 :        2001 :               tree i = create_tmp_var (TREE_TYPE (v));
    5501                 :        2001 :               gimplify_assign (i, build_int_cst (TREE_TYPE (v), 0), ilist);
    5502                 :        2001 :               tree body = create_artificial_label (UNKNOWN_LOCATION);
    5503                 :        2001 :               gimple_seq_add_stmt (ilist, gimple_build_label (body));
    5504                 :        2001 :               if (y2)
    5505                 :             :                 {
    5506                 :         297 :                   i2 = create_tmp_var (TREE_TYPE (v));
    5507                 :         297 :                   gimplify_assign (i2, build_int_cst (TREE_TYPE (v), 0), dlist);
    5508                 :         297 :                   body2 = create_artificial_label (UNKNOWN_LOCATION);
    5509                 :         297 :                   end2 = create_artificial_label (UNKNOWN_LOCATION);
    5510                 :         297 :                   gimple_seq_add_stmt (dlist, gimple_build_label (body2));
    5511                 :             :                 }
    5512                 :        2001 :               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    5513                 :             :                 {
    5514                 :         602 :                   tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
    5515                 :         602 :                   tree decl_placeholder
    5516                 :         602 :                     = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c);
    5517                 :         602 :                   SET_DECL_VALUE_EXPR (decl_placeholder,
    5518                 :             :                                        build_simple_mem_ref (y1));
    5519                 :         602 :                   DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 1;
    5520                 :         602 :                   SET_DECL_VALUE_EXPR (placeholder,
    5521                 :             :                                        y3 ? build_simple_mem_ref (y3)
    5522                 :             :                                        : error_mark_node);
    5523                 :         602 :                   DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
    5524                 :         602 :                   x = lang_hooks.decls.omp_clause_default_ctor
    5525                 :         722 :                                 (c, build_simple_mem_ref (y1),
    5526                 :         120 :                                  y3 ? build_simple_mem_ref (y3) : NULL_TREE);
    5527                 :         602 :                   if (x)
    5528                 :         154 :                     gimplify_and_add (x, ilist);
    5529                 :         602 :                   if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
    5530                 :             :                     {
    5531                 :         576 :                       gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
    5532                 :         576 :                       lower_omp (&tseq, ctx);
    5533                 :         576 :                       gimple_seq_add_seq (ilist, tseq);
    5534                 :             :                     }
    5535                 :         602 :                   OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
    5536                 :         602 :                   if (is_simd)
    5537                 :             :                     {
    5538                 :           0 :                       SET_DECL_VALUE_EXPR (decl_placeholder,
    5539                 :             :                                            build_simple_mem_ref (y2));
    5540                 :           0 :                       SET_DECL_VALUE_EXPR (placeholder,
    5541                 :             :                                            build_simple_mem_ref (y4));
    5542                 :           0 :                       gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
    5543                 :           0 :                       lower_omp (&tseq, ctx);
    5544                 :           0 :                       gimple_seq_add_seq (dlist, tseq);
    5545                 :           0 :                       OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    5546                 :             :                     }
    5547                 :         602 :                   DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
    5548                 :         602 :                   DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 0;
    5549                 :         602 :                   if (y2)
    5550                 :             :                     {
    5551                 :          72 :                       x = lang_hooks.decls.omp_clause_dtor
    5552                 :          72 :                                                 (c, build_simple_mem_ref (y2));
    5553                 :          72 :                       if (x)
    5554                 :          40 :                         gimplify_and_add (x, dlist);
    5555                 :             :                     }
    5556                 :             :                 }
    5557                 :             :               else
    5558                 :             :                 {
    5559                 :        1399 :                   x = omp_reduction_init (c, TREE_TYPE (type));
    5560                 :        1399 :                   enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
    5561                 :             : 
    5562                 :             :                   /* reduction(-:var) sums up the partial results, so it
    5563                 :             :                      acts identically to reduction(+:var).  */
    5564                 :        1399 :                   if (code == MINUS_EXPR)
    5565                 :           0 :                     code = PLUS_EXPR;
    5566                 :             : 
    5567                 :        1399 :                   gimplify_assign (build_simple_mem_ref (y1), x, ilist);
    5568                 :        1399 :                   if (is_simd)
    5569                 :             :                     {
    5570                 :         225 :                       x = build2 (code, TREE_TYPE (type),
    5571                 :             :                                   build_simple_mem_ref (y4),
    5572                 :             :                                   build_simple_mem_ref (y2));
    5573                 :         225 :                       gimplify_assign (build_simple_mem_ref (y4), x, dlist);
    5574                 :             :                     }
    5575                 :             :                 }
    5576                 :        2001 :               gimple *g
    5577                 :        2001 :                 = gimple_build_assign (y1, POINTER_PLUS_EXPR, y1,
    5578                 :        2001 :                                        TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5579                 :        2001 :               gimple_seq_add_stmt (ilist, g);
    5580                 :        2001 :               if (y3)
    5581                 :             :                 {
    5582                 :         120 :                   g = gimple_build_assign (y3, POINTER_PLUS_EXPR, y3,
    5583                 :         120 :                                            TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5584                 :         120 :                   gimple_seq_add_stmt (ilist, g);
    5585                 :             :                 }
    5586                 :        2001 :               g = gimple_build_assign (i, PLUS_EXPR, i,
    5587                 :        2001 :                                        build_int_cst (TREE_TYPE (i), 1));
    5588                 :        2001 :               gimple_seq_add_stmt (ilist, g);
    5589                 :        2001 :               g = gimple_build_cond (LE_EXPR, i, v, body, end);
    5590                 :        2001 :               gimple_seq_add_stmt (ilist, g);
    5591                 :        2001 :               gimple_seq_add_stmt (ilist, gimple_build_label (end));
    5592                 :        2001 :               if (y2)
    5593                 :             :                 {
    5594                 :         297 :                   g = gimple_build_assign (y2, POINTER_PLUS_EXPR, y2,
    5595                 :         297 :                                            TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5596                 :         297 :                   gimple_seq_add_stmt (dlist, g);
    5597                 :         297 :                   if (y4)
    5598                 :             :                     {
    5599                 :         225 :                       g = gimple_build_assign
    5600                 :         225 :                                         (y4, POINTER_PLUS_EXPR, y4,
    5601                 :         225 :                                          TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5602                 :         225 :                       gimple_seq_add_stmt (dlist, g);
    5603                 :             :                     }
    5604                 :         297 :                   g = gimple_build_assign (i2, PLUS_EXPR, i2,
    5605                 :         297 :                                            build_int_cst (TREE_TYPE (i2), 1));
    5606                 :         297 :                   gimple_seq_add_stmt (dlist, g);
    5607                 :         297 :                   g = gimple_build_cond (LE_EXPR, i2, v, body2, end2);
    5608                 :         297 :                   gimple_seq_add_stmt (dlist, g);
    5609                 :         297 :                   gimple_seq_add_stmt (dlist, gimple_build_label (end2));
    5610                 :             :                 }
    5611                 :        2001 :               if (allocator)
    5612                 :             :                 {
    5613                 :         390 :                   tree f = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
    5614                 :         390 :                   g = gimple_build_call (f, 2, allocate_ptr, allocator);
    5615                 :         390 :                   gimple_seq_add_stmt (dlist, g);
    5616                 :             :                 }
    5617                 :        2001 :               continue;
    5618                 :        2001 :             }
    5619                 :      310756 :           else if (pass == 2)
    5620                 :             :             {
    5621                 :         966 :               tree out = maybe_lookup_decl_in_outer_ctx (var, ctx);
    5622                 :         966 :               if (is_global_var (out))
    5623                 :             :                 x = var;
    5624                 :         367 :               else if (is_omp_target (ctx->stmt))
    5625                 :             :                 x = out;
    5626                 :             :               else
    5627                 :             :                 {
    5628                 :         307 :                   bool by_ref = use_pointer_for_field (var, ctx);
    5629                 :         307 :                   x = build_receiver_ref (var, by_ref, ctx);
    5630                 :             :                 }
    5631                 :         966 :               if (!omp_privatize_by_reference (var))
    5632                 :         838 :                 x = build_fold_addr_expr (x);
    5633                 :         966 :               x = fold_convert (ptr_type_node, x);
    5634                 :         966 :               unsigned cnt = task_reduction_cnt - 1;
    5635                 :         966 :               if (!task_reduction_needs_orig_p)
    5636                 :         926 :                 cnt += task_reduction_cntorig_full - task_reduction_cntorig;
    5637                 :             :               else
    5638                 :          40 :                 cnt = task_reduction_cntorig - 1;
    5639                 :         966 :               tree r = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
    5640                 :             :                                size_int (cnt), NULL_TREE, NULL_TREE);
    5641                 :         966 :               gimplify_assign (r, x, ilist);
    5642                 :         966 :               continue;
    5643                 :         966 :             }
    5644                 :      309790 :           else if (pass == 3)
    5645                 :             :             {
    5646                 :        1854 :               tree type = TREE_TYPE (new_var);
    5647                 :        1854 :               if (!omp_privatize_by_reference (var))
    5648                 :        1700 :                 type = build_pointer_type (type);
    5649                 :        1854 :               if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
    5650                 :             :                 {
    5651                 :         966 :                   unsigned cnt = task_reduction_cnt - 1;
    5652                 :         966 :                   if (!task_reduction_needs_orig_p)
    5653                 :         926 :                     cnt += (task_reduction_cntorig_full
    5654                 :         926 :                             - task_reduction_cntorig);
    5655                 :             :                   else
    5656                 :          40 :                     cnt = task_reduction_cntorig - 1;
    5657                 :         966 :                   x = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
    5658                 :             :                               size_int (cnt), NULL_TREE, NULL_TREE);
    5659                 :             :                 }
    5660                 :             :               else
    5661                 :             :                 {
    5662                 :         888 :                   unsigned int idx = *ctx->task_reduction_map->get (c);
    5663                 :         888 :                   tree off;
    5664                 :         888 :                   if (ctx->task_reductions[1 + idx])
    5665                 :         888 :                     off = fold_convert (sizetype,
    5666                 :             :                                         ctx->task_reductions[1 + idx]);
    5667                 :             :                   else
    5668                 :           0 :                     off = task_reduction_read (ilist, tskred_temp, sizetype,
    5669                 :           0 :                                                7 + 3 * idx + 1);
    5670                 :         888 :                   x = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
    5671                 :             :                                    tskred_base, off);
    5672                 :             :                 }
    5673                 :        1854 :               x = fold_convert (type, x);
    5674                 :        1854 :               tree t;
    5675                 :        1854 :               if (omp_privatize_by_reference (var))
    5676                 :             :                 {
    5677                 :         154 :                   gimplify_assign (new_var, x, ilist);
    5678                 :         154 :                   t = new_var;
    5679                 :         154 :                   new_var = build_simple_mem_ref (new_var);
    5680                 :             :                 }
    5681                 :             :               else
    5682                 :             :                 {
    5683                 :        1700 :                   t = create_tmp_var (type);
    5684                 :        1700 :                   gimplify_assign (t, x, ilist);
    5685                 :        1700 :                   SET_DECL_VALUE_EXPR (new_var, build_simple_mem_ref (t));
    5686                 :        1700 :                   DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    5687                 :             :                 }
    5688                 :        1854 :               t = fold_convert (build_pointer_type (boolean_type_node), t);
    5689                 :        1854 :               t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t,
    5690                 :             :                                TYPE_SIZE_UNIT (TREE_TYPE (type)));
    5691                 :        1854 :               cond = create_tmp_var (TREE_TYPE (t));
    5692                 :        1854 :               gimplify_assign (cond, t, ilist);
    5693                 :             :             }
    5694                 :      307936 :           else if (is_variable_sized (var))
    5695                 :             :             {
    5696                 :             :               /* For variable sized types, we need to allocate the
    5697                 :             :                  actual storage here.  Call alloca and store the
    5698                 :             :                  result in the pointer decl that we created elsewhere.  */
    5699                 :         254 :               if (pass == 0)
    5700                 :         130 :                 continue;
    5701                 :             : 
    5702                 :         124 :               if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
    5703                 :             :                 {
    5704                 :         110 :                   tree tmp;
    5705                 :             : 
    5706                 :         110 :                   ptr = DECL_VALUE_EXPR (new_var);
    5707                 :         110 :                   gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
    5708                 :         110 :                   ptr = TREE_OPERAND (ptr, 0);
    5709                 :         110 :                   gcc_assert (DECL_P (ptr));
    5710                 :         110 :                   x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
    5711                 :             : 
    5712                 :         110 :                   if (lower_private_allocate (var, new_var, allocator,
    5713                 :             :                                               allocate_ptr, ilist, ctx,
    5714                 :             :                                               false, x))
    5715                 :           8 :                     tmp = allocate_ptr;
    5716                 :             :                   else
    5717                 :             :                     {
    5718                 :             :                       /* void *tmp = __builtin_alloca */
    5719                 :         102 :                       tree atmp
    5720                 :         102 :                         = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
    5721                 :         102 :                       gcall *stmt
    5722                 :         102 :                         = gimple_build_call (atmp, 2, x,
    5723                 :         102 :                                              size_int (DECL_ALIGN (var)));
    5724                 :         102 :                       cfun->calls_alloca = 1;
    5725                 :         102 :                       tmp = create_tmp_var_raw (ptr_type_node);
    5726                 :         102 :                       gimple_add_tmp_var (tmp);
    5727                 :         102 :                       gimple_call_set_lhs (stmt, tmp);
    5728                 :             : 
    5729                 :         102 :                       gimple_seq_add_stmt (ilist, stmt);
    5730                 :             :                     }
    5731                 :             : 
    5732                 :         110 :                   x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
    5733                 :         110 :                   gimplify_assign (ptr, x, ilist);
    5734                 :             :                 }
    5735                 :             :             }
    5736                 :      307682 :           else if (omp_privatize_by_reference (var)
    5737                 :      307682 :                    && (c_kind != OMP_CLAUSE_FIRSTPRIVATE
    5738                 :        2058 :                        || !OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c)))
    5739                 :             :             {
    5740                 :             :               /* For references that are being privatized for Fortran,
    5741                 :             :                  allocate new backing storage for the new pointer
    5742                 :             :                  variable.  This allows us to avoid changing all the
    5743                 :             :                  code that expects a pointer to something that expects
    5744                 :             :                  a direct variable.  */
    5745                 :        5142 :               if (pass == 0)
    5746                 :        2675 :                 continue;
    5747                 :             : 
    5748                 :        2467 :               x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
    5749                 :        2467 :               if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
    5750                 :             :                 {
    5751                 :         151 :                   x = build_receiver_ref (var, false, ctx);
    5752                 :         151 :                   if (ctx->allocate_map)
    5753                 :          16 :                     if (tree *allocatep = ctx->allocate_map->get (var))
    5754                 :             :                       {
    5755                 :          16 :                         allocator = *allocatep;
    5756                 :          16 :                         if (TREE_CODE (allocator) == TREE_LIST)
    5757                 :           0 :                           allocator = TREE_PURPOSE (allocator);
    5758                 :          16 :                         if (TREE_CODE (allocator) != INTEGER_CST)
    5759                 :           8 :                           allocator = build_outer_var_ref (allocator, ctx);
    5760                 :          16 :                         allocator = fold_convert (pointer_sized_int_node,
    5761                 :             :                                                   allocator);
    5762                 :          16 :                         allocate_ptr = unshare_expr (x);
    5763                 :             :                       }
    5764                 :         151 :                   if (allocator == NULL_TREE)
    5765                 :         135 :                     x = build_fold_addr_expr_loc (clause_loc, x);
    5766                 :             :                 }
    5767                 :        2316 :               else if (lower_private_allocate (var, new_var, allocator,
    5768                 :             :                                                allocate_ptr,
    5769                 :             :                                                ilist, ctx, true, x))
    5770                 :         104 :                 x = allocate_ptr;
    5771                 :        2212 :               else if (TREE_CONSTANT (x))
    5772                 :             :                 {
    5773                 :             :                   /* For reduction in SIMD loop, defer adding the
    5774                 :             :                      initialization of the reference, because if we decide
    5775                 :             :                      to use SIMD array for it, the initilization could cause
    5776                 :             :                      expansion ICE.  Ditto for other privatization clauses.  */
    5777                 :        1516 :                   if (is_simd)
    5778                 :             :                     x = NULL_TREE;
    5779                 :             :                   else
    5780                 :             :                     {
    5781                 :        1099 :                       x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
    5782                 :             :                                               get_name (var));
    5783                 :        1099 :                       gimple_add_tmp_var (x);
    5784                 :        1099 :                       TREE_ADDRESSABLE (x) = 1;
    5785                 :        1099 :                       x = build_fold_addr_expr_loc (clause_loc, x);
    5786                 :             :                     }
    5787                 :             :                 }
    5788                 :             :               else
    5789                 :             :                 {
    5790                 :         696 :                   tree atmp
    5791                 :         696 :                     = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
    5792                 :         696 :                   tree rtype = TREE_TYPE (TREE_TYPE (new_var));
    5793                 :         696 :                   tree al = size_int (TYPE_ALIGN (rtype));
    5794                 :         696 :                   x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
    5795                 :             :                 }
    5796                 :             : 
    5797                 :        2050 :               if (x)
    5798                 :             :                 {
    5799                 :        2050 :                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
    5800                 :        2050 :                   gimplify_assign (new_var, x, ilist);
    5801                 :             :                 }
    5802                 :             : 
    5803                 :        2467 :               new_var = build_simple_mem_ref_loc (clause_loc, new_var);
    5804                 :             :             }
    5805                 :      302540 :           else if ((c_kind == OMP_CLAUSE_REDUCTION
    5806                 :             :                     || c_kind == OMP_CLAUSE_IN_REDUCTION)
    5807                 :      302540 :                    && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    5808                 :             :             {
    5809                 :        1928 :               if (pass == 0)
    5810                 :         964 :                 continue;
    5811                 :             :             }
    5812                 :      300612 :           else if (pass != 0)
    5813                 :      150033 :             continue;
    5814                 :             : 
    5815                 :      167850 :           switch (OMP_CLAUSE_CODE (c))
    5816                 :             :             {
    5817                 :       11312 :             case OMP_CLAUSE_SHARED:
    5818                 :             :               /* Ignore shared directives in teams construct inside
    5819                 :             :                  target construct.  */
    5820                 :       11312 :               if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
    5821                 :       11312 :                   && !is_host_teams_ctx (ctx))
    5822                 :           0 :                 continue;
    5823                 :             :               /* Shared global vars are just accessed directly.  */
    5824                 :       11312 :               if (is_global_var (new_var))
    5825                 :             :                 break;
    5826                 :             :               /* For taskloop firstprivate/lastprivate, represented
    5827                 :             :                  as firstprivate and shared clause on the task, new_var
    5828                 :             :                  is the firstprivate var.  */
    5829                 :       11156 :               if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
    5830                 :             :                 break;
    5831                 :             :               /* Set up the DECL_VALUE_EXPR for shared variables now.  This
    5832                 :             :                  needs to be delayed until after fixup_child_record_type so
    5833                 :             :                  that we get the correct type during the dereference.  */
    5834                 :       10813 :               by_ref = use_pointer_for_field (var, ctx);
    5835                 :       10813 :               x = build_receiver_ref (var, by_ref, ctx);
    5836                 :       10813 :               SET_DECL_VALUE_EXPR (new_var, x);
    5837                 :       10813 :               DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    5838                 :             : 
    5839                 :             :               /* ??? If VAR is not passed by reference, and the variable
    5840                 :             :                  hasn't been initialized yet, then we'll get a warning for
    5841                 :             :                  the store into the omp_data_s structure.  Ideally, we'd be
    5842                 :             :                  able to notice this and not store anything at all, but
    5843                 :             :                  we're generating code too early.  Suppress the warning.  */
    5844                 :       10813 :               if (!by_ref)
    5845                 :        4726 :                 suppress_warning (var, OPT_Wuninitialized);
    5846                 :             :               break;
    5847                 :             : 
    5848                 :         218 :             case OMP_CLAUSE__CONDTEMP_:
    5849                 :         218 :               if (is_parallel_ctx (ctx))
    5850                 :             :                 {
    5851                 :         108 :                   x = build_receiver_ref (var, false, ctx);
    5852                 :         108 :                   SET_DECL_VALUE_EXPR (new_var, x);
    5853                 :         108 :                   DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    5854                 :             :                 }
    5855                 :         110 :               else if (is_simd && !OMP_CLAUSE__CONDTEMP__ITER (c))
    5856                 :             :                 {
    5857                 :         110 :                   x = build_zero_cst (TREE_TYPE (var));
    5858                 :         110 :                   goto do_private;
    5859                 :             :                 }
    5860                 :             :               break;
    5861                 :             : 
    5862                 :       21997 :             case OMP_CLAUSE_LASTPRIVATE:
    5863                 :       21997 :               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
    5864                 :             :                 break;
    5865                 :             :               /* FALLTHRU */
    5866                 :             : 
    5867                 :       87268 :             case OMP_CLAUSE_PRIVATE:
    5868                 :       87268 :               if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
    5869                 :       21456 :                 x = build_outer_var_ref (var, ctx);
    5870                 :       65812 :               else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
    5871                 :             :                 {
    5872                 :         162 :                   if (is_task_ctx (ctx))
    5873                 :          12 :                     x = build_receiver_ref (var, false, ctx);
    5874                 :             :                   else
    5875                 :         150 :                     x = build_outer_var_ref (var, ctx, OMP_CLAUSE_PRIVATE);
    5876                 :             :                 }
    5877                 :             :               else
    5878                 :             :                 x = NULL;
    5879                 :       94349 :             do_private:
    5880                 :       94349 :               tree nx;
    5881                 :       94349 :               bool copy_ctor;
    5882                 :       94349 :               copy_ctor = false;
    5883                 :       94349 :               lower_private_allocate (var, new_var, allocator, allocate_ptr,
    5884                 :             :                                       ilist, ctx, false, NULL_TREE);
    5885                 :       94349 :               nx = unshare_expr (new_var);
    5886                 :       94349 :               if (is_simd
    5887                 :       24907 :                   && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    5888                 :      101991 :                   && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
    5889                 :          22 :                 copy_ctor = true;
    5890                 :       94349 :               if (copy_ctor)
    5891                 :          22 :                 nx = lang_hooks.decls.omp_clause_copy_ctor (c, nx, x);
    5892                 :             :               else
    5893                 :       94327 :                 nx = lang_hooks.decls.omp_clause_default_ctor (c, nx, x);
    5894                 :       94349 :               if (is_simd)
    5895                 :             :                 {
    5896                 :       24907 :                   tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
    5897                 :       24219 :                   if ((TREE_ADDRESSABLE (new_var) || nx || y
    5898                 :       24203 :                        || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    5899                 :        7266 :                            && (gimple_omp_for_collapse (ctx->stmt) != 1
    5900                 :        1531 :                                || (gimple_omp_for_index (ctx->stmt, 0)
    5901                 :             :                                    != new_var)))
    5902                 :       17284 :                        || OMP_CLAUSE_CODE (c) == OMP_CLAUSE__CONDTEMP_
    5903                 :       17174 :                        || omp_privatize_by_reference (var))
    5904                 :       31992 :                       && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
    5905                 :             :                                                        ivar, lvar))
    5906                 :             :                     {
    5907                 :        5999 :                       if (omp_privatize_by_reference (var))
    5908                 :             :                         {
    5909                 :          56 :                           gcc_assert (TREE_CODE (new_var) == MEM_REF);
    5910                 :          56 :                           tree new_vard = TREE_OPERAND (new_var, 0);
    5911                 :          56 :                           gcc_assert (DECL_P (new_vard));
    5912                 :          56 :                           SET_DECL_VALUE_EXPR (new_vard,
    5913                 :             :                                                build_fold_addr_expr (lvar));
    5914                 :          56 :                           DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
    5915                 :             :                         }
    5916                 :             : 
    5917                 :        5999 :                       if (nx)
    5918                 :             :                         {
    5919                 :          30 :                           tree iv = unshare_expr (ivar);
    5920                 :          30 :                           if (copy_ctor)
    5921                 :          22 :                             x = lang_hooks.decls.omp_clause_copy_ctor (c, iv,
    5922                 :             :                                                                        x);
    5923                 :             :                           else
    5924                 :           8 :                             x = lang_hooks.decls.omp_clause_default_ctor (c,
    5925                 :             :                                                                           iv,
    5926                 :             :                                                                           x);
    5927                 :             :                         }
    5928                 :        5969 :                       else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__CONDTEMP_)
    5929                 :             :                         {
    5930                 :          37 :                           x = build2 (MODIFY_EXPR, TREE_TYPE (ivar),
    5931                 :             :                                       unshare_expr (ivar), x);
    5932                 :          37 :                           nx = x;
    5933                 :             :                         }
    5934                 :        5999 :                       if (nx && x)
    5935                 :          67 :                         gimplify_and_add (x, &llist[0]);
    5936                 :        5999 :                       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    5937                 :        5999 :                           && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
    5938                 :             :                         {
    5939                 :          37 :                           tree v = new_var;
    5940                 :          37 :                           if (!DECL_P (v))
    5941                 :             :                             {
    5942                 :           4 :                               gcc_assert (TREE_CODE (v) == MEM_REF);
    5943                 :           4 :                               v = TREE_OPERAND (v, 0);
    5944                 :           4 :                               gcc_assert (DECL_P (v));
    5945                 :             :                             }
    5946                 :          37 :                           v = *ctx->lastprivate_conditional_map->get (v);
    5947                 :          37 :                           tree t = create_tmp_var (TREE_TYPE (v));
    5948                 :          37 :                           tree z = build_zero_cst (TREE_TYPE (v));
    5949                 :          37 :                           tree orig_v
    5950                 :          37 :                             = build_outer_var_ref (var, ctx,
    5951                 :             :                                                    OMP_CLAUSE_LASTPRIVATE);
    5952                 :          37 :                           gimple_seq_add_stmt (dlist,
    5953                 :          37 :                                                gimple_build_assign (t, z));
    5954                 :          37 :                           gcc_assert (DECL_HAS_VALUE_EXPR_P (v));
    5955                 :          37 :                           tree civar = DECL_VALUE_EXPR (v);
    5956                 :          37 :                           gcc_assert (TREE_CODE (civar) == ARRAY_REF);
    5957                 :          37 :                           civar = unshare_expr (civar);
    5958                 :          37 :                           TREE_OPERAND (civar, 1) = sctx.idx;
    5959                 :          37 :                           x = build2 (MODIFY_EXPR, TREE_TYPE (t), t,
    5960                 :             :                                       unshare_expr (civar));
    5961                 :          74 :                           x = build2 (COMPOUND_EXPR, TREE_TYPE (orig_v), x,
    5962                 :          37 :                                       build2 (MODIFY_EXPR, TREE_TYPE (orig_v),
    5963                 :             :                                               orig_v, unshare_expr (ivar)));
    5964                 :          37 :                           tree cond = build2 (LT_EXPR, boolean_type_node, t,
    5965                 :             :                                               civar);
    5966                 :          37 :                           x = build3 (COND_EXPR, void_type_node, cond, x,
    5967                 :             :                                       void_node);
    5968                 :          37 :                           gimple_seq tseq = NULL;
    5969                 :          37 :                           gimplify_and_add (x, &tseq);
    5970                 :          37 :                           if (ctx->outer)
    5971                 :          27 :                             lower_omp (&tseq, ctx->outer);
    5972                 :          37 :                           gimple_seq_add_seq (&llist[1], tseq);
    5973                 :             :                         }
    5974                 :        5999 :                       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    5975                 :        5999 :                           && ctx->for_simd_scan_phase)
    5976                 :             :                         {
    5977                 :           9 :                           x = unshare_expr (ivar);
    5978                 :           9 :                           tree orig_v
    5979                 :           9 :                             = build_outer_var_ref (var, ctx,
    5980                 :             :                                                    OMP_CLAUSE_LASTPRIVATE);
    5981                 :           9 :                           x = lang_hooks.decls.omp_clause_assign_op (c, x,
    5982                 :             :                                                                      orig_v);
    5983                 :           9 :                           gimplify_and_add (x, &llist[0]);
    5984                 :             :                         }
    5985                 :        5999 :                       if (y)
    5986                 :             :                         {
    5987                 :          30 :                           y = lang_hooks.decls.omp_clause_dtor (c, ivar);
    5988                 :          30 :                           if (y)
    5989                 :          30 :                             gimplify_and_add (y, &llist[1]);
    5990                 :             :                         }
    5991                 :             :                       break;
    5992                 :             :                     }
    5993                 :       18908 :                   if (omp_privatize_by_reference (var))
    5994                 :             :                     {
    5995                 :          36 :                       gcc_assert (TREE_CODE (new_var) == MEM_REF);
    5996                 :          36 :                       tree new_vard = TREE_OPERAND (new_var, 0);
    5997                 :          36 :                       gcc_assert (DECL_P (new_vard));
    5998                 :          36 :                       tree type = TREE_TYPE (TREE_TYPE (new_vard));
    5999                 :          36 :                       x = TYPE_SIZE_UNIT (type);
    6000                 :          36 :                       if (TREE_CONSTANT (x))
    6001                 :             :                         {
    6002                 :          36 :                           x = create_tmp_var_raw (type, get_name (var));
    6003                 :          36 :                           gimple_add_tmp_var (x);
    6004                 :          36 :                           TREE_ADDRESSABLE (x) = 1;
    6005                 :          36 :                           x = build_fold_addr_expr_loc (clause_loc, x);
    6006                 :          36 :                           x = fold_convert_loc (clause_loc,
    6007                 :          36 :                                                 TREE_TYPE (new_vard), x);
    6008                 :          36 :                           gimplify_assign (new_vard, x, ilist);
    6009                 :             :                         }
    6010                 :             :                     }
    6011                 :             :                 }
    6012                 :       88350 :               if (nx)
    6013                 :         492 :                 gimplify_and_add (nx, ilist);
    6014                 :       88350 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    6015                 :       15821 :                   && is_simd
    6016                 :       90357 :                   && ctx->for_simd_scan_phase)
    6017                 :             :                 {
    6018                 :           5 :                   tree orig_v = build_outer_var_ref (var, ctx,
    6019                 :             :                                                      OMP_CLAUSE_LASTPRIVATE);
    6020                 :           5 :                   x = lang_hooks.decls.omp_clause_assign_op (c, new_var,
    6021                 :             :                                                              orig_v);
    6022                 :           5 :                   gimplify_and_add (x, ilist);
    6023                 :             :                 }
    6024                 :             :               /* FALLTHRU */
    6025                 :             : 
    6026                 :      117642 :             do_dtor:
    6027                 :      117642 :               x = lang_hooks.decls.omp_clause_dtor (c, new_var);
    6028                 :      117642 :               if (x)
    6029                 :        1150 :                 gimplify_and_add (x, dlist);
    6030                 :      117642 :               if (allocator)
    6031                 :             :                 {
    6032                 :         915 :                   if (!is_gimple_val (allocator))
    6033                 :             :                     {
    6034                 :          22 :                       tree avar = create_tmp_var (TREE_TYPE (allocator));
    6035                 :          22 :                       gimplify_assign (avar, allocator, dlist);
    6036                 :          22 :                       allocator = avar;
    6037                 :             :                     }
    6038                 :         915 :                   if (!is_gimple_val (allocate_ptr))
    6039                 :             :                     {
    6040                 :          44 :                       tree apvar = create_tmp_var (TREE_TYPE (allocate_ptr));
    6041                 :          44 :                       gimplify_assign (apvar, allocate_ptr, dlist);
    6042                 :          44 :                       allocate_ptr = apvar;
    6043                 :             :                     }
    6044                 :         915 :                   tree f = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
    6045                 :         915 :                   gimple *g
    6046                 :         915 :                     = gimple_build_call (f, 2, allocate_ptr, allocator);
    6047                 :         915 :                   gimple_seq_add_stmt (dlist, g);
    6048                 :             :                 }
    6049                 :             :               break;
    6050                 :             : 
    6051                 :        8319 :             case OMP_CLAUSE_LINEAR:
    6052                 :        8319 :               if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
    6053                 :        1348 :                 goto do_firstprivate;
    6054                 :        6971 :               if (OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
    6055                 :             :                 x = NULL;
    6056                 :             :               else
    6057                 :        3788 :                 x = build_outer_var_ref (var, ctx);
    6058                 :        6971 :               goto do_private;
    6059                 :             : 
    6060                 :       27020 :             case OMP_CLAUSE_FIRSTPRIVATE:
    6061                 :       27020 :               if (is_task_ctx (ctx))
    6062                 :             :                 {
    6063                 :        4146 :                   if ((omp_privatize_by_reference (var)
    6064                 :         151 :                        && !OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c))
    6065                 :        4146 :                       || is_variable_sized (var))
    6066                 :         165 :                     goto do_dtor;
    6067                 :        3981 :                   else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
    6068                 :             :                                                                           ctx))
    6069                 :        3981 :                            || use_pointer_for_field (var, NULL))
    6070                 :             :                     {
    6071                 :         449 :                       x = build_receiver_ref (var, false, ctx);
    6072                 :         449 :                       if (ctx->allocate_map)
    6073                 :          28 :                         if (tree *allocatep = ctx->allocate_map->get (var))
    6074                 :             :                           {
    6075                 :          28 :                             allocator = *allocatep;
    6076                 :          28 :                             if (TREE_CODE (allocator) == TREE_LIST)
    6077                 :           4 :                               allocator = TREE_PURPOSE (allocator);
    6078                 :          28 :                             if (TREE_CODE (allocator) != INTEGER_CST)
    6079                 :          14 :                               allocator = build_outer_var_ref (allocator, ctx);
    6080                 :          28 :                             allocator = fold_convert (pointer_sized_int_node,
    6081                 :             :                                                       allocator);
    6082                 :          28 :                             allocate_ptr = unshare_expr (x);
    6083                 :          28 :                             x = build_simple_mem_ref (x);
    6084                 :          28 :                             TREE_THIS_NOTRAP (x) = 1;
    6085                 :             :                           }
    6086                 :         449 :                       SET_DECL_VALUE_EXPR (new_var, x);
    6087                 :         449 :                       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    6088                 :         449 :                       goto do_dtor;
    6089                 :             :                     }
    6090                 :             :                 }
    6091                 :       26406 :               if (OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c)
    6092                 :       26406 :                   && omp_privatize_by_reference (var))
    6093                 :             :                 {
    6094                 :          23 :                   x = build_outer_var_ref (var, ctx);
    6095                 :          23 :                   gcc_assert (TREE_CODE (x) == MEM_REF
    6096                 :             :                               && integer_zerop (TREE_OPERAND (x, 1)));
    6097                 :          23 :                   x = TREE_OPERAND (x, 0);
    6098                 :          23 :                   x = lang_hooks.decls.omp_clause_copy_ctor
    6099                 :          23 :                                                 (c, unshare_expr (new_var), x);
    6100                 :          23 :                   gimplify_and_add (x, ilist);
    6101                 :          23 :                   goto do_dtor;
    6102                 :             :                 }
    6103                 :       27731 :             do_firstprivate:
    6104                 :       27731 :               lower_private_allocate (var, new_var, allocator, allocate_ptr,
    6105                 :             :                                       ilist, ctx, false, NULL_TREE);
    6106                 :       27731 :               x = build_outer_var_ref (var, ctx);
    6107                 :       27731 :               if (is_simd)
    6108                 :             :                 {
    6109                 :        1127 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
    6110                 :        1127 :                       && gimple_omp_for_combined_into_p (ctx->stmt))
    6111                 :             :                     {
    6112                 :         715 :                       tree t = OMP_CLAUSE_LINEAR_STEP (c);
    6113                 :         715 :                       if (DECL_P (t))
    6114                 :         118 :                         t = build_outer_var_ref (t, ctx);
    6115                 :         715 :                       tree stept = TREE_TYPE (t);
    6116                 :         715 :                       tree ct = omp_find_clause (clauses,
    6117                 :             :                                                  OMP_CLAUSE__LOOPTEMP_);
    6118                 :         715 :                       gcc_assert (ct);
    6119                 :         715 :                       tree l = OMP_CLAUSE_DECL (ct);
    6120                 :         715 :                       tree n1 = fd->loop.n1;
    6121                 :         715 :                       tree step = fd->loop.step;
    6122                 :         715 :                       tree itype = TREE_TYPE (l);
    6123                 :         715 :                       if (POINTER_TYPE_P (itype))
    6124                 :           0 :                         itype = signed_type_for (itype);
    6125                 :         715 :                       l = fold_build2 (MINUS_EXPR, itype, l, n1);
    6126                 :         715 :                       if (TYPE_UNSIGNED (itype)
    6127                 :         715 :                           && fd->loop.cond_code == GT_EXPR)
    6128                 :           0 :                         l = fold_build2 (TRUNC_DIV_EXPR, itype,
    6129                 :             :                                          fold_build1 (NEGATE_EXPR, itype, l),
    6130                 :             :                                          fold_build1 (NEGATE_EXPR,
    6131                 :             :                                                       itype, step));
    6132                 :             :                       else
    6133                 :         715 :                         l = fold_build2 (TRUNC_DIV_EXPR, itype, l, step);
    6134                 :         715 :                       t = fold_build2 (MULT_EXPR, stept,
    6135                 :             :                                        fold_convert (stept, l), t);
    6136                 :             : 
    6137                 :         715 :                       if (OMP_CLAUSE_LINEAR_ARRAY (c))
    6138                 :             :                         {
    6139                 :         108 :                           if (omp_privatize_by_reference (var))
    6140                 :             :                             {
    6141                 :          72 :                               gcc_assert (TREE_CODE (new_var) == MEM_REF);
    6142                 :          72 :                               tree new_vard = TREE_OPERAND (new_var, 0);
    6143                 :          72 :                               gcc_assert (DECL_P (new_vard));
    6144                 :          72 :                               tree type = TREE_TYPE (TREE_TYPE (new_vard));
    6145                 :          72 :                               nx = TYPE_SIZE_UNIT (type);
    6146                 :          72 :                               if (TREE_CONSTANT (nx))
    6147                 :             :                                 {
    6148                 :          24 :                                   nx = create_tmp_var_raw (type,
    6149                 :             :                                                            get_name (var));
    6150                 :          24 :                                   gimple_add_tmp_var (nx);
    6151                 :          24 :                                   TREE_ADDRESSABLE (nx) = 1;
    6152                 :          24 :                                   nx = build_fold_addr_expr_loc (clause_loc,
    6153                 :             :                                                                  nx);
    6154                 :          24 :                                   nx = fold_convert_loc (clause_loc,
    6155                 :          24 :                                                          TREE_TYPE (new_vard),
    6156                 :             :                                                          nx);
    6157                 :          24 :                                   gimplify_assign (new_vard, nx, ilist);
    6158                 :             :                                 }
    6159                 :             :                             }
    6160                 :             : 
    6161                 :         108 :                           x = lang_hooks.decls.omp_clause_linear_ctor
    6162                 :         108 :                                                         (c, new_var, x, t);
    6163                 :         108 :                           gimplify_and_add (x, ilist);
    6164                 :         108 :                           goto do_dtor;
    6165                 :             :                         }
    6166                 :             : 
    6167                 :         607 :                       if (POINTER_TYPE_P (TREE_TYPE (x)))
    6168                 :          13 :                         x = fold_build_pointer_plus (x, t);
    6169                 :             :                       else
    6170                 :         594 :                         x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x,
    6171                 :             :                                          fold_convert (TREE_TYPE (x), t));
    6172                 :             :                     }
    6173                 :             : 
    6174                 :        1019 :                   if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
    6175                 :         998 :                        || TREE_ADDRESSABLE (new_var)
    6176                 :         863 :                        || omp_privatize_by_reference (var))
    6177                 :        1287 :                       && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
    6178                 :             :                                                        ivar, lvar))
    6179                 :             :                     {
    6180                 :         154 :                       if (omp_privatize_by_reference (var))
    6181                 :             :                         {
    6182                 :          24 :                           gcc_assert (TREE_CODE (new_var) == MEM_REF);
    6183                 :          24 :                           tree new_vard = TREE_OPERAND (new_var, 0);
    6184                 :          24 :                           gcc_assert (DECL_P (new_vard));
    6185                 :          24 :                           SET_DECL_VALUE_EXPR (new_vard,
    6186                 :             :                                                build_fold_addr_expr (lvar));
    6187                 :          24 :                           DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
    6188                 :             :                         }
    6189                 :         154 :                       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
    6190                 :             :                         {
    6191                 :         133 :                           tree iv = create_tmp_var (TREE_TYPE (new_var));
    6192                 :         133 :                           x = lang_hooks.decls.omp_clause_copy_ctor (c, iv, x);
    6193                 :         133 :                           gimplify_and_add (x, ilist);
    6194                 :         133 :                           gimple_stmt_iterator gsi
    6195                 :         133 :                             = gsi_start (*gimple_omp_body_ptr (ctx->stmt));
    6196                 :         133 :                           gassign *g
    6197                 :         133 :                             = gimple_build_assign (unshare_expr (lvar), iv);
    6198                 :         133 :                           gsi_insert_before_without_update (&gsi, g,
    6199                 :             :                                                             GSI_SAME_STMT);
    6200                 :         133 :                           tree t = OMP_CLAUSE_LINEAR_STEP (c);
    6201                 :         133 :                           enum tree_code code = PLUS_EXPR;
    6202                 :         133 :                           if (POINTER_TYPE_P (TREE_TYPE (new_var)))
    6203                 :             :                             code = POINTER_PLUS_EXPR;
    6204                 :         133 :                           g = gimple_build_assign (iv, code, iv, t);
    6205                 :         133 :                           gsi_insert_before_without_update (&gsi, g,
    6206                 :             :                                                             GSI_SAME_STMT);
    6207                 :         133 :                           break;
    6208                 :             :                         }
    6209                 :          21 :                       x = lang_hooks.decls.omp_clause_copy_ctor
    6210                 :          21 :                                                 (c, unshare_expr (ivar), x);
    6211                 :          21 :                       gimplify_and_add (x, &llist[0]);
    6212                 :          21 :                       x = lang_hooks.decls.omp_clause_dtor (c, ivar);
    6213                 :          21 :                       if (x)
    6214                 :          21 :                         gimplify_and_add (x, &llist[1]);
    6215                 :             :                       break;
    6216                 :             :                     }
    6217                 :         865 :                   if (omp_privatize_by_reference (var))
    6218                 :             :                     {
    6219                 :         109 :                       gcc_assert (TREE_CODE (new_var) == MEM_REF);
    6220                 :         109 :                       tree new_vard = TREE_OPERAND (new_var, 0);
    6221                 :         109 :                       gcc_assert (DECL_P (new_vard));
    6222                 :         109 :                       tree type = TREE_TYPE (TREE_TYPE (new_vard));
    6223                 :         109 :                       nx = TYPE_SIZE_UNIT (type);
    6224                 :         109 :                       if (TREE_CONSTANT (nx))
    6225                 :             :                         {
    6226                 :          61 :                           nx = create_tmp_var_raw (type, get_name (var));
    6227                 :          61 :                           gimple_add_tmp_var (nx);
    6228                 :          61 :                           TREE_ADDRESSABLE (nx) = 1;
    6229                 :          61 :                           nx = build_fold_addr_expr_loc (clause_loc, nx);
    6230                 :          61 :                           nx = fold_convert_loc (clause_loc,
    6231                 :          61 :                                                  TREE_TYPE (new_vard), nx);
    6232                 :          61 :                           gimplify_assign (new_vard, nx, ilist);
    6233                 :             :                         }
    6234                 :             :                     }
    6235                 :             :                 }
    6236                 :       27469 :               x = lang_hooks.decls.omp_clause_copy_ctor
    6237                 :       27469 :                                                 (c, unshare_expr (new_var), x);
    6238                 :       27465 :               gimplify_and_add (x, ilist);
    6239                 :       27465 :               goto do_dtor;
    6240                 :             : 
    6241                 :       19713 :             case OMP_CLAUSE__LOOPTEMP_:
    6242                 :       19713 :             case OMP_CLAUSE__REDUCTEMP_:
    6243                 :       19713 :               gcc_assert (is_taskreg_ctx (ctx));
    6244                 :       19713 :               x = build_outer_var_ref (var, ctx);
    6245                 :       19713 :               x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
    6246                 :       19713 :               gimplify_and_add (x, ilist);
    6247                 :       19713 :               break;
    6248                 :             : 
    6249                 :         550 :             case OMP_CLAUSE_COPYIN:
    6250                 :         550 :               by_ref = use_pointer_for_field (var, NULL);
    6251                 :         550 :               x = build_receiver_ref (var, by_ref, ctx);
    6252                 :         550 :               x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
    6253                 :         550 :               append_to_statement_list (x, &copyin_seq);
    6254                 :         550 :               copyin_by_ref |= by_ref;
    6255                 :         550 :               break;
    6256                 :             : 
    6257                 :       12909 :             case OMP_CLAUSE_REDUCTION:
    6258                 :       12909 :             case OMP_CLAUSE_IN_REDUCTION:
    6259                 :             :               /* OpenACC reductions are initialized using the
    6260                 :             :                  GOACC_REDUCTION internal function.  */
    6261                 :       12909 :               if (is_gimple_omp_oacc (ctx->stmt))
    6262                 :             :                 break;
    6263                 :        9481 :               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    6264                 :             :                 {
    6265                 :        1483 :                   tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
    6266                 :        1483 :                   gimple *tseq;
    6267                 :        1483 :                   tree ptype = TREE_TYPE (placeholder);
    6268                 :        1483 :                   if (cond)
    6269                 :             :                     {
    6270                 :         296 :                       x = error_mark_node;
    6271                 :         296 :                       if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c)
    6272                 :         296 :                           && !task_reduction_needs_orig_p)
    6273                 :          20 :                         x = var;
    6274                 :         276 :                       else if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
    6275                 :             :                         {
    6276                 :          53 :                           tree pptype = build_pointer_type (ptype);
    6277                 :          53 :                           if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
    6278                 :          40 :                             x = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
    6279                 :          40 :                                         size_int (task_reduction_cnt_full
    6280                 :             :                                                   + task_reduction_cntorig - 1),
    6281                 :             :                                         NULL_TREE, NULL_TREE);
    6282                 :             :                           else
    6283                 :             :                             {
    6284                 :          13 :                               unsigned int idx
    6285                 :          13 :                                 = *ctx->task_reduction_map->get (c);
    6286                 :          13 :                               x = task_reduction_read (ilist, tskred_temp,
    6287                 :          13 :                                                        pptype, 7 + 3 * idx);
    6288                 :             :                             }
    6289                 :          53 :                           x = fold_convert (pptype, x);
    6290                 :          53 :                           x = build_simple_mem_ref (x);
    6291                 :             :                         }
    6292                 :             :                     }
    6293                 :             :                   else
    6294                 :             :                     {
    6295                 :        1187 :                       lower_private_allocate (var, new_var, allocator,
    6296                 :             :                                               allocate_ptr, ilist, ctx, false,
    6297                 :             :                                               NULL_TREE);
    6298                 :        1187 :                       x = build_outer_var_ref (var, ctx);
    6299                 :             : 
    6300                 :        1187 :                       if (omp_privatize_by_reference (var)
    6301                 :        1187 :                           && !useless_type_conversion_p (ptype, TREE_TYPE (x)))
    6302                 :          49 :                         x = build_fold_addr_expr_loc (clause_loc, x);
    6303                 :             :                     }
    6304                 :        1483 :                   SET_DECL_VALUE_EXPR (placeholder, x);
    6305                 :        1483 :                   DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
    6306                 :        1483 :                   tree new_vard = new_var;
    6307                 :        1483 :                   if (omp_privatize_by_reference (var))
    6308                 :             :                     {
    6309                 :         279 :                       gcc_assert (TREE_CODE (new_var) == MEM_REF);
    6310                 :         279 :                       new_vard = TREE_OPERAND (new_var, 0);
    6311                 :         279 :                       gcc_assert (DECL_P (new_vard));
    6312                 :             :                     }
    6313                 :        1483 :                   tree rvar = NULL_TREE, *rvarp = NULL, rvar2 = NULL_TREE;
    6314                 :        1483 :                   if (is_simd
    6315                 :         346 :                       && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    6316                 :        1829 :                       && OMP_CLAUSE_REDUCTION_INSCAN (c))
    6317                 :             :                     rvarp = &rvar;
    6318                 :        1483 :                   if (is_simd
    6319                 :        1483 :                       && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
    6320                 :             :                                                        ivar, lvar, rvarp,
    6321                 :             :                                                        &rvar2))
    6322                 :             :                     {
    6323                 :         189 :                       if (new_vard == new_var)
    6324                 :             :                         {
    6325                 :         122 :                           gcc_assert (DECL_VALUE_EXPR (new_var) == lvar);
    6326                 :         122 :                           SET_DECL_VALUE_EXPR (new_var, ivar);
    6327                 :             :                         }
    6328                 :             :                       else
    6329                 :             :                         {
    6330                 :          67 :                           SET_DECL_VALUE_EXPR (new_vard,
    6331                 :             :                                                build_fold_addr_expr (ivar));
    6332                 :          67 :                           DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
    6333                 :             :                         }
    6334                 :         189 :                       x = lang_hooks.decls.omp_clause_default_ctor
    6335                 :         189 :                                 (c, unshare_expr (ivar),
    6336                 :             :                                  build_outer_var_ref (var, ctx));
    6337                 :         189 :                       if (rvarp && ctx->for_simd_scan_phase)
    6338                 :             :                         {
    6339                 :          16 :                           if (x)
    6340                 :           8 :                             gimplify_and_add (x, &llist[0]);
    6341                 :          16 :                           x = lang_hooks.decls.omp_clause_dtor (c, ivar);
    6342                 :          16 :                           if (x)
    6343                 :           8 :                             gimplify_and_add (x, &llist[1]);
    6344                 :         485 :                           break;
    6345                 :             :                         }
    6346                 :          92 :                       else if (rvarp)
    6347                 :             :                         {
    6348                 :          92 :                           if (x)
    6349                 :             :                             {
    6350                 :          48 :                               gimplify_and_add (x, &llist[0]);
    6351                 :             : 
    6352                 :          48 :                               tree ivar2 = unshare_expr (lvar);
    6353                 :          48 :                               TREE_OPERAND (ivar2, 1) = sctx.idx;
    6354                 :          48 :                               x = lang_hooks.decls.omp_clause_default_ctor
    6355                 :          48 :                                     (c, ivar2, build_outer_var_ref (var, ctx));
    6356                 :          48 :                               gimplify_and_add (x, &llist[0]);
    6357                 :             : 
    6358                 :          48 :                               if (rvar2)
    6359                 :             :                                 {
    6360                 :          20 :                                   x = lang_hooks.decls.omp_clause_default_ctor
    6361                 :          20 :                                         (c, unshare_expr (rvar2),
    6362                 :             :                                          build_outer_var_ref (var, ctx));
    6363                 :          20 :                                   gimplify_and_add (x, &llist[0]);
    6364                 :             :                                 }
    6365                 :             : 
    6366                 :             :                               /* For types that need construction, add another
    6367                 :             :                                  private var which will be default constructed
    6368                 :             :                                  and optionally initialized with
    6369                 :             :                                  OMP_CLAUSE_REDUCTION_GIMPLE_INIT, as in the
    6370                 :             :                                  loop we want to assign this value instead of
    6371                 :             :                                  constructing and destructing it in each
    6372                 :             :                                  iteration.  */
    6373                 :          48 :                               tree nv = create_tmp_var_raw (TREE_TYPE (ivar));
    6374                 :          48 :                               gimple_add_tmp_var (nv);
    6375                 :          76 :                               ctx->cb.decl_map->put (TREE_OPERAND (rvar2
    6376                 :             :                                                                    ? rvar2
    6377                 :             :                                                                    : ivar, 0),
    6378                 :             :                                                      nv);
    6379                 :          48 :                               x = lang_hooks.decls.omp_clause_default_ctor
    6380                 :          48 :                                     (c, nv, build_outer_var_ref (var, ctx));
    6381                 :          48 :                               gimplify_and_add (x, ilist);
    6382                 :             : 
    6383                 :          48 :                               if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
    6384                 :             :                                 {
    6385                 :          24 :                                   tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
    6386                 :          24 :                                   x = DECL_VALUE_EXPR (new_vard);
    6387                 :          24 :                                   tree vexpr = nv;
    6388                 :          24 :                                   if (new_vard != new_var)
    6389                 :          14 :                                     vexpr = build_fold_addr_expr (nv);
    6390                 :          24 :                                   SET_DECL_VALUE_EXPR (new_vard, vexpr);
    6391                 :          24 :                                   lower_omp (&tseq, ctx);
    6392                 :          24 :                                   SET_DECL_VALUE_EXPR (new_vard, x);
    6393                 :          24 :                                   gimple_seq_add_seq (ilist, tseq);
    6394                 :          24 :                                   OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
    6395                 :             :                                 }
    6396                 :             : 
    6397                 :          48 :                               x = lang_hooks.decls.omp_clause_dtor (c, nv);
    6398                 :          48 :                               if (x)
    6399                 :          48 :                                 gimplify_and_add (x, dlist);
    6400                 :             :                             }
    6401                 :             : 
    6402                 :          92 :                           tree ref = build_outer_var_ref (var, ctx);
    6403                 :          92 :                           x = unshare_expr (ivar);
    6404                 :          92 :                           x = lang_hooks.decls.omp_clause_assign_op (c, x,
    6405                 :             :                                                                      ref);
    6406                 :          92 :                           gimplify_and_add (x, &llist[0]);
    6407                 :             : 
    6408                 :          92 :                           ref = build_outer_var_ref (var, ctx);
    6409                 :          92 :                           x = lang_hooks.decls.omp_clause_assign_op (c, ref,
    6410                 :             :                                                                      rvar);
    6411                 :          92 :                           gimplify_and_add (x, &llist[3]);
    6412                 :             : 
    6413                 :          92 :                           DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
    6414                 :          92 :                           if (new_vard == new_var)
    6415                 :          44 :                             SET_DECL_VALUE_EXPR (new_var, lvar);
    6416                 :             :                           else
    6417                 :          48 :                             SET_DECL_VALUE_EXPR (new_vard,
    6418                 :             :                                                  build_fold_addr_expr (lvar));
    6419                 :             : 
    6420                 :          92 :                           x = lang_hooks.decls.omp_clause_dtor (c, ivar);
    6421                 :          92 :                           if (x)
    6422                 :          48 :                             gimplify_and_add (x, &llist[1]);
    6423                 :             : 
    6424                 :          92 :                           tree ivar2 = unshare_expr (lvar);
    6425                 :          92 :                           TREE_OPERAND (ivar2, 1) = sctx.idx;
    6426                 :          92 :                           x = lang_hooks.decls.omp_clause_dtor (c, ivar2);
    6427                 :          92 :                           if (x)
    6428                 :          48 :                             gimplify_and_add (x, &llist[1]);
    6429                 :             : 
    6430                 :          92 :                           if (rvar2)
    6431                 :             :                             {
    6432                 :          42 :                               x = lang_hooks.decls.omp_clause_dtor (c, rvar2);
    6433                 :          42 :                               if (x)
    6434                 :          20 :                                 gimplify_and_add (x, &llist[1]);
    6435                 :             :                             }
    6436                 :             :                           break;
    6437                 :             :                         }
    6438                 :          81 :                       if (x)
    6439                 :          34 :                         gimplify_and_add (x, &llist[0]);
    6440                 :          81 :                       if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
    6441                 :             :                         {
    6442                 :          77 :                           tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
    6443                 :          77 :                           lower_omp (&tseq, ctx);
    6444                 :          77 :                           gimple_seq_add_seq (&llist[0], tseq);
    6445                 :             :                         }
    6446                 :          81 :                       OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
    6447                 :          81 :                       tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
    6448                 :          81 :                       lower_omp (&tseq, ctx);
    6449                 :          81 :                       gimple_seq_add_seq (&llist[1], tseq);
    6450                 :          81 :                       OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    6451                 :          81 :                       DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
    6452                 :          81 :                       if (new_vard == new_var)
    6453                 :          70 :                         SET_DECL_VALUE_EXPR (new_var, lvar);
    6454                 :             :                       else
    6455                 :          11 :                         SET_DECL_VALUE_EXPR (new_vard,
    6456                 :             :                                              build_fold_addr_expr (lvar));
    6457                 :          81 :                       x = lang_hooks.decls.omp_clause_dtor (c, ivar);
    6458                 :          81 :                       if (x)
    6459                 :          38 :                         gimplify_and_add (x, &llist[1]);
    6460                 :             :                       break;
    6461                 :             :                     }
    6462                 :             :                   /* If this is a reference to constant size reduction var
    6463                 :             :                      with placeholder, we haven't emitted the initializer
    6464                 :             :                      for it because it is undesirable if SIMD arrays are used.
    6465                 :             :                      But if they aren't used, we need to emit the deferred
    6466                 :             :                      initialization now.  */
    6467                 :        1294 :                   else if (omp_privatize_by_reference (var) && is_simd)
    6468                 :          67 :                     handle_simd_reference (clause_loc, new_vard, ilist);
    6469                 :             : 
    6470                 :        1294 :                   tree lab2 = NULL_TREE;
    6471                 :        1294 :                   if (cond)
    6472                 :             :                     {
    6473                 :         296 :                       gimple *g;
    6474                 :         296 :                       if (!is_parallel_ctx (ctx))
    6475                 :             :                         {
    6476                 :         280 :                           tree condv = create_tmp_var (boolean_type_node);
    6477                 :         280 :                           tree m = build_simple_mem_ref (cond);
    6478                 :         280 :                           g = gimple_build_assign (condv, m);
    6479                 :         280 :                           gimple_seq_add_stmt (ilist, g);
    6480                 :         280 :                           tree lab1
    6481                 :         280 :                             = create_artificial_label (UNKNOWN_LOCATION);
    6482                 :         280 :                           lab2 = create_artificial_label (UNKNOWN_LOCATION);
    6483                 :         280 :                           g = gimple_build_cond (NE_EXPR, condv,
    6484                 :             :                                                  boolean_false_node,
    6485                 :             :                                                  lab2, lab1);
    6486                 :         280 :                           gimple_seq_add_stmt (ilist, g);
    6487                 :         280 :                           gimple_seq_add_stmt (ilist,
    6488                 :         280 :                                                gimple_build_label (lab1));
    6489                 :             :                         }
    6490                 :         296 :                       g = gimple_build_assign (build_simple_mem_ref (cond),
    6491                 :             :                                                boolean_true_node);
    6492                 :         296 :                       gimple_seq_add_stmt (ilist, g);
    6493                 :             :                     }
    6494                 :        1294 :                   x = lang_hooks.decls.omp_clause_default_ctor
    6495                 :        2292 :                                 (c, unshare_expr (new_var),
    6496                 :             :                                  cond ? NULL_TREE
    6497                 :         998 :                                  : build_outer_var_ref (var, ctx));
    6498                 :        1294 :                   if (x)
    6499                 :         301 :                     gimplify_and_add (x, ilist);
    6500                 :             : 
    6501                 :        1294 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    6502                 :        1294 :                       && OMP_CLAUSE_REDUCTION_INSCAN (c))
    6503                 :             :                     {
    6504                 :         172 :                       if (ctx->for_simd_scan_phase)
    6505                 :         998 :                         goto do_dtor;
    6506                 :         156 :                       if (x || (!is_simd
    6507                 :          32 :                                 && OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c)))
    6508                 :             :                         {
    6509                 :          80 :                           tree nv = create_tmp_var_raw (TREE_TYPE (new_var));
    6510                 :          80 :                           gimple_add_tmp_var (nv);
    6511                 :          80 :                           ctx->cb.decl_map->put (new_vard, nv);
    6512                 :          80 :                           x = lang_hooks.decls.omp_clause_default_ctor
    6513                 :          80 :                                 (c, nv, build_outer_var_ref (var, ctx));
    6514                 :          80 :                           if (x)
    6515                 :          80 :                             gimplify_and_add (x, ilist);
    6516                 :          80 :                           if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
    6517                 :             :                             {
    6518                 :          40 :                               tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
    6519                 :          40 :                               tree vexpr = nv;
    6520                 :          40 :                               if (new_vard != new_var)
    6521                 :          22 :                                 vexpr = build_fold_addr_expr (nv);
    6522                 :          40 :                               SET_DECL_VALUE_EXPR (new_vard, vexpr);
    6523                 :          40 :                               DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
    6524                 :          40 :                               lower_omp (&tseq, ctx);
    6525                 :          40 :                               SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
    6526                 :          40 :                               DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
    6527                 :          40 :                               gimple_seq_add_seq (ilist, tseq);
    6528                 :             :                             }
    6529                 :          80 :                           OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
    6530                 :          80 :                           if (is_simd && ctx->scan_exclusive)
    6531                 :             :                             {
    6532                 :          20 :                               tree nv2
    6533                 :          20 :                                 = create_tmp_var_raw (TREE_TYPE (new_var));
    6534                 :          20 :                               gimple_add_tmp_var (nv2);
    6535                 :          20 :                               ctx->cb.decl_map->put (nv, nv2);
    6536                 :          20 :                               x = lang_hooks.decls.omp_clause_default_ctor
    6537                 :          20 :                                     (c, nv2, build_outer_var_ref (var, ctx));
    6538                 :          20 :                               gimplify_and_add (x, ilist);
    6539                 :          20 :                               x = lang_hooks.decls.omp_clause_dtor (c, nv2);
    6540                 :          20 :                               if (x)
    6541                 :          20 :                                 gimplify_and_add (x, dlist);
    6542                 :             :                             }
    6543                 :          80 :                           x = lang_hooks.decls.omp_clause_dtor (c, nv);
    6544                 :          80 :                           if (x)
    6545                 :          80 :                             gimplify_and_add (x, dlist);
    6546                 :             :                         }
    6547                 :          76 :                       else if (is_simd
    6548                 :          44 :                                && ctx->scan_exclusive
    6549                 :          98 :                                && TREE_ADDRESSABLE (TREE_TYPE (new_var)))
    6550                 :             :                         {
    6551                 :           0 :                           tree nv2 = create_tmp_var_raw (TREE_TYPE (new_var));
    6552                 :           0 :                           gimple_add_tmp_var (nv2);
    6553                 :           0 :                           ctx->cb.decl_map->put (new_vard, nv2);
    6554                 :           0 :                           x = lang_hooks.decls.omp_clause_dtor (c, nv2);
    6555                 :           0 :                           if (x)
    6556                 :           0 :                             gimplify_and_add (x, dlist);
    6557                 :             :                         }
    6558                 :         156 :                       DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
    6559                 :         156 :                       goto do_dtor;
    6560                 :             :                     }
    6561                 :             : 
    6562                 :        1122 :                   if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
    6563                 :             :                     {
    6564                 :        1068 :                       tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
    6565                 :        1068 :                       if (c_kind == OMP_CLAUSE_IN_REDUCTION
    6566                 :        1068 :                           && is_omp_target (ctx->stmt))
    6567                 :             :                         {
    6568                 :          12 :                           tree d = maybe_lookup_decl_in_outer_ctx (var, ctx);
    6569                 :          12 :                           tree oldv = NULL_TREE;
    6570                 :          12 :                           gcc_assert (d);
    6571                 :          12 :                           if (DECL_HAS_VALUE_EXPR_P (d))
    6572                 :           6 :                             oldv = DECL_VALUE_EXPR (d);
    6573                 :          12 :                           SET_DECL_VALUE_EXPR (d, new_vard);
    6574                 :          12 :                           DECL_HAS_VALUE_EXPR_P (d) = 1;
    6575                 :          12 :                           lower_omp (&tseq, ctx);
    6576                 :          12 :                           if (oldv)
    6577                 :           6 :                             SET_DECL_VALUE_EXPR (d, oldv);
    6578                 :             :                           else
    6579                 :             :                             {
    6580                 :           6 :                               SET_DECL_VALUE_EXPR (d, NULL_TREE);
    6581                 :           6 :                               DECL_HAS_VALUE_EXPR_P (d) = 0;
    6582                 :             :                             }
    6583                 :             :                         }
    6584                 :             :                       else
    6585                 :        1056 :                         lower_omp (&tseq, ctx);
    6586                 :        1068 :                       gimple_seq_add_seq (ilist, tseq);
    6587                 :             :                     }
    6588                 :        1122 :                   OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
    6589                 :        1122 :                   if (is_simd)
    6590                 :             :                     {
    6591                 :          49 :                       tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
    6592                 :          49 :                       lower_omp (&tseq, ctx);
    6593                 :          49 :                       gimple_seq_add_seq (dlist, tseq);
    6594                 :          49 :                       OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    6595                 :             :                     }
    6596                 :        1122 :                   DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
    6597                 :        1122 :                   if (cond)
    6598                 :             :                     {
    6599                 :         296 :                       if (lab2)
    6600                 :         280 :                         gimple_seq_add_stmt (ilist, gimple_build_label (lab2));
    6601                 :             :                       break;
    6602                 :             :                     }
    6603                 :         826 :                   goto do_dtor;
    6604                 :             :                 }
    6605                 :             :               else
    6606                 :             :                 {
    6607                 :        7998 :                   x = omp_reduction_init (c, TREE_TYPE (new_var));
    6608                 :        7998 :                   gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
    6609                 :        7998 :                   enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
    6610                 :             : 
    6611                 :        7998 :                   if (cond)
    6612                 :             :                     {
    6613                 :        1558 :                       gimple *g;
    6614                 :        1558 :                       tree lab2 = NULL_TREE;
    6615                 :             :                       /* GOMP_taskgroup_reduction_register memsets the whole
    6616                 :             :                          array to zero.  If the initializer is zero, we don't
    6617                 :             :                          need to initialize it again, just mark it as ever
    6618                 :             :                          used unconditionally, i.e. cond = true.  */
    6619                 :        1558 :                       if (initializer_zerop (x))
    6620                 :             :                         {
    6621                 :        1374 :                           g = gimple_build_assign (build_simple_mem_ref (cond),
    6622                 :             :                                                    boolean_true_node);
    6623                 :        1374 :                           gimple_seq_add_stmt (ilist, g);
    6624                 :        3474 :                           break;
    6625                 :             :                         }
    6626                 :             : 
    6627                 :             :                       /* Otherwise, emit
    6628                 :             :                          if (!cond) { cond = true; new_var = x; }  */
    6629                 :         184 :                       if (!is_parallel_ctx (ctx))
    6630                 :             :                         {
    6631                 :         180 :                           tree condv = create_tmp_var (boolean_type_node);
    6632                 :         180 :                           tree m = build_simple_mem_ref (cond);
    6633                 :         180 :                           g = gimple_build_assign (condv, m);
    6634                 :         180 :                           gimple_seq_add_stmt (ilist, g);
    6635                 :         180 :                           tree lab1
    6636                 :         180 :                             = create_artificial_label (UNKNOWN_LOCATION);
    6637                 :         180 :                           lab2 = create_artificial_label (UNKNOWN_LOCATION);
    6638                 :         180 :                           g = gimple_build_cond (NE_EXPR, condv,
    6639                 :             :                                                  boolean_false_node,
    6640                 :             :                                                  lab2, lab1);
    6641                 :         180 :                           gimple_seq_add_stmt (ilist, g);
    6642                 :         180 :                           gimple_seq_add_stmt (ilist,
    6643                 :         180 :                                                gimple_build_label (lab1));
    6644                 :             :                         }
    6645                 :         184 :                       g = gimple_build_assign (build_simple_mem_ref (cond),
    6646                 :             :                                                boolean_true_node);
    6647                 :         184 :                       gimple_seq_add_stmt (ilist, g);
    6648                 :         184 :                       gimplify_assign (new_var, x, ilist);
    6649                 :         184 :                       if (lab2)
    6650                 :         180 :                         gimple_seq_add_stmt (ilist, gimple_build_label (lab2));
    6651                 :             :                       break;
    6652                 :             :                     }
    6653                 :             : 
    6654                 :             :                   /* reduction(-:var) sums up the partial results, so it
    6655                 :             :                      acts identically to reduction(+:var).  */
    6656                 :        6440 :                   if (code == MINUS_EXPR)
    6657                 :          25 :                     code = PLUS_EXPR;
    6658                 :             : 
    6659                 :        6440 :                   bool is_truth_op
    6660                 :        6440 :                     = (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR);
    6661                 :        6440 :                   tree new_vard = new_var;
    6662                 :        6440 :                   if (is_simd && omp_privatize_by_reference (var))
    6663                 :             :                     {
    6664                 :          82 :                       gcc_assert (TREE_CODE (new_var) == MEM_REF);
    6665                 :          82 :                       new_vard = TREE_OPERAND (new_var, 0);
    6666                 :          82 :                       gcc_assert (DECL_P (new_vard));
    6667                 :             :                     }
    6668                 :        6440 :                   tree rvar = NULL_TREE, *rvarp = NULL, rvar2 = NULL_TREE;
    6669                 :        6440 :                   if (is_simd
    6670                 :        2250 :                       && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    6671                 :        8690 :                       && OMP_CLAUSE_REDUCTION_INSCAN (c))
    6672                 :             :                     rvarp = &rvar;
    6673                 :        6440 :                   if (is_simd
    6674                 :        6440 :                       && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
    6675                 :             :                                                        ivar, lvar, rvarp,
    6676                 :             :                                                        &rvar2))
    6677                 :             :                     {
    6678                 :         889 :                       if (new_vard != new_var)
    6679                 :             :                         {
    6680                 :          48 :                           SET_DECL_VALUE_EXPR (new_vard,
    6681                 :             :                                                build_fold_addr_expr (lvar));
    6682                 :          48 :                           DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
    6683                 :             :                         }
    6684                 :             : 
    6685                 :         889 :                       tree ref = build_outer_var_ref (var, ctx);
    6686                 :             : 
    6687                 :         889 :                       if (rvarp)
    6688                 :             :                         {
    6689                 :         197 :                           if (ctx->for_simd_scan_phase)
    6690                 :             :                             break;
    6691                 :         158 :                           gimplify_assign (ivar, ref, &llist[0]);
    6692                 :         158 :                           ref = build_outer_var_ref (var, ctx);
    6693                 :         158 :                           gimplify_assign (ref, rvar, &llist[3]);
    6694                 :         158 :                           break;
    6695                 :             :                         }
    6696                 :             : 
    6697                 :         692 :                       gimplify_assign (unshare_expr (ivar), x, &llist[0]);
    6698                 :             : 
    6699                 :         692 :                       if (sctx.is_simt)
    6700                 :             :                         {
    6701                 :           0 :                           if (!simt_lane)
    6702                 :           0 :                             simt_lane = create_tmp_var (unsigned_type_node);
    6703                 :           0 :                           x = build_call_expr_internal_loc
    6704                 :           0 :                             (UNKNOWN_LOCATION, IFN_GOMP_SIMT_XCHG_BFLY,
    6705                 :           0 :                              TREE_TYPE (ivar), 2, ivar, simt_lane);
    6706                 :             :                           /* Make sure x is evaluated unconditionally.  */
    6707                 :           0 :                           tree bfly_var = create_tmp_var (TREE_TYPE (ivar));
    6708                 :           0 :                           gimplify_assign (bfly_var, x, &llist[2]);
    6709                 :           0 :                           x = build2 (code, TREE_TYPE (ivar), ivar, bfly_var);
    6710                 :           0 :                           gimplify_assign (ivar, x, &llist[2]);
    6711                 :             :                         }
    6712                 :         692 :                       tree ivar2 = ivar;
    6713                 :         692 :                       tree ref2 = ref;
    6714                 :         692 :                       if (is_truth_op)
    6715                 :             :                         {
    6716                 :          99 :                           tree zero = build_zero_cst (TREE_TYPE (ivar));
    6717                 :          99 :                           ivar2 = fold_build2_loc (clause_loc, NE_EXPR,
    6718                 :             :                                                    boolean_type_node, ivar,
    6719                 :             :                                                    zero);
    6720                 :          99 :                           ref2 = fold_build2_loc (clause_loc, NE_EXPR,
    6721                 :             :                                                   boolean_type_node, ref,
    6722                 :             :                                                   zero);
    6723                 :             :                         }
    6724                 :         692 :                       x = build2 (code, TREE_TYPE (ref), ref2, ivar2);
    6725                 :         692 :                       if (is_truth_op)
    6726                 :          99 :                         x = fold_convert (TREE_TYPE (ref), x);
    6727                 :         692 :                       ref = build_outer_var_ref (var, ctx);
    6728                 :         692 :                       gimplify_assign (ref, x, &llist[1]);
    6729                 :             : 
    6730                 :             :                     }
    6731                 :             :                   else
    6732                 :             :                     {
    6733                 :        5551 :                       lower_private_allocate (var, new_var, allocator,
    6734                 :             :                                               allocate_ptr, ilist, ctx,
    6735                 :             :                                               false, NULL_TREE);
    6736                 :        5551 :                       if (omp_privatize_by_reference (var) && is_simd)
    6737                 :          34 :                         handle_simd_reference (clause_loc, new_vard, ilist);
    6738                 :        5551 :                       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    6739                 :        5551 :                           && OMP_CLAUSE_REDUCTION_INSCAN (c))
    6740                 :             :                         break;
    6741                 :        5206 :                       gimplify_assign (new_var, x, ilist);
    6742                 :        5206 :                       if (is_simd)
    6743                 :             :                         {
    6744                 :        1160 :                           tree ref = build_outer_var_ref (var, ctx);
    6745                 :        1160 :                           tree new_var2 = new_var;
    6746                 :        1160 :                           tree ref2 = ref;
    6747                 :        1160 :                           if (is_truth_op)
    6748                 :             :                             {
    6749                 :          24 :                               tree zero = build_zero_cst (TREE_TYPE (new_var));
    6750                 :          24 :                               new_var2
    6751                 :          24 :                                 = fold_build2_loc (clause_loc, NE_EXPR,
    6752                 :             :                                                    boolean_type_node, new_var,
    6753                 :             :                                                    zero);
    6754                 :          24 :                               ref2 = fold_build2_loc (clause_loc, NE_EXPR,
    6755                 :             :                                                       boolean_type_node, ref,
    6756                 :             :                                                       zero);
    6757                 :             :                             }
    6758                 :        1160 :                           x = build2 (code, TREE_TYPE (ref2), ref2, new_var2);
    6759                 :        1160 :                           if (is_truth_op)
    6760                 :          24 :                             x = fold_convert (TREE_TYPE (new_var), x);
    6761                 :        1160 :                           ref = build_outer_var_ref (var, ctx);
    6762                 :        1160 :                           gimplify_assign (ref, x, dlist);
    6763                 :             :                         }
    6764                 :        5206 :                       if (allocator)
    6765                 :          84 :                         goto do_dtor;
    6766                 :             :                     }
    6767                 :             :                 }
    6768                 :        5814 :               break;
    6769                 :             : 
    6770                 :           0 :             default:
    6771                 :           0 :               gcc_unreachable ();
    6772                 :             :             }
    6773                 :             :         }
    6774                 :             :     }
    6775                 :       77254 :   if (tskred_avar)
    6776                 :             :     {
    6777                 :         923 :       tree clobber = build_clobber (TREE_TYPE (tskred_avar));
    6778                 :         923 :       gimple_seq_add_stmt (ilist, gimple_build_assign (tskred_avar, clobber));
    6779                 :             :     }
    6780                 :             : 
    6781                 :       77254 :   if (known_eq (sctx.max_vf, 1U))
    6782                 :             :     {
    6783                 :        2028 :       sctx.is_simt = false;
    6784                 :        2028 :       if (ctx->lastprivate_conditional_map)
    6785                 :             :         {
    6786                 :          55 :           if (gimple_omp_for_combined_into_p (ctx->stmt))
    6787                 :             :             {
    6788                 :             :               /* Signal to lower_omp_1 that it should use parent context.  */
    6789                 :          45 :               ctx->combined_into_simd_safelen1 = true;
    6790                 :         384 :               for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    6791                 :         339 :                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    6792                 :         339 :                     && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
    6793                 :             :                   {
    6794                 :          59 :                     tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
    6795                 :          59 :                     omp_context *outer = ctx->outer;
    6796                 :          59 :                     if (gimple_code (outer->stmt) == GIMPLE_OMP_SCAN)
    6797                 :           6 :                       outer = outer->outer;
    6798                 :          59 :                     tree *v = ctx->lastprivate_conditional_map->get (o);
    6799                 :          59 :                     tree po = lookup_decl (OMP_CLAUSE_DECL (c), outer);
    6800                 :          59 :                     tree *pv = outer->lastprivate_conditional_map->get (po);
    6801                 :          59 :                     *v = *pv;
    6802                 :             :                   }
    6803                 :             :             }
    6804                 :             :           else
    6805                 :             :             {
    6806                 :             :               /* When not vectorized, treat lastprivate(conditional:) like
    6807                 :             :                  normal lastprivate, as there will be just one simd lane
    6808                 :             :                  writing the privatized variable.  */
    6809                 :          10 :               delete ctx->lastprivate_conditional_map;
    6810                 :          10 :               ctx->lastprivate_conditional_map = NULL;
    6811                 :             :             }
    6812                 :             :         }
    6813                 :             :     }
    6814                 :             : 
    6815                 :       77254 :   if (nonconst_simd_if)
    6816                 :             :     {
    6817                 :         702 :       if (sctx.lane == NULL_TREE)
    6818                 :             :         {
    6819                 :         647 :           sctx.idx = create_tmp_var (unsigned_type_node);
    6820                 :         647 :           sctx.lane = create_tmp_var (unsigned_type_node);
    6821                 :             :         }
    6822                 :             :       /* FIXME: For now.  */
    6823                 :         702 :       sctx.is_simt = false;
    6824                 :             :     }
    6825                 :             : 
    6826                 :       77254 :   if (sctx.lane || sctx.is_simt)
    6827                 :             :     {
    6828                 :        4126 :       uid = create_tmp_var (ptr_type_node, "simduid");
    6829                 :             :       /* Don't want uninit warnings on simduid, it is always uninitialized,
    6830                 :             :          but we use it not for the value, but for the DECL_UID only.  */
    6831                 :        4126 :       suppress_warning (uid, OPT_Wuninitialized);
    6832                 :        4126 :       c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_);
    6833                 :        4126 :       OMP_CLAUSE__SIMDUID__DECL (c) = uid;
    6834                 :        4126 :       OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
    6835                 :        4126 :       gimple_omp_for_set_clauses (ctx->stmt, c);
    6836                 :             :     }
    6837                 :             :   /* Emit calls denoting privatized variables and initializing a pointer to
    6838                 :             :      structure that holds private variables as fields after ompdevlow pass.  */
    6839                 :       77254 :   if (sctx.is_simt)
    6840                 :             :     {
    6841                 :           0 :       sctx.simt_eargs[0] = uid;
    6842                 :           0 :       gimple *g
    6843                 :           0 :         = gimple_build_call_internal_vec (IFN_GOMP_SIMT_ENTER, sctx.simt_eargs);
    6844                 :           0 :       gimple_call_set_lhs (g, uid);
    6845                 :           0 :       gimple_seq_add_stmt (ilist, g);
    6846                 :           0 :       sctx.simt_eargs.release ();
    6847                 :             : 
    6848                 :           0 :       simtrec = create_tmp_var (ptr_type_node, ".omp_simt");
    6849                 :           0 :       g = gimple_build_call_internal (IFN_GOMP_SIMT_ENTER_ALLOC, 1, uid);
    6850                 :           0 :       gimple_call_set_lhs (g, simtrec);
    6851                 :           0 :       gimple_seq_add_stmt (ilist, g);
    6852                 :             :     }
    6853                 :       77254 :   if (sctx.lane)
    6854                 :             :     {
    6855                 :        7550 :       gimple *g = gimple_build_call_internal (IFN_GOMP_SIMD_LANE,
    6856                 :             :                                               2 + (nonconst_simd_if != NULL),
    6857                 :             :                                               uid, integer_zero_node,
    6858                 :             :                                               nonconst_simd_if);
    6859                 :        4126 :       gimple_call_set_lhs (g, sctx.lane);
    6860                 :        4126 :       gimple_stmt_iterator gsi = gsi_start (*gimple_omp_body_ptr (ctx->stmt));
    6861                 :        4126 :       gsi_insert_before_without_update (&gsi, g, GSI_SAME_STMT);
    6862                 :        4126 :       g = gimple_build_assign (sctx.lane, INTEGER_CST,
    6863                 :        4126 :                                build_int_cst (unsigned_type_node, 0));
    6864                 :        4126 :       gimple_seq_add_stmt (ilist, g);
    6865                 :        4126 :       if (sctx.lastlane)
    6866                 :             :         {
    6867                 :         202 :           g = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE,
    6868                 :             :                                           2, uid, sctx.lane);
    6869                 :         202 :           gimple_call_set_lhs (g, sctx.lastlane);
    6870                 :         202 :           gimple_seq_add_stmt (dlist, g);
    6871                 :         202 :           gimple_seq_add_seq (dlist, llist[3]);
    6872                 :             :         }
    6873                 :             :       /* Emit reductions across SIMT lanes in log_2(simt_vf) steps.  */
    6874                 :        4126 :       if (llist[2])
    6875                 :             :         {
    6876                 :           0 :           tree simt_vf = create_tmp_var (unsigned_type_node);
    6877                 :           0 :           g = gimple_build_call_internal (IFN_GOMP_SIMT_VF, 0);
    6878                 :           0 :           gimple_call_set_lhs (g, simt_vf);
    6879                 :           0 :           gimple_seq_add_stmt (dlist, g);
    6880                 :             : 
    6881                 :           0 :           tree t = build_int_cst (unsigned_type_node, 1);
    6882                 :           0 :           g = gimple_build_assign (simt_lane, INTEGER_CST, t);
    6883                 :           0 :           gimple_seq_add_stmt (dlist, g);
    6884                 :             : 
    6885                 :           0 :           t = build_int_cst (unsigned_type_node, 0);
    6886                 :           0 :           g = gimple_build_assign (sctx.idx, INTEGER_CST, t);
    6887                 :           0 :           gimple_seq_add_stmt (dlist, g);
    6888                 :             : 
    6889                 :           0 :           tree body = create_artificial_label (UNKNOWN_LOCATION);
    6890                 :           0 :           tree header = create_artificial_label (UNKNOWN_LOCATION);
    6891                 :           0 :           tree end = create_artificial_label (UNKNOWN_LOCATION);
    6892                 :           0 :           gimple_seq_add_stmt (dlist, gimple_build_goto (header));
    6893                 :           0 :           gimple_seq_add_stmt (dlist, gimple_build_label (body));
    6894                 :             : 
    6895                 :           0 :           gimple_seq_add_seq (dlist, llist[2]);
    6896                 :             : 
    6897                 :           0 :           g = gimple_build_assign (simt_lane, LSHIFT_EXPR, simt_lane, integer_one_node);
    6898                 :           0 :           gimple_seq_add_stmt (dlist, g);
    6899                 :             : 
    6900                 :           0 :           gimple_seq_add_stmt (dlist, gimple_build_label (header));
    6901                 :           0 :           g = gimple_build_cond (LT_EXPR, simt_lane, simt_vf, body, end);
    6902                 :           0 :           gimple_seq_add_stmt (dlist, g);
    6903                 :             : 
    6904                 :           0 :           gimple_seq_add_stmt (dlist, gimple_build_label (end));
    6905                 :             :         }
    6906                 :       12378 :       for (int i = 0; i < 2; i++)
    6907                 :        8252 :         if (llist[i])
    6908                 :             :           {
    6909                 :        1782 :             tree vf = create_tmp_var (unsigned_type_node);
    6910                 :        1782 :             g = gimple_build_call_internal (IFN_GOMP_SIMD_VF, 1, uid);
    6911                 :        1782 :             gimple_call_set_lhs (g, vf);
    6912                 :        1782 :             gimple_seq *seq = i == 0 ? ilist : dlist;
    6913                 :        1782 :             gimple_seq_add_stmt (seq, g);
    6914                 :        1782 :             tree t = build_int_cst (unsigned_type_node, 0);
    6915                 :        1782 :             g = gimple_build_assign (sctx.idx, INTEGER_CST, t);
    6916                 :        1782 :             gimple_seq_add_stmt (seq, g);
    6917                 :        1782 :             tree body = create_artificial_label (UNKNOWN_LOCATION);
    6918                 :        1782 :             tree header = create_artificial_label (UNKNOWN_LOCATION);
    6919                 :        1782 :             tree end = create_artificial_label (UNKNOWN_LOCATION);
    6920                 :        1782 :             gimple_seq_add_stmt (seq, gimple_build_goto (header));
    6921                 :        1782 :             gimple_seq_add_stmt (seq, gimple_build_label (body));
    6922                 :        1782 :             gimple_seq_add_seq (seq, llist[i]);
    6923                 :        1782 :             t = build_int_cst (unsigned_type_node, 1);
    6924                 :        1782 :             g = gimple_build_assign (sctx.idx, PLUS_EXPR, sctx.idx, t);
    6925                 :        1782 :             gimple_seq_add_stmt (seq, g);
    6926                 :        1782 :             gimple_seq_add_stmt (seq, gimple_build_label (header));
    6927                 :        1782 :             g = gimple_build_cond (LT_EXPR, sctx.idx, vf, body, end);
    6928                 :        1782 :             gimple_seq_add_stmt (seq, g);
    6929                 :        1782 :             gimple_seq_add_stmt (seq, gimple_build_label (end));
    6930                 :             :           }
    6931                 :             :     }
    6932                 :       77254 :   if (sctx.is_simt)
    6933                 :             :     {
    6934                 :           0 :       gimple_seq_add_seq (dlist, sctx.simt_dlist);
    6935                 :           0 :       gimple *g
    6936                 :           0 :         = gimple_build_call_internal (IFN_GOMP_SIMT_EXIT, 1, simtrec);
    6937                 :           0 :       gimple_seq_add_stmt (dlist, g);
    6938                 :             :     }
    6939                 :             : 
    6940                 :             :   /* The copyin sequence is not to be executed by the main thread, since
    6941                 :             :      that would result in self-copies.  Perhaps not visible to scalars,
    6942                 :             :      but it certainly is to C++ operator=.  */
    6943                 :       77254 :   if (copyin_seq)
    6944                 :             :     {
    6945                 :         476 :       x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
    6946                 :             :                            0);
    6947                 :         476 :       x = build2 (NE_EXPR, boolean_type_node, x,
    6948                 :         476 :                   build_int_cst (TREE_TYPE (x), 0));
    6949                 :         476 :       x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
    6950                 :         476 :       gimplify_and_add (x, ilist);
    6951                 :             :     }
    6952                 :             : 
    6953                 :             :   /* If any copyin variable is passed by reference, we must ensure the
    6954                 :             :      master thread doesn't modify it before it is copied over in all
    6955                 :             :      threads.  Similarly for variables in both firstprivate and
    6956                 :             :      lastprivate clauses we need to ensure the lastprivate copying
    6957                 :             :      happens after firstprivate copying in all threads.  And similarly
    6958                 :             :      for UDRs if initializer expression refers to omp_orig.  */
    6959                 :       77254 :   if (copyin_by_ref || lastprivate_firstprivate
    6960                 :       75188 :       || (reduction_omp_orig_ref
    6961                 :          90 :           && !ctx->scan_inclusive
    6962                 :          90 :           && !ctx->scan_exclusive))
    6963                 :             :     {
    6964                 :             :       /* Don't add any barrier for #pragma omp simd or
    6965                 :             :          #pragma omp distribute.  */
    6966                 :        2156 :       if (!is_task_ctx (ctx)
    6967                 :        2156 :           && (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
    6968                 :        1602 :               || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR))
    6969                 :         930 :         gimple_seq_add_stmt (ilist, omp_build_barrier (NULL_TREE));
    6970                 :             :     }
    6971                 :             : 
    6972                 :             :   /* If max_vf is non-zero, then we can use only a vectorization factor
    6973                 :             :      up to the max_vf we chose.  So stick it into the safelen clause.  */
    6974                 :       77254 :   if (maybe_ne (sctx.max_vf, 0U))
    6975                 :             :     {
    6976                 :        5507 :       tree c = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
    6977                 :             :                                 OMP_CLAUSE_SAFELEN);
    6978                 :        5507 :       poly_uint64 safe_len;
    6979                 :        5507 :       if (c == NULL_TREE
    6980                 :        5507 :           || (poly_int_tree_p (OMP_CLAUSE_SAFELEN_EXPR (c), &safe_len)
    6981                 :         688 :               && maybe_gt (safe_len, sctx.max_vf)))
    6982                 :             :         {
    6983                 :        5416 :           c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
    6984                 :        5416 :           OMP_CLAUSE_SAFELEN_EXPR (c) = build_int_cst (integer_type_node,
    6985                 :             :                                                        sctx.max_vf);
    6986                 :        5416 :           OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
    6987                 :        5416 :           gimple_omp_for_set_clauses (ctx->stmt, c);
    6988                 :             :         }
    6989                 :             :     }
    6990                 :       77254 : }
    6991                 :             : 
    6992                 :             : /* Create temporary variables for lastprivate(conditional:) implementation
    6993                 :             :    in context CTX with CLAUSES.  */
    6994                 :             : 
    6995                 :             : static void
    6996                 :       47108 : lower_lastprivate_conditional_clauses (tree *clauses, omp_context *ctx)
    6997                 :             : {
    6998                 :       47108 :   tree iter_type = NULL_TREE;
    6999                 :       47108 :   tree cond_ptr = NULL_TREE;
    7000                 :       47108 :   tree iter_var = NULL_TREE;
    7001                 :       47108 :   bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    7002                 :       47108 :                   && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD);
    7003                 :       47108 :   tree next = *clauses;
    7004                 :      228897 :   for (tree c = *clauses; c; c = OMP_CLAUSE_CHAIN (c))
    7005                 :      181789 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7006                 :      181789 :         && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
    7007                 :             :       {
    7008                 :         400 :         if (is_simd)
    7009                 :             :           {
    7010                 :         110 :             tree cc = omp_find_clause (next, OMP_CLAUSE__CONDTEMP_);
    7011                 :         110 :             gcc_assert (cc);
    7012                 :         110 :             if (iter_type == NULL_TREE)
    7013                 :             :               {
    7014                 :          80 :                 iter_type = TREE_TYPE (OMP_CLAUSE_DECL (cc));
    7015                 :          80 :                 iter_var = create_tmp_var_raw (iter_type);
    7016                 :          80 :                 DECL_CONTEXT (iter_var) = current_function_decl;
    7017                 :          80 :                 DECL_SEEN_IN_BIND_EXPR_P (iter_var) = 1;
    7018                 :          80 :                 DECL_CHAIN (iter_var) = ctx->block_vars;
    7019                 :          80 :                 ctx->block_vars = iter_var;
    7020                 :          80 :                 tree c3
    7021                 :          80 :                   = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
    7022                 :          80 :                 OMP_CLAUSE__CONDTEMP__ITER (c3) = 1;
    7023                 :          80 :                 OMP_CLAUSE_DECL (c3) = iter_var;
    7024                 :          80 :                 OMP_CLAUSE_CHAIN (c3) = *clauses;
    7025                 :          80 :                 *clauses = c3;
    7026                 :          80 :                 ctx->lastprivate_conditional_map = new hash_map<tree, tree>;
    7027                 :             :               }
    7028                 :         110 :             next = OMP_CLAUSE_CHAIN (cc);
    7029                 :         110 :             tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
    7030                 :         110 :             tree v = lookup_decl (OMP_CLAUSE_DECL (cc), ctx);
    7031                 :         110 :             ctx->lastprivate_conditional_map->put (o, v);
    7032                 :         110 :             continue;
    7033                 :         110 :           }
    7034                 :         290 :         if (iter_type == NULL)
    7035                 :             :           {
    7036                 :         213 :             if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR)
    7037                 :             :               {
    7038                 :         201 :                 struct omp_for_data fd;
    7039                 :         201 :                 omp_extract_for_data (as_a <gomp_for *> (ctx->stmt), &fd,
    7040                 :             :                                       NULL);
    7041                 :         201 :                 iter_type = unsigned_type_for (fd.iter_type);
    7042                 :             :               }
    7043                 :          12 :             else if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
    7044                 :          12 :               iter_type = unsigned_type_node;
    7045                 :         213 :             tree c2 = omp_find_clause (*clauses, OMP_CLAUSE__CONDTEMP_);
    7046                 :         213 :             if (c2)
    7047                 :             :               {
    7048                 :         108 :                 cond_ptr
    7049                 :         108 :                   = lookup_decl_in_outer_ctx (OMP_CLAUSE_DECL (c2), ctx);
    7050                 :         108 :                 OMP_CLAUSE_DECL (c2) = cond_ptr;
    7051                 :             :               }
    7052                 :             :             else
    7053                 :             :               {
    7054                 :         105 :                 cond_ptr = create_tmp_var_raw (build_pointer_type (iter_type));
    7055                 :         105 :                 DECL_CONTEXT (cond_ptr) = current_function_decl;
    7056                 :         105 :                 DECL_SEEN_IN_BIND_EXPR_P (cond_ptr) = 1;
    7057                 :         105 :                 DECL_CHAIN (cond_ptr) = ctx->block_vars;
    7058                 :         105 :                 ctx->block_vars = cond_ptr;
    7059                 :         105 :                 c2 = build_omp_clause (UNKNOWN_LOCATION,
    7060                 :             :                                        OMP_CLAUSE__CONDTEMP_);
    7061                 :         105 :                 OMP_CLAUSE_DECL (c2) = cond_ptr;
    7062                 :         105 :                 OMP_CLAUSE_CHAIN (c2) = *clauses;
    7063                 :         105 :                 *clauses = c2;
    7064                 :             :               }
    7065                 :         213 :             iter_var = create_tmp_var_raw (iter_type);
    7066                 :         213 :             DECL_CONTEXT (iter_var) = current_function_decl;
    7067                 :         213 :             DECL_SEEN_IN_BIND_EXPR_P (iter_var) = 1;
    7068                 :         213 :             DECL_CHAIN (iter_var) = ctx->block_vars;
    7069                 :         213 :             ctx->block_vars = iter_var;
    7070                 :         213 :             tree c3
    7071                 :         213 :               = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
    7072                 :         213 :             OMP_CLAUSE__CONDTEMP__ITER (c3) = 1;
    7073                 :         213 :             OMP_CLAUSE_DECL (c3) = iter_var;
    7074                 :         213 :             OMP_CLAUSE_CHAIN (c3) = OMP_CLAUSE_CHAIN (c2);
    7075                 :         213 :             OMP_CLAUSE_CHAIN (c2) = c3;
    7076                 :         213 :             ctx->lastprivate_conditional_map = new hash_map<tree, tree>;
    7077                 :             :           }
    7078                 :         290 :         tree v = create_tmp_var_raw (iter_type);
    7079                 :         290 :         DECL_CONTEXT (v) = current_function_decl;
    7080                 :         290 :         DECL_SEEN_IN_BIND_EXPR_P (v) = 1;
    7081                 :         290 :         DECL_CHAIN (v) = ctx->block_vars;
    7082                 :         290 :         ctx->block_vars = v;
    7083                 :         290 :         tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
    7084                 :         290 :         ctx->lastprivate_conditional_map->put (o, v);
    7085                 :             :       }
    7086                 :       47108 : }
    7087                 :             : 
    7088                 :             : 
    7089                 :             : /* Generate code to implement the LASTPRIVATE clauses.  This is used for
    7090                 :             :    both parallel and workshare constructs.  PREDICATE may be NULL if it's
    7091                 :             :    always true.  BODY_P is the sequence to insert early initialization
    7092                 :             :    if needed, STMT_LIST is where the non-conditional lastprivate handling
    7093                 :             :    goes into and CSTMT_LIST is a sequence that needs to be run in a critical
    7094                 :             :    section.  */
    7095                 :             : 
    7096                 :             : static void
    7097                 :       47108 : lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p,
    7098                 :             :                            gimple_seq *stmt_list, gimple_seq *cstmt_list,
    7099                 :             :                            omp_context *ctx)
    7100                 :             : {
    7101                 :       47108 :   tree x, c, label = NULL, orig_clauses = clauses;
    7102                 :       47108 :   bool par_clauses = false;
    7103                 :       47108 :   tree simduid = NULL, lastlane = NULL, simtcond = NULL, simtlast = NULL;
    7104                 :       47108 :   unsigned HOST_WIDE_INT conditional_off = 0;
    7105                 :       47108 :   gimple_seq post_stmt_list = NULL;
    7106                 :             : 
    7107                 :             :   /* Early exit if there are no lastprivate or linear clauses.  */
    7108                 :      196708 :   for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
    7109                 :      162760 :     if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LASTPRIVATE
    7110                 :      162760 :         || (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LINEAR
    7111                 :        7218 :             && !OMP_CLAUSE_LINEAR_NO_COPYOUT (clauses)))
    7112                 :             :       break;
    7113                 :       47108 :   if (clauses == NULL)
    7114                 :             :     {
    7115                 :             :       /* If this was a workshare clause, see if it had been combined
    7116                 :             :          with its parallel.  In that case, look for the clauses on the
    7117                 :             :          parallel statement itself.  */
    7118                 :       33948 :       if (is_parallel_ctx (ctx))
    7119                 :       29875 :         return;
    7120                 :             : 
    7121                 :       33948 :       ctx = ctx->outer;
    7122                 :       33948 :       if (ctx == NULL || !is_parallel_ctx (ctx))
    7123                 :             :         return;
    7124                 :             : 
    7125                 :       11875 :       clauses = omp_find_clause (gimple_omp_parallel_clauses (ctx->stmt),
    7126                 :             :                                  OMP_CLAUSE_LASTPRIVATE);
    7127                 :       11875 :       if (clauses == NULL)
    7128                 :             :         return;
    7129                 :             :       par_clauses = true;
    7130                 :             :     }
    7131                 :             : 
    7132                 :       17233 :   bool maybe_simt = false;
    7133                 :       17233 :   if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    7134                 :       17233 :       && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
    7135                 :             :     {
    7136                 :        7810 :       maybe_simt = omp_find_clause (orig_clauses, OMP_CLAUSE__SIMT_);
    7137                 :        7810 :       simduid = omp_find_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
    7138                 :        7810 :       if (simduid)
    7139                 :        3643 :         simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
    7140                 :             :     }
    7141                 :             : 
    7142                 :       17233 :   if (predicate)
    7143                 :             :     {
    7144                 :       17102 :       gcond *stmt;
    7145                 :       17102 :       tree label_true, arm1, arm2;
    7146                 :       17102 :       enum tree_code pred_code = TREE_CODE (predicate);
    7147                 :             : 
    7148                 :       17102 :       label = create_artificial_label (UNKNOWN_LOCATION);
    7149                 :       17102 :       label_true = create_artificial_label (UNKNOWN_LOCATION);
    7150                 :       17102 :       if (TREE_CODE_CLASS (pred_code) == tcc_comparison)
    7151                 :             :         {
    7152                 :       17102 :           arm1 = TREE_OPERAND (predicate, 0);
    7153                 :       17102 :           arm2 = TREE_OPERAND (predicate, 1);
    7154                 :       17102 :           gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
    7155                 :       17102 :           gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
    7156                 :             :         }
    7157                 :             :       else
    7158                 :             :         {
    7159                 :           0 :           arm1 = predicate;
    7160                 :           0 :           gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
    7161                 :           0 :           arm2 = boolean_false_node;
    7162                 :           0 :           pred_code = NE_EXPR;
    7163                 :             :         }
    7164                 :       17102 :       if (maybe_simt)
    7165                 :             :         {
    7166                 :           0 :           c = build2 (pred_code, boolean_type_node, arm1, arm2);
    7167                 :           0 :           c = fold_convert (integer_type_node, c);
    7168                 :           0 :           simtcond = create_tmp_var (integer_type_node);
    7169                 :           0 :           gimplify_assign (simtcond, c, stmt_list);
    7170                 :           0 :           gcall *g = gimple_build_call_internal (IFN_GOMP_SIMT_VOTE_ANY,
    7171                 :             :                                                  1, simtcond);
    7172                 :           0 :           c = create_tmp_var (integer_type_node);
    7173                 :           0 :           gimple_call_set_lhs (g, c);
    7174                 :           0 :           gimple_seq_add_stmt (stmt_list, g);
    7175                 :           0 :           stmt = gimple_build_cond (NE_EXPR, c, integer_zero_node,
    7176                 :             :                                     label_true, label);
    7177                 :             :         }
    7178                 :             :       else
    7179                 :       17102 :         stmt = gimple_build_cond (pred_code, arm1, arm2, label_true, label);
    7180                 :       17102 :       gimple_seq_add_stmt (stmt_list, stmt);
    7181                 :       17102 :       gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
    7182                 :             :     }
    7183                 :             : 
    7184                 :       17233 :   tree cond_ptr = NULL_TREE;
    7185                 :       63686 :   for (c = clauses; c ;)
    7186                 :             :     {
    7187                 :       58323 :       tree var, new_var;
    7188                 :       58323 :       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
    7189                 :       58323 :       gimple_seq *this_stmt_list = stmt_list;
    7190                 :       58323 :       tree lab2 = NULL_TREE;
    7191                 :             : 
    7192                 :       58323 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7193                 :       22554 :           && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
    7194                 :         400 :           && ctx->lastprivate_conditional_map
    7195                 :       58709 :           && !ctx->combined_into_simd_safelen1)
    7196                 :             :         {
    7197                 :         327 :           gcc_assert (body_p);
    7198                 :         327 :           if (simduid)
    7199                 :          37 :             goto next;
    7200                 :         290 :           if (cond_ptr == NULL_TREE)
    7201                 :             :             {
    7202                 :         213 :               cond_ptr = omp_find_clause (orig_clauses, OMP_CLAUSE__CONDTEMP_);
    7203                 :         213 :               cond_ptr = OMP_CLAUSE_DECL (cond_ptr);
    7204                 :             :             }
    7205                 :         290 :           tree type = TREE_TYPE (TREE_TYPE (cond_ptr));
    7206                 :         290 :           tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
    7207                 :         290 :           tree v = *ctx->lastprivate_conditional_map->get (o);
    7208                 :         290 :           gimplify_assign (v, build_zero_cst (type), body_p);
    7209                 :         290 :           this_stmt_list = cstmt_list;
    7210                 :         290 :           tree mem;
    7211                 :         290 :           if (POINTER_TYPE_P (TREE_TYPE (cond_ptr)))
    7212                 :             :             {
    7213                 :         139 :               mem = build2 (MEM_REF, type, cond_ptr,
    7214                 :         139 :                             build_int_cst (TREE_TYPE (cond_ptr),
    7215                 :             :                                            conditional_off));
    7216                 :         139 :               conditional_off += tree_to_uhwi (TYPE_SIZE_UNIT (type));
    7217                 :             :             }
    7218                 :             :           else
    7219                 :         151 :             mem = build4 (ARRAY_REF, type, cond_ptr,
    7220                 :         151 :                           size_int (conditional_off++), NULL_TREE, NULL_TREE);
    7221                 :         290 :           tree mem2 = copy_node (mem);
    7222                 :         290 :           gimple_seq seq = NULL;
    7223                 :         290 :           mem = force_gimple_operand (mem, &seq, true, NULL_TREE);
    7224                 :         290 :           gimple_seq_add_seq (this_stmt_list, seq);
    7225                 :         290 :           tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
    7226                 :         290 :           lab2 = create_artificial_label (UNKNOWN_LOCATION);
    7227                 :         290 :           gimple *g = gimple_build_cond (GT_EXPR, v, mem, lab1, lab2);
    7228                 :         290 :           gimple_seq_add_stmt (this_stmt_list, g);
    7229                 :         290 :           gimple_seq_add_stmt (this_stmt_list, gimple_build_label (lab1));
    7230                 :         290 :           gimplify_assign (mem2, v, this_stmt_list);
    7231                 :             :         }
    7232                 :       57996 :       else if (predicate
    7233                 :       57738 :                && ctx->combined_into_simd_safelen1
    7234                 :         120 :                && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7235                 :          59 :                && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
    7236                 :       58055 :                && ctx->lastprivate_conditional_map)
    7237                 :             :         this_stmt_list = &post_stmt_list;
    7238                 :             : 
    7239                 :       58286 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7240                 :       58286 :           || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
    7241                 :        5136 :               && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
    7242                 :             :         {
    7243                 :       27653 :           var = OMP_CLAUSE_DECL (c);
    7244                 :       27653 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7245                 :       22517 :               && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
    7246                 :       28751 :               && is_taskloop_ctx (ctx))
    7247                 :             :             {
    7248                 :         343 :               gcc_checking_assert (ctx->outer && is_task_ctx (ctx->outer));
    7249                 :         343 :               new_var = lookup_decl (var, ctx->outer);
    7250                 :             :             }
    7251                 :             :           else
    7252                 :             :             {
    7253                 :       27310 :               new_var = lookup_decl (var, ctx);
    7254                 :             :               /* Avoid uninitialized warnings for lastprivate and
    7255                 :             :                  for linear iterators.  */
    7256                 :       27310 :               if (predicate
    7257                 :       54413 :                   && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7258                 :        5136 :                       || OMP_CLAUSE_LINEAR_NO_COPYIN (c)))
    7259                 :       25755 :                 suppress_warning (new_var, OPT_Wuninitialized);
    7260                 :             :             }
    7261                 :             : 
    7262                 :       27653 :           if (!maybe_simt && simduid && DECL_HAS_VALUE_EXPR_P (new_var))
    7263                 :             :             {
    7264                 :        5877 :               tree val = DECL_VALUE_EXPR (new_var);
    7265                 :        5877 :               if (TREE_CODE (val) == ARRAY_REF
    7266                 :        5825 :                   && VAR_P (TREE_OPERAND (val, 0))
    7267                 :       11702 :                   && lookup_attribute ("omp simd array",
    7268                 :        5825 :                                        DECL_ATTRIBUTES (TREE_OPERAND (val,
    7269                 :             :                                                                       0))))
    7270                 :             :                 {
    7271                 :        5825 :                   if (lastlane == NULL)
    7272                 :             :                     {
    7273                 :        2764 :                       lastlane = create_tmp_var (unsigned_type_node);
    7274                 :        2764 :                       gcall *g
    7275                 :        2764 :                         = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE,
    7276                 :             :                                                       2, simduid,
    7277                 :        2764 :                                                       TREE_OPERAND (val, 1));
    7278                 :        2764 :                       gimple_call_set_lhs (g, lastlane);
    7279                 :        2764 :                       gimple_seq_add_stmt (this_stmt_list, g);
    7280                 :             :                     }
    7281                 :        5825 :                   new_var = build4 (ARRAY_REF, TREE_TYPE (val),
    7282                 :        5825 :                                     TREE_OPERAND (val, 0), lastlane,
    7283                 :             :                                     NULL_TREE, NULL_TREE);
    7284                 :        5825 :                   TREE_THIS_NOTRAP (new_var) = 1;
    7285                 :             :                 }
    7286                 :             :             }
    7287                 :       21776 :           else if (maybe_simt)
    7288                 :             :             {
    7289                 :           0 :               tree val = (DECL_HAS_VALUE_EXPR_P (new_var)
    7290                 :           0 :                           ? DECL_VALUE_EXPR (new_var)
    7291                 :           0 :                           : new_var);
    7292                 :           0 :               if (simtlast == NULL)
    7293                 :             :                 {
    7294                 :           0 :                   simtlast = create_tmp_var (unsigned_type_node);
    7295                 :           0 :                   gcall *g = gimple_build_call_internal
    7296                 :           0 :                     (IFN_GOMP_SIMT_LAST_LANE, 1, simtcond);
    7297                 :           0 :                   gimple_call_set_lhs (g, simtlast);
    7298                 :           0 :                   gimple_seq_add_stmt (this_stmt_list, g);
    7299                 :             :                 }
    7300                 :           0 :               x = build_call_expr_internal_loc
    7301                 :           0 :                 (UNKNOWN_LOCATION, IFN_GOMP_SIMT_XCHG_IDX,
    7302                 :           0 :                  TREE_TYPE (val), 2, val, simtlast);
    7303                 :           0 :               new_var = unshare_expr (new_var);
    7304                 :           0 :               gimplify_assign (new_var, x, this_stmt_list);
    7305                 :           0 :               new_var = unshare_expr (new_var);
    7306                 :             :             }
    7307                 :             : 
    7308                 :       27653 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7309                 :       27653 :               && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
    7310                 :             :             {
    7311                 :        7277 :               lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
    7312                 :        7277 :               gimple_seq_add_seq (this_stmt_list,
    7313                 :        7277 :                                   OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
    7314                 :        7277 :               OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
    7315                 :             :             }
    7316                 :       20376 :           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
    7317                 :       20376 :                    && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
    7318                 :             :             {
    7319                 :         455 :               lower_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
    7320                 :         455 :               gimple_seq_add_seq (this_stmt_list,
    7321                 :         455 :                                   OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
    7322                 :         455 :               OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) = NULL;
    7323                 :             :             }
    7324                 :             : 
    7325                 :       27653 :           x = NULL_TREE;
    7326                 :       27653 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
    7327                 :       22517 :               && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)
    7328                 :       27713 :               && is_taskloop_ctx (ctx))
    7329                 :             :             {
    7330                 :          76 :               tree ovar = maybe_lookup_decl_in_outer_ctx (var,
    7331                 :          38 :                                                           ctx->outer->outer);
    7332                 :          38 :               if (is_global_var (ovar))
    7333                 :           7 :                 x = ovar;
    7334                 :             :             }
    7335                 :           7 :           if (!x)
    7336                 :       27646 :             x = build_outer_var_ref (var, ctx, OMP_CLAUSE_LASTPRIVATE);
    7337                 :       27653 :           if (omp_privatize_by_reference (var))
    7338                 :         675 :             new_var = build_simple_mem_ref_loc (clause_loc, new_var);
    7339                 :       27653 :           x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
    7340                 :       27653 :           gimplify_and_add (x, this_stmt_list);
    7341                 :             : 
    7342                 :       27653 :           if (lab2)
    7343                 :         290 :             gimple_seq_add_stmt (this_stmt_list, gimple_build_label (lab2));
    7344                 :             :         }
    7345                 :             : 
    7346                 :       58323 :      next:
    7347                 :       58323 :       c = OMP_CLAUSE_CHAIN (c);
    7348                 :       58323 :       if (c == NULL && !par_clauses)
    7349                 :             :         {
    7350                 :             :           /* If this was a workshare clause, see if it had been combined
    7351                 :             :              with its parallel.  In that case, continue looking for the
    7352                 :             :              clauses also on the parallel statement itself.  */
    7353                 :       13160 :           if (is_parallel_ctx (ctx))
    7354                 :             :             break;
    7355                 :             : 
    7356                 :       13160 :           ctx = ctx->outer;
    7357                 :       13160 :           if (ctx == NULL || !is_parallel_ctx (ctx))
    7358                 :             :             break;
    7359                 :             : 
    7360                 :        1290 :           c = omp_find_clause (gimple_omp_parallel_clauses (ctx->stmt),
    7361                 :             :                                OMP_CLAUSE_LASTPRIVATE);
    7362                 :        1290 :           par_clauses = true;
    7363                 :             :         }
    7364                 :             :     }
    7365                 :             : 
    7366                 :       17233 :   if (label)
    7367                 :       17102 :     gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
    7368                 :       17233 :   gimple_seq_add_seq (stmt_list, post_stmt_list);
    7369                 :             : }
    7370                 :             : 
    7371                 :             : /* Lower the OpenACC reductions of CLAUSES for compute axis LEVEL
    7372                 :             :    (which might be a placeholder).  INNER is true if this is an inner
    7373                 :             :    axis of a multi-axis loop.  FORK and JOIN are (optional) fork and
    7374                 :             :    join markers.  Generate the before-loop forking sequence in
    7375                 :             :    FORK_SEQ and the after-loop joining sequence to JOIN_SEQ.  The
    7376                 :             :    general form of these sequences is
    7377                 :             : 
    7378                 :             :      GOACC_REDUCTION_SETUP
    7379                 :             :      GOACC_FORK
    7380                 :             :      GOACC_REDUCTION_INIT
    7381                 :             :      ...
    7382                 :             :      GOACC_REDUCTION_FINI
    7383                 :             :      GOACC_JOIN
    7384                 :             :      GOACC_REDUCTION_TEARDOWN.  */
    7385                 :             : 
    7386                 :             : static void
    7387                 :       24001 : lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner,
    7388                 :             :                        gcall *fork, gcall *private_marker, gcall *join,
    7389                 :             :                        gimple_seq *fork_seq, gimple_seq *join_seq,
    7390                 :             :                        omp_context *ctx)
    7391                 :             : {
    7392                 :       24001 :   gimple_seq before_fork = NULL;
    7393                 :       24001 :   gimple_seq after_fork = NULL;
    7394                 :       24001 :   gimple_seq before_join = NULL;
    7395                 :       24001 :   gimple_seq after_join = NULL;
    7396                 :       24001 :   tree init_code = NULL_TREE, fini_code = NULL_TREE,
    7397                 :       24001 :     setup_code = NULL_TREE, teardown_code = NULL_TREE;
    7398                 :       24001 :   unsigned offset = 0;
    7399                 :             : 
    7400                 :       91292 :   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    7401                 :       67291 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
    7402                 :             :       {
    7403                 :             :         /* No 'reduction' clauses on OpenACC 'kernels'.  */
    7404                 :        6380 :         gcc_checking_assert (!is_oacc_kernels (ctx));
    7405                 :             :         /* Likewise, on OpenACC 'kernels' decomposed parts.  */
    7406                 :        6380 :         gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));
    7407                 :             : 
    7408                 :        6380 :         tree orig = OMP_CLAUSE_DECL (c);
    7409                 :        6380 :         tree var = maybe_lookup_decl (orig, ctx);
    7410                 :        6380 :         tree ref_to_res = NULL_TREE;
    7411                 :        6380 :         tree incoming, outgoing, v1, v2, v3;
    7412                 :        6380 :         bool is_private = false;
    7413                 :             : 
    7414                 :        6380 :         enum tree_code rcode = OMP_CLAUSE_REDUCTION_CODE (c);
    7415                 :        6380 :         if (rcode == MINUS_EXPR)
    7416                 :             :           rcode = PLUS_EXPR;
    7417                 :        5612 :         else if (rcode == TRUTH_ANDIF_EXPR)
    7418                 :             :           rcode = BIT_AND_EXPR;
    7419                 :        5432 :         else if (rcode == TRUTH_ORIF_EXPR)
    7420                 :         435 :           rcode = BIT_IOR_EXPR;
    7421                 :        6380 :         tree op = build_int_cst (unsigned_type_node, rcode);
    7422                 :             : 
    7423                 :        6380 :         if (!var)
    7424                 :           5 :           var = orig;
    7425                 :             : 
    7426                 :        6380 :         incoming = outgoing = var;
    7427                 :             : 
    7428                 :        6380 :         if (!inner)
    7429                 :             :           {
    7430                 :             :             /* See if an outer construct also reduces this variable.  */
    7431                 :             :             omp_context *outer = ctx;
    7432                 :             : 
    7433                 :        6428 :             while (omp_context *probe = outer->outer)
    7434                 :             :               {
    7435                 :        3871 :                 enum gimple_code type = gimple_code (probe->stmt);
    7436                 :        3871 :                 tree cls;
    7437                 :             : 
    7438                 :        3871 :                 switch (type)
    7439                 :             :                   {
    7440                 :        1566 :                   case GIMPLE_OMP_FOR:
    7441                 :        1566 :                     cls = gimple_omp_for_clauses (probe->stmt);
    7442                 :        1566 :                     break;
    7443                 :             : 
    7444                 :        2305 :                   case GIMPLE_OMP_TARGET:
    7445                 :             :                     /* No 'reduction' clauses inside OpenACC 'kernels'
    7446                 :             :                        regions.  */
    7447                 :        2305 :                     gcc_checking_assert (!is_oacc_kernels (probe));
    7448                 :             : 
    7449                 :        2305 :                     if (!is_gimple_omp_offloaded (probe->stmt))
    7450                 :          31 :                       goto do_lookup;
    7451                 :             : 
    7452                 :        2274 :                     cls = gimple_omp_target_clauses (probe->stmt);
    7453                 :        2274 :                     break;
    7454                 :             : 
    7455                 :           0 :                   default:
    7456                 :           0 :                     goto do_lookup;
    7457                 :             :                   }
    7458                 :             : 
    7459                 :       12901 :                 outer = probe;
    7460                 :       12901 :                 for (; cls;  cls = OMP_CLAUSE_CHAIN (cls))
    7461                 :       10437 :                   if (OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_REDUCTION
    7462                 :       10437 :                       && orig == OMP_CLAUSE_DECL (cls))
    7463                 :             :                     {
    7464                 :        1296 :                       incoming = outgoing = lookup_decl (orig, probe);
    7465                 :        1296 :                       goto has_outer_reduction;
    7466                 :             :                     }
    7467                 :        9141 :                   else if ((OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_FIRSTPRIVATE
    7468                 :        8531 :                             || OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_PRIVATE)
    7469                 :       10032 :                            && orig == OMP_CLAUSE_DECL (cls))
    7470                 :             :                     {
    7471                 :          80 :                       is_private = true;
    7472                 :          80 :                       goto do_lookup;
    7473                 :             :                     }
    7474                 :             :               }
    7475                 :             : 
    7476                 :        2557 :           do_lookup:
    7477                 :             :             /* This is the outermost construct with this reduction,
    7478                 :             :                see if there's a mapping for it.  */
    7479                 :        2668 :             if (gimple_code (outer->stmt) == GIMPLE_OMP_TARGET
    7480                 :        5175 :                 && maybe_lookup_field (orig, outer) && !is_private)
    7481                 :             :               {
    7482                 :        2413 :                 ref_to_res = build_receiver_ref (orig, false, outer);
    7483                 :        2413 :                 if (omp_privatize_by_reference (orig))
    7484                 :          79 :                   ref_to_res = build_simple_mem_ref (ref_to_res);
    7485                 :             : 
    7486                 :        2413 :                 tree type = TREE_TYPE (var);
    7487                 :        2413 :                 if (POINTER_TYPE_P (type))
    7488                 :          79 :                   type = TREE_TYPE (type);
    7489                 :             : 
    7490                 :        2413 :                 outgoing = var;
    7491                 :        2413 :                 incoming = omp_reduction_init_op (loc, rcode, type);
    7492                 :             :               }
    7493                 :             :             else
    7494                 :             :               {
    7495                 :             :                 /* Try to look at enclosing contexts for reduction var,
    7496                 :             :                    use original if no mapping found.  */
    7497                 :         255 :                 tree t = NULL_TREE;
    7498                 :         255 :                 omp_context *c = ctx->outer;
    7499                 :         362 :                 while (c && !t)
    7500                 :             :                   {
    7501                 :         107 :                     t = maybe_lookup_decl (orig, c);
    7502                 :         107 :                     c = c->outer;
    7503                 :             :                   }
    7504                 :         255 :                 incoming = outgoing = (t ? t : orig);
    7505                 :             :               }
    7506                 :             : 
    7507                 :        6380 :           has_outer_reduction:;
    7508                 :             :           }
    7509                 :             : 
    7510                 :        6380 :         if (!ref_to_res)
    7511                 :        3967 :           ref_to_res = integer_zero_node;
    7512                 :             : 
    7513                 :        6380 :         if (omp_privatize_by_reference (orig))
    7514                 :             :           {
    7515                 :         159 :             tree type = TREE_TYPE (var);
    7516                 :         159 :             const char *id = IDENTIFIER_POINTER (DECL_NAME (var));
    7517                 :             : 
    7518                 :         159 :             if (!inner)
    7519                 :             :               {
    7520                 :         110 :                 tree x = create_tmp_var (TREE_TYPE (type), id);
    7521                 :         110 :                 gimplify_assign (var, build_fold_addr_expr (x), fork_seq);
    7522                 :             :               }
    7523                 :             : 
    7524                 :         159 :             v1 = create_tmp_var (type, id);
    7525                 :         159 :             v2 = create_tmp_var (type, id);
    7526                 :         159 :             v3 = create_tmp_var (type, id);
    7527                 :             : 
    7528                 :         159 :             gimplify_assign (v1, var, fork_seq);
    7529                 :         159 :             gimplify_assign (v2, var, fork_seq);
    7530                 :         159 :             gimplify_assign (v3, var, fork_seq);
    7531                 :             : 
    7532                 :         159 :             var = build_simple_mem_ref (var);
    7533                 :         159 :             v1 = build_simple_mem_ref (v1);
    7534                 :         159 :             v2 = build_simple_mem_ref (v2);
    7535                 :         159 :             v3 = build_simple_mem_ref (v3);
    7536                 :         159 :             outgoing = build_simple_mem_ref (outgoing);
    7537                 :             : 
    7538                 :         159 :             if (!TREE_CONSTANT (incoming))
    7539                 :          80 :               incoming = build_simple_mem_ref (incoming);
    7540                 :             :           }
    7541                 :             :         else
    7542                 :             :           /* Note that 'var' might be a mem ref.  */
    7543                 :             :           v1 = v2 = v3 = var;
    7544                 :             : 
    7545                 :             :         /* Determine position in reduction buffer, which may be used
    7546                 :             :            by target.  The parser has ensured that this is not a
    7547                 :             :            variable-sized type.  */
    7548                 :        6380 :         fixed_size_mode mode
    7549                 :        6380 :           = as_a <fixed_size_mode> (TYPE_MODE (TREE_TYPE (var)));
    7550                 :        6380 :         unsigned align = GET_MODE_ALIGNMENT (mode) /  BITS_PER_UNIT;
    7551                 :        6380 :         offset = (offset + align - 1) & ~(align - 1);
    7552                 :        6380 :         tree off = build_int_cst (sizetype, offset);
    7553                 :        6380 :         offset += GET_MODE_SIZE (mode);
    7554                 :             : 
    7555                 :        6380 :         if (!init_code)
    7556                 :             :           {
    7557                 :       11504 :             init_code = build_int_cst (integer_type_node,
    7558                 :        5752 :                                        IFN_GOACC_REDUCTION_INIT);
    7559                 :       11504 :             fini_code = build_int_cst (integer_type_node,
    7560                 :        5752 :                                        IFN_GOACC_REDUCTION_FINI);
    7561                 :       11504 :             setup_code = build_int_cst (integer_type_node,
    7562                 :        5752 :                                         IFN_GOACC_REDUCTION_SETUP);
    7563                 :        5752 :             teardown_code = build_int_cst (integer_type_node,
    7564                 :        5752 :                                            IFN_GOACC_REDUCTION_TEARDOWN);
    7565                 :             :           }
    7566                 :             : 
    7567                 :        6380 :         tree setup_call
    7568                 :       12760 :           = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
    7569                 :        6380 :                                           TREE_TYPE (var), 6, setup_code,
    7570                 :             :                                           unshare_expr (ref_to_res),
    7571                 :             :                                           unshare_expr (incoming),
    7572                 :             :                                           level, op, off);
    7573                 :        6380 :         tree init_call
    7574                 :       12760 :           = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
    7575                 :        6380 :                                           TREE_TYPE (var), 6, init_code,
    7576                 :             :                                           unshare_expr (ref_to_res),
    7577                 :             :                                           unshare_expr (v1), level, op, off);
    7578                 :        6380 :         tree fini_call
    7579                 :       12760 :           = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
    7580                 :        6380 :                                           TREE_TYPE (var), 6, fini_code,
    7581                 :             :                                           unshare_expr (ref_to_res),
    7582                 :             :                                           unshare_expr (v2), level, op, off);
    7583                 :        6380 :         tree teardown_call
    7584                 :       12760 :           = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
    7585                 :        6380 :                                           TREE_TYPE (var), 6, teardown_code,
    7586                 :             :                                           ref_to_res, unshare_expr (v3),
    7587                 :             :                                           level, op, off);
    7588                 :             : 
    7589                 :        6380 :         gimplify_assign (unshare_expr (v1), setup_call, &before_fork);
    7590                 :        6380 :         gimplify_assign (unshare_expr (v2), init_call, &after_fork);
    7591                 :        6380 :         gimplify_assign (unshare_expr (v3), fini_call, &before_join);
    7592                 :        6380 :         gimplify_assign (unshare_expr (outgoing), teardown_call, &after_join);
    7593                 :             :       }
    7594                 :             : 
    7595                 :             :   /* Now stitch things together.  */
    7596                 :       24001 :   gimple_seq_add_seq (fork_seq, before_fork);
    7597                 :       24001 :   if (private_marker)
    7598                 :         248 :     gimple_seq_add_stmt (fork_seq, private_marker);
    7599                 :       24001 :   if (fork)
    7600                 :       14875 :     gimple_seq_add_stmt (fork_seq, fork);
    7601                 :       24001 :   gimple_seq_add_seq (fork_seq, after_fork);
    7602                 :             : 
    7603                 :       24001 :   gimple_seq_add_seq (join_seq, before_join);
    7604                 :       24001 :   if (join)
    7605                 :       14875 :     gimple_seq_add_stmt (join_seq, join);
    7606                 :       24001 :   gimple_seq_add_seq (join_seq, after_join);
    7607                 :       24001 : }
    7608                 :             : 
    7609                 :             : /* Generate code to implement the REDUCTION clauses, append it
    7610                 :             :    to STMT_SEQP.  CLIST if non-NULL is a pointer to a sequence
    7611                 :             :    that should be emitted also inside of the critical section,
    7612                 :             :    in that case clear *CLIST afterwards, otherwise leave it as is
    7613                 :             :    and let the caller emit it itself.  */
    7614                 :             : 
    7615                 :             : static void
    7616                 :       71819 : lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp,
    7617                 :             :                          gimple_seq *clist, omp_context *ctx)
    7618                 :             : {
    7619                 :       71819 :   gimple_seq sub_seq = NULL;
    7620                 :       71819 :   gimple *stmt;
    7621                 :       71819 :   tree x, c;
    7622                 :       71819 :   int count = 0;
    7623                 :             : 
    7624                 :             :   /* OpenACC loop reductions are handled elsewhere.  */
    7625                 :       71819 :   if (is_gimple_omp_oacc (ctx->stmt))
    7626                 :       70554 :     return;
    7627                 :             : 
    7628                 :             :   /* SIMD reductions are handled in lower_rec_input_clauses.  */
    7629                 :       61230 :   if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
    7630                 :       61230 :       && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
    7631                 :             :     return;
    7632                 :             : 
    7633                 :             :   /* inscan reductions are handled elsewhere.  */
    7634                 :       51385 :   if (ctx->scan_inclusive || ctx->scan_exclusive)
    7635                 :             :     return;
    7636                 :             : 
    7637                 :             :   /* First see if there is exactly one reduction clause.  Use OMP_ATOMIC
    7638                 :             :      update in that case, otherwise use a lock.  */
    7639                 :      243017 :   for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
    7640                 :      192894 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    7641                 :      192894 :         && !OMP_CLAUSE_REDUCTION_TASK (c))
    7642                 :             :       {
    7643                 :        4935 :         if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
    7644                 :        4935 :             || TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
    7645                 :             :           {
    7646                 :             :             /* Never use OMP_ATOMIC for array reductions or UDRs.  */
    7647                 :             :             count = -1;
    7648                 :             :             break;
    7649                 :             :           }
    7650                 :        3849 :         count++;
    7651                 :             :       }
    7652                 :             : 
    7653                 :       51209 :   if (count == 0)
    7654                 :             :     return;
    7655                 :             : 
    7656                 :       16352 :   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    7657                 :             :     {
    7658                 :       15087 :       tree var, ref, new_var, orig_var;
    7659                 :       15087 :       enum tree_code code;
    7660                 :       15087 :       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
    7661                 :             : 
    7662                 :       24421 :       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
    7663                 :       15087 :           || OMP_CLAUSE_REDUCTION_TASK (c))
    7664                 :        9334 :         continue;
    7665                 :             : 
    7666                 :        5753 :       enum omp_clause_code ccode = OMP_CLAUSE_REDUCTION;
    7667                 :        5753 :       orig_var = var = OMP_CLAUSE_DECL (c);
    7668                 :        5753 :       if (TREE_CODE (var) == MEM_REF)
    7669                 :             :         {
    7670                 :         930 :           var = TREE_OPERAND (var, 0);
    7671                 :         930 :           if (TREE_CODE (var) == POINTER_PLUS_EXPR)
    7672                 :          52 :             var = TREE_OPERAND (var, 0);
    7673                 :         930 :           if (TREE_CODE (var) == ADDR_EXPR)
    7674                 :         387 :             var = TREE_OPERAND (var, 0);
    7675                 :             :           else
    7676                 :             :             {
    7677                 :             :               /* If this is a pointer or referenced based array
    7678                 :             :                  section, the var could be private in the outer
    7679                 :             :                  context e.g. on orphaned loop construct.  Pretend this
    7680                 :             :                  is private variable's outer reference.  */
    7681                 :         543 :               ccode = OMP_CLAUSE_PRIVATE;
    7682                 :         543 :               if (INDIRECT_REF_P (var))
    7683                 :          90 :                 var = TREE_OPERAND (var, 0);
    7684                 :             :             }
    7685                 :         930 :           orig_var = var;
    7686                 :         930 :           if (is_variable_sized (var))
    7687                 :             :             {
    7688                 :          27 :               gcc_assert (DECL_HAS_VALUE_EXPR_P (var));
    7689                 :          27 :               var = DECL_VALUE_EXPR (var);
    7690                 :          27 :               gcc_assert (INDIRECT_REF_P (var));
    7691                 :          27 :               var = TREE_OPERAND (var, 0);
    7692                 :          27 :               gcc_assert (DECL_P (var));
    7693                 :             :             }
    7694                 :             :         }
    7695                 :        5753 :       new_var = lookup_decl (var, ctx);
    7696                 :        5753 :       if (var == OMP_CLAUSE_DECL (c)
    7697                 :        5753 :           && omp_privatize_by_reference (var))
    7698                 :         172 :         new_var = build_simple_mem_ref_loc (clause_loc, new_var);
    7699                 :        5753 :       ref = build_outer_var_ref (var, ctx, ccode);
    7700                 :        5753 :       code = OMP_CLAUSE_REDUCTION_CODE (c);
    7701                 :             : 
    7702                 :             :       /* reduction(-:var) sums up the partial results, so it acts
    7703                 :             :          identically to reduction(+:var).  */
    7704                 :        5753 :       if (code == MINUS_EXPR)
    7705                 :          49 :         code = PLUS_EXPR;
    7706                 :             : 
    7707                 :        5753 :       bool is_truth_op = (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR);
    7708                 :        5753 :       if (count == 1)
    7709                 :             :         {
    7710                 :        3430 :           tree addr = build_fold_addr_expr_loc (clause_loc, ref);
    7711                 :             : 
    7712                 :        3430 :           addr = save_expr (addr);
    7713                 :        3430 :           ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
    7714                 :        3430 :           tree new_var2 = new_var;
    7715                 :        3430 :           tree ref2 = ref;
    7716                 :        3430 :           if (is_truth_op)
    7717                 :             :             {
    7718                 :         784 :               tree zero = build_zero_cst (TREE_TYPE (new_var));
    7719                 :         784 :               new_var2 = fold_build2_loc (clause_loc, NE_EXPR,
    7720                 :             :                                           boolean_type_node, new_var, zero);
    7721                 :         784 :               ref2 = fold_build2_loc (clause_loc, NE_EXPR, boolean_type_node,
    7722                 :             :                                       ref, zero);
    7723                 :             :             }
    7724                 :        3430 :           x = fold_build2_loc (clause_loc, code, TREE_TYPE (new_var2), ref2,
    7725                 :             :                                new_var2);
    7726                 :        3430 :           if (is_truth_op)
    7727                 :         784 :             x = fold_convert (TREE_TYPE (new_var), x);
    7728                 :        3430 :           x = build2 (OMP_ATOMIC, void_type_node, addr, x);
    7729                 :        3430 :           OMP_ATOMIC_MEMORY_ORDER (x) = OMP_MEMORY_ORDER_RELAXED;
    7730                 :        3430 :           gimplify_and_add (x, stmt_seqp);
    7731                 :        3430 :           return;
    7732                 :             :         }
    7733                 :        2323 :       else if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
    7734                 :             :         {
    7735                 :         930 :           tree d = OMP_CLAUSE_DECL (c);
    7736                 :         930 :           tree type = TREE_TYPE (d);
    7737                 :         930 :           tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
    7738                 :         930 :           tree i = create_tmp_var (TREE_TYPE (v));
    7739                 :         930 :           tree ptype = build_pointer_type (TREE_TYPE (type));
    7740                 :         930 :           tree bias = TREE_OPERAND (d, 1);
    7741                 :         930 :           d = TREE_OPERAND (d, 0);
    7742                 :         930 :           if (TREE_CODE (d) == POINTER_PLUS_EXPR)
    7743                 :             :             {
    7744                 :          52 :               tree b = TREE_OPERAND (d, 1);
    7745                 :          52 :               b = maybe_lookup_decl (b, ctx);
    7746                 :          52 :               if (b == NULL)
    7747                 :             :                 {
    7748                 :           2 :                   b = TREE_OPERAND (d, 1);
    7749                 :           2 :                   b = maybe_lookup_decl_in_outer_ctx (b, ctx);
    7750                 :             :                 }
    7751                 :          52 :               if (integer_zerop (bias))
    7752                 :             :                 bias = b;
    7753                 :             :               else
    7754                 :             :                 {
    7755                 :           0 :                   bias = fold_convert_loc (clause_loc, TREE_TYPE (b), bias);
    7756                 :           0 :                   bias = fold_build2_loc (clause_loc, PLUS_EXPR,
    7757                 :           0 :                                           TREE_TYPE (b), b, bias);
    7758                 :             :                 }
    7759                 :          52 :               d = TREE_OPERAND (d, 0);
    7760                 :             :             }
    7761                 :             :           /* For ref build_outer_var_ref already performs this, so
    7762                 :             :              only new_var needs a dereference.  */
    7763                 :         930 :           if (INDIRECT_REF_P (d))
    7764                 :             :             {
    7765                 :          90 :               new_var = build_simple_mem_ref_loc (clause_loc, new_var);
    7766                 :          90 :               gcc_assert (omp_privatize_by_reference (var)
    7767                 :             :                           && var == orig_var);
    7768                 :             :             }
    7769                 :         840 :           else if (TREE_CODE (d) == ADDR_EXPR)
    7770                 :             :             {
    7771                 :         387 :               if (orig_var == var)
    7772                 :             :                 {
    7773                 :         360 :                   new_var = build_fold_addr_expr (new_var);
    7774                 :         360 :                   ref = build_fold_addr_expr (ref);
    7775                 :             :                 }
    7776                 :             :             }
    7777                 :             :           else
    7778                 :             :             {
    7779                 :         453 :               gcc_assert (orig_var == var);
    7780                 :         453 :               if (omp_privatize_by_reference (var))
    7781                 :         133 :                 ref = build_fold_addr_expr (ref);
    7782                 :             :             }
    7783                 :         930 :           if (DECL_P (v))
    7784                 :             :             {
    7785                 :          96 :               tree t = maybe_lookup_decl (v, ctx);
    7786                 :          96 :               if (t)
    7787                 :          91 :                 v = t;
    7788                 :             :               else
    7789                 :           5 :                 v = maybe_lookup_decl_in_outer_ctx (v, ctx);
    7790                 :          96 :               gimplify_expr (&v, stmt_seqp, NULL, is_gimple_val, fb_rvalue);
    7791                 :             :             }
    7792                 :         930 :           if (!integer_zerop (bias))
    7793                 :             :             {
    7794                 :         533 :               bias = fold_convert_loc (clause_loc, sizetype, bias);
    7795                 :        1066 :               new_var = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
    7796                 :         533 :                                          TREE_TYPE (new_var), new_var,
    7797                 :             :                                          unshare_expr (bias));
    7798                 :         533 :               ref = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
    7799                 :         533 :                                          TREE_TYPE (ref), ref, bias);
    7800                 :             :             }
    7801                 :         930 :           new_var = fold_convert_loc (clause_loc, ptype, new_var);
    7802                 :         930 :           ref = fold_convert_loc (clause_loc, ptype, ref);
    7803                 :         930 :           tree m = create_tmp_var (ptype);
    7804                 :         930 :           gimplify_assign (m, new_var, stmt_seqp);
    7805                 :         930 :           new_var = m;
    7806                 :         930 :           m = create_tmp_var (ptype);
    7807                 :         930 :           gimplify_assign (m, ref, stmt_seqp);
    7808                 :         930 :           ref = m;
    7809                 :         930 :           gimplify_assign (i, build_int_cst (TREE_TYPE (v), 0), stmt_seqp);
    7810                 :         930 :           tree body = create_artificial_label (UNKNOWN_LOCATION);
    7811                 :         930 :           tree end = create_artificial_label (UNKNOWN_LOCATION);
    7812                 :         930 :           gimple_seq_add_stmt (&sub_seq, gimple_build_label (body));
    7813                 :         930 :           tree priv = build_simple_mem_ref_loc (clause_loc, new_var);
    7814                 :         930 :           tree out = build_simple_mem_ref_loc (clause_loc, ref);
    7815                 :         930 :           if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    7816                 :             :             {
    7817                 :          72 :               tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
    7818                 :          72 :               tree decl_placeholder
    7819                 :          72 :                 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c);
    7820                 :          72 :               SET_DECL_VALUE_EXPR (placeholder, out);
    7821                 :          72 :               DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
    7822                 :          72 :               SET_DECL_VALUE_EXPR (decl_placeholder, priv);
    7823                 :          72 :               DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 1;
    7824                 :          72 :               lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
    7825                 :          72 :               gimple_seq_add_seq (&sub_seq,
    7826                 :          72 :                                   OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
    7827                 :          72 :               OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    7828                 :          72 :               OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
    7829                 :          72 :               OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) = NULL;
    7830                 :             :             }
    7831                 :             :           else
    7832                 :             :             {
    7833                 :         858 :               tree out2 = out;
    7834                 :         858 :               tree priv2 = priv;
    7835                 :         858 :               if (is_truth_op)
    7836                 :             :                 {
    7837                 :           0 :                   tree zero = build_zero_cst (TREE_TYPE (out));
    7838                 :           0 :                   out2 = fold_build2_loc (clause_loc, NE_EXPR,
    7839                 :             :                                           boolean_type_node, out, zero);
    7840                 :           0 :                   priv2 = fold_build2_loc (clause_loc, NE_EXPR,
    7841                 :             :                                            boolean_type_node, priv, zero);
    7842                 :             :                 }
    7843                 :         858 :               x = build2 (code, TREE_TYPE (out2), out2, priv2);
    7844                 :         858 :               if (is_truth_op)
    7845                 :           0 :                 x = fold_convert (TREE_TYPE (out), x);
    7846                 :         858 :               out = unshare_expr (out);
    7847                 :         858 :               gimplify_assign (out, x, &sub_seq);
    7848                 :             :             }
    7849                 :         930 :           gimple *g = gimple_build_assign (new_var, POINTER_PLUS_EXPR, new_var,
    7850                 :         930 :                                            TYPE_SIZE_UNIT (TREE_TYPE (type)));
    7851                 :         930 :           gimple_seq_add_stmt (&sub_seq, g);
    7852                 :         930 :           g = gimple_build_assign (ref, POINTER_PLUS_EXPR, ref,
    7853                 :         930 :                                    TYPE_SIZE_UNIT (TREE_TYPE (type)));
    7854                 :         930 :           gimple_seq_add_stmt (&sub_seq, g);
    7855                 :         930 :           g = gimple_build_assign (i, PLUS_EXPR, i,
    7856                 :         930 :                                    build_int_cst (TREE_TYPE (i), 1));
    7857                 :         930 :           gimple_seq_add_stmt (&sub_seq, g);
    7858                 :         930 :           g = gimple_build_cond (LE_EXPR, i, v, body, end);
    7859                 :         930 :           gimple_seq_add_stmt (&sub_seq, g);
    7860                 :         930 :           gimple_seq_add_stmt (&sub_seq, gimple_build_label (end));
    7861                 :             :         }
    7862                 :        1393 :       else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    7863                 :             :         {
    7864                 :         777 :           tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
    7865                 :             : 
    7866                 :         777 :           if (omp_privatize_by_reference (var)
    7867                 :         834 :               && !useless_type_conversion_p (TREE_TYPE (placeholder),
    7868                 :          57 :                                              TREE_TYPE (ref)))
    7869                 :          49 :             ref = build_fold_addr_expr_loc (clause_loc, ref);
    7870                 :         777 :           SET_DECL_VALUE_EXPR (placeholder, ref);
    7871                 :         777 :           DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
    7872                 :         777 :           lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
    7873                 :         777 :           gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
    7874                 :         777 :           OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    7875                 :         777 :           OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
    7876                 :             :         }
    7877                 :             :       else
    7878                 :             :         {
    7879                 :         616 :           tree new_var2 = new_var;
    7880                 :         616 :           tree ref2 = ref;
    7881                 :         616 :           if (is_truth_op)
    7882                 :             :             {
    7883                 :          78 :               tree zero = build_zero_cst (TREE_TYPE (new_var));
    7884                 :          78 :               new_var2 = fold_build2_loc (clause_loc, NE_EXPR,
    7885                 :             :                                           boolean_type_node, new_var, zero);
    7886                 :          78 :               ref2 = fold_build2_loc (clause_loc, NE_EXPR, boolean_type_node,
    7887                 :             :                                       ref, zero);
    7888                 :             :             }
    7889                 :         616 :           x = build2 (code, TREE_TYPE (ref), ref2, new_var2);
    7890                 :         616 :           if (is_truth_op)
    7891                 :          78 :             x = fold_convert (TREE_TYPE (new_var), x);
    7892                 :         616 :           ref = build_outer_var_ref (var, ctx);
    7893                 :         616 :           gimplify_assign (ref, x, &sub_seq);
    7894                 :             :         }
    7895                 :             :     }
    7896                 :             : 
    7897                 :        1265 :   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
    7898                 :             :                             0);
    7899                 :        1265 :   gimple_seq_add_stmt (stmt_seqp, stmt);
    7900                 :             : 
    7901                 :        1265 :   gimple_seq_add_seq (stmt_seqp, sub_seq);
    7902                 :             : 
    7903                 :        1265 :   if (clist)
    7904                 :             :     {
    7905                 :         181 :       gimple_seq_add_seq (stmt_seqp, *clist);
    7906                 :         181 :       *clist = NULL;
    7907                 :             :     }
    7908                 :             : 
    7909                 :        1265 :   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
    7910                 :             :                             0);
    7911                 :        1265 :   gimple_seq_add_stmt (stmt_seqp, stmt);
    7912                 :             : }
    7913                 :             : 
    7914                 :             : 
    7915                 :             : /* Generate code to implement the COPYPRIVATE clauses.  */
    7916                 :             : 
    7917                 :             : static void
    7918                 :         119 : lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
    7919                 :             :                             omp_context *ctx)
    7920                 :             : {
    7921                 :         119 :   tree c;
    7922                 :             : 
    7923                 :         471 :   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    7924                 :             :     {
    7925                 :         352 :       tree var, new_var, ref, x;
    7926                 :         352 :       bool by_ref;
    7927                 :         352 :       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
    7928                 :             : 
    7929                 :         352 :       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
    7930                 :           6 :         continue;
    7931                 :             : 
    7932                 :         346 :       var = OMP_CLAUSE_DECL (c);
    7933                 :         346 :       by_ref = use_pointer_for_field (var, NULL);
    7934                 :             : 
    7935                 :         346 :       ref = build_sender_ref (var, ctx);
    7936                 :         346 :       x = new_var = lookup_decl_in_outer_ctx (var, ctx);
    7937                 :         346 :       if (by_ref)
    7938                 :             :         {
    7939                 :          74 :           x = build_fold_addr_expr_loc (clause_loc, new_var);
    7940                 :          74 :           x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
    7941                 :             :         }
    7942                 :         346 :       gimplify_assign (ref, x, slist);
    7943                 :             : 
    7944                 :         346 :       ref = build_receiver_ref (var, false, ctx);
    7945                 :         346 :       if (by_ref)
    7946                 :             :         {
    7947                 :          74 :           ref = fold_convert_loc (clause_loc,
    7948                 :          74 :                                   build_pointer_type (TREE_TYPE (new_var)),
    7949                 :             :                                   ref);
    7950                 :          74 :           ref = build_fold_indirect_ref_loc (clause_loc, ref);
    7951                 :             :         }
    7952                 :         346 :       if (omp_privatize_by_reference (var))
    7953                 :             :         {
    7954                 :         173 :           ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
    7955                 :         173 :           ref = build_simple_mem_ref_loc (clause_loc, ref);
    7956                 :         173 :           new_var = build_simple_mem_ref_loc (clause_loc, new_var);
    7957                 :             :         }
    7958                 :         346 :       x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
    7959                 :         346 :       gimplify_and_add (x, rlist);
    7960                 :             :     }
    7961                 :         119 : }
    7962                 :             : 
    7963                 :             : 
    7964                 :             : /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
    7965                 :             :    and REDUCTION from the sender (aka parent) side.  */
    7966                 :             : 
    7967                 :             : static void
    7968                 :       22501 : lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
    7969                 :             :                     omp_context *ctx)
    7970                 :             : {
    7971                 :       22501 :   tree c, t;
    7972                 :       22501 :   int ignored_looptemp = 0;
    7973                 :       22501 :   bool is_taskloop = false;
    7974                 :             : 
    7975                 :             :   /* For taskloop, ignore first two _looptemp_ clauses, those are initialized
    7976                 :             :      by GOMP_taskloop.  */
    7977                 :       22501 :   if (is_task_ctx (ctx) && gimple_omp_task_taskloop_p (ctx->stmt))
    7978                 :             :     {
    7979                 :             :       ignored_looptemp = 2;
    7980                 :             :       is_taskloop = true;
    7981                 :             :     }
    7982                 :             : 
    7983                 :      116509 :   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    7984                 :             :     {
    7985                 :       94008 :       tree val, ref, x, var;
    7986                 :       94008 :       bool by_ref, do_in = false, do_out = false;
    7987                 :       94008 :       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
    7988                 :             : 
    7989                 :       94008 :       switch (OMP_CLAUSE_CODE (c))
    7990                 :             :         {
    7991                 :        4363 :         case OMP_CLAUSE_PRIVATE:
    7992                 :        4363 :           if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
    7993                 :             :             break;
    7994                 :        4208 :           continue;
    7995                 :             :         case OMP_CLAUSE_FIRSTPRIVATE:
    7996                 :             :         case OMP_CLAUSE_COPYIN:
    7997                 :             :         case OMP_CLAUSE_LASTPRIVATE:
    7998                 :             :         case OMP_CLAUSE_IN_REDUCTION:
    7999                 :             :         case OMP_CLAUSE__REDUCTEMP_:
    8000                 :             :           break;
    8001                 :        5080 :         case OMP_CLAUSE_REDUCTION:
    8002                 :        5080 :           if (is_task_ctx (ctx) || OMP_CLAUSE_REDUCTION_TASK (c))
    8003                 :         812 :             continue;
    8004                 :             :           break;
    8005                 :       17051 :         case OMP_CLAUSE_SHARED:
    8006                 :       17051 :           if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
    8007                 :             :             break;
    8008                 :       16708 :           continue;
    8009                 :       19089 :         case OMP_CLAUSE__LOOPTEMP_:
    8010                 :       19089 :           if (ignored_looptemp)
    8011                 :             :             {
    8012                 :        2788 :               ignored_looptemp--;
    8013                 :        2788 :               continue;
    8014                 :             :             }
    8015                 :             :           break;
    8016                 :       13101 :         default:
    8017                 :       13101 :           continue;
    8018                 :             :         }
    8019                 :             : 
    8020                 :       56391 :       val = OMP_CLAUSE_DECL (c);
    8021                 :       56391 :       if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
    8022                 :       52123 :            || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
    8023                 :       58056 :           && TREE_CODE (val) == MEM_REF)
    8024                 :             :         {
    8025                 :        1785 :           val = TREE_OPERAND (val, 0);
    8026                 :        1785 :           if (TREE_CODE (val) == POINTER_PLUS_EXPR)
    8027                 :         353 :             val = TREE_OPERAND (val, 0);
    8028                 :        1785 :           if (INDIRECT_REF_P (val)
    8029                 :        1625 :               || TREE_CODE (val) == ADDR_EXPR)
    8030                 :         909 :             val = TREE_OPERAND (val, 0);
    8031                 :        1785 :           if (is_variable_sized (val))
    8032                 :          58 :             continue;
    8033                 :             :         }
    8034                 :             : 
    8035                 :             :       /* For OMP_CLAUSE_SHARED_FIRSTPRIVATE, look beyond the
    8036                 :             :          outer taskloop region.  */
    8037                 :       56333 :       omp_context *ctx_for_o = ctx;
    8038                 :       56333 :       if (is_taskloop
    8039                 :        3471 :           && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
    8040                 :       56676 :           && OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
    8041                 :         343 :         ctx_for_o = ctx->outer;
    8042                 :             : 
    8043                 :       56333 :       var = lookup_decl_in_outer_ctx (val, ctx_for_o);
    8044                 :             : 
    8045                 :       56333 :       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
    8046                 :       55783 :           && is_global_var (var)
    8047                 :       58831 :           && (val == OMP_CLAUSE_DECL (c)
    8048                 :         277 :               || !is_task_ctx (ctx)
    8049                 :         241 :               || (TREE_CODE (TREE_TYPE (val)) != POINTER_TYPE
    8050                 :         205 :                   && (TREE_CODE (TREE_TYPE (val)) != REFERENCE_TYPE
    8051                 :          81 :                       || (TREE_CODE (TREE_TYPE (TREE_TYPE (val)))
    8052                 :             :                           != POINTER_TYPE)))))
    8053                 :        2444 :         continue;
    8054                 :             : 
    8055                 :       53889 :       t = omp_member_access_dummy_var (var);
    8056                 :       53889 :       if (t)
    8057                 :             :         {
    8058                 :         269 :           var = DECL_VALUE_EXPR (var);
    8059                 :         269 :           tree o = maybe_lookup_decl_in_outer_ctx (t, ctx_for_o);
    8060                 :         269 :           if (o != t)
    8061                 :          71 :             var = unshare_and_remap (var, t, o);
    8062                 :             :           else
    8063                 :         198 :             var = unshare_expr (var);
    8064                 :             :         }
    8065                 :             : 
    8066                 :       53889 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
    8067                 :             :         {
    8068                 :             :           /* Handle taskloop firstprivate/lastprivate, where the
    8069                 :             :              lastprivate on GIMPLE_OMP_TASK is represented as
    8070                 :             :              OMP_CLAUSE_SHARED_FIRSTPRIVATE.  */
    8071                 :          83 :           tree f = lookup_sfield ((splay_tree_key) &DECL_UID (val), ctx);
    8072                 :          83 :           x = omp_build_component_ref (ctx->sender_decl, f);
    8073                 :          83 :           if (use_pointer_for_field (val, ctx))
    8074                 :          63 :             var = build_fold_addr_expr (var);
    8075                 :          83 :           gimplify_assign (x, var, ilist);
    8076                 :          83 :           DECL_ABSTRACT_ORIGIN (f) = NULL;
    8077                 :          83 :           continue;
    8078                 :          83 :         }
    8079                 :             : 
    8080                 :       53860 :       if (((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
    8081                 :       50342 :             && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION)
    8082                 :        4608 :            || val == OMP_CLAUSE_DECL (c))
    8083                 :      106108 :           && is_variable_sized (val))
    8084                 :          54 :         continue;
    8085                 :       53752 :       by_ref = use_pointer_for_field (val, NULL);
    8086                 :             : 
    8087                 :       53752 :       switch (OMP_CLAUSE_CODE (c))
    8088                 :             :         {
    8089                 :       24970 :         case OMP_CLAUSE_FIRSTPRIVATE:
    8090                 :       24970 :           if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)
    8091                 :        6601 :               && !by_ref
    8092                 :       31515 :               && is_task_ctx (ctx))
    8093                 :        2085 :             suppress_warning (var);
    8094                 :             :           do_in = true;
    8095                 :             :           break;
    8096                 :             : 
    8097                 :             :         case OMP_CLAUSE_PRIVATE:
    8098                 :             :         case OMP_CLAUSE_COPYIN:
    8099                 :             :         case OMP_CLAUSE__LOOPTEMP_:
    8100                 :             :         case OMP_CLAUSE__REDUCTEMP_:
    8101                 :             :           do_in = true;
    8102                 :             :           break;
    8103                 :             : 
    8104                 :        6545 :         case OMP_CLAUSE_LASTPRIVATE:
    8105                 :        6545 :           if (by_ref || omp_privatize_by_reference (val))
    8106                 :             :             {
    8107                 :         389 :               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
    8108                 :         242 :                 continue;
    8109                 :             :               do_in = true;
    8110                 :             :             }
    8111                 :             :           else
    8112                 :             :             {
    8113                 :        6156 :               do_out = true;
    8114                 :        6156 :               if (lang_hooks.decls.omp_private_outer_ref (val))
    8115                 :             :                 do_in = true;
    8116                 :             :             }
    8117                 :             :           break;
    8118                 :             : 
    8119                 :        4608 :         case OMP_CLAUSE_REDUCTION:
    8120                 :        4608 :         case OMP_CLAUSE_IN_REDUCTION:
    8121                 :        4608 :           do_in = true;
    8122                 :        4608 :           if (val == OMP_CLAUSE_DECL (c))
    8123                 :             :             {
    8124                 :        3104 :               if (is_task_ctx (ctx))
    8125                 :         307 :                 by_ref = use_pointer_for_field (val, ctx);
    8126                 :             :               else
    8127                 :        2797 :                 do_out = !(by_ref || omp_privatize_by_reference (val));
    8128                 :             :             }
    8129                 :             :           else
    8130                 :        1504 :             by_ref = TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE;
    8131                 :             :           break;
    8132                 :             : 
    8133                 :           0 :         default:
    8134                 :           0 :           gcc_unreachable ();
    8135                 :             :         }
    8136                 :             : 
    8137                 :       53510 :       if (do_in)
    8138                 :             :         {
    8139                 :       47378 :           ref = build_sender_ref (val, ctx);
    8140                 :       47378 :           x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
    8141                 :       47378 :           gimplify_assign (ref, x, ilist);
    8142                 :       47378 :           if (is_task_ctx (ctx))
    8143                 :        5737 :             DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
    8144                 :             :         }
    8145                 :             : 
    8146                 :       53510 :       if (do_out)
    8147                 :             :         {
    8148                 :        8401 :           ref = build_sender_ref (val, ctx);
    8149                 :        8401 :           gimplify_assign (var, ref, olist);
    8150                 :             :         }
    8151                 :             :     }
    8152                 :       22501 : }
    8153                 :             : 
    8154                 :             : /* Generate code to implement SHARED from the sender (aka parent)
    8155                 :             :    side.  This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
    8156                 :             :    list things that got automatically shared.  */
    8157                 :             : 
    8158                 :             : static void
    8159                 :       22501 : lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
    8160                 :             : {
    8161                 :       22501 :   tree var, ovar, nvar, t, f, x, record_type;
    8162                 :             : 
    8163                 :       22501 :   if (ctx->record_type == NULL)
    8164                 :        4541 :     return;
    8165                 :             : 
    8166                 :       17960 :   record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
    8167                 :       84997 :   for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
    8168                 :             :     {
    8169                 :       67037 :       ovar = DECL_ABSTRACT_ORIGIN (f);
    8170                 :       67037 :       if (!ovar || TREE_CODE (ovar) == FIELD_DECL)
    8171                 :        5820 :         continue;
    8172                 :             : 
    8173                 :       61217 :       nvar = maybe_lookup_decl (ovar, ctx);
    8174                 :      111396 :       if (!nvar
    8175                 :       60768 :           || !DECL_HAS_VALUE_EXPR_P (nvar)
    8176                 :       72492 :           || (ctx->allocate_map
    8177                 :         332 :               && ctx->allocate_map->get (ovar)))
    8178                 :       50179 :         continue;
    8179                 :             : 
    8180                 :             :       /* If CTX is a nested parallel directive.  Find the immediately
    8181                 :             :          enclosing parallel or workshare construct that contains a
    8182                 :             :          mapping for OVAR.  */
    8183                 :       11038 :       var = lookup_decl_in_outer_ctx (ovar, ctx);
    8184                 :             : 
    8185                 :       11038 :       t = omp_member_access_dummy_var (var);
    8186                 :       11038 :       if (t)
    8187                 :             :         {
    8188                 :          49 :           var = DECL_VALUE_EXPR (var);
    8189                 :          49 :           tree o = maybe_lookup_decl_in_outer_ctx (t, ctx);
    8190                 :          49 :           if (o != t)
    8191                 :          18 :             var = unshare_and_remap (var, t, o);
    8192                 :             :           else
    8193                 :          31 :             var = unshare_expr (var);
    8194                 :             :         }
    8195                 :             : 
    8196                 :       11038 :       if (use_pointer_for_field (ovar, ctx))
    8197                 :             :         {
    8198                 :        6314 :           x = build_sender_ref (ovar, ctx);
    8199                 :        6314 :           if (TREE_CODE (TREE_TYPE (f)) == ARRAY_TYPE
    8200                 :        6314 :               && TREE_TYPE (f) == TREE_TYPE (ovar))
    8201                 :             :             {
    8202                 :         108 :               gcc_assert (is_parallel_ctx (ctx)
    8203                 :             :                           && DECL_ARTIFICIAL (ovar));
    8204                 :             :               /* _condtemp_ clause.  */
    8205                 :         108 :               var = build_constructor (TREE_TYPE (x), NULL);
    8206                 :             :             }
    8207                 :             :           else
    8208                 :        6206 :             var = build_fold_addr_expr (var);
    8209                 :        6314 :           gimplify_assign (x, var, ilist);
    8210                 :             :         }
    8211                 :             :       else
    8212                 :             :         {
    8213                 :        4724 :           x = build_sender_ref (ovar, ctx);
    8214                 :        4724 :           gimplify_assign (x, var, ilist);
    8215                 :             : 
    8216                 :        4724 :           if (!TREE_READONLY (var)
    8217                 :             :               /* We don't need to receive a new reference to a result
    8218                 :             :                  or parm decl.  In fact we may not store to it as we will
    8219                 :             :                  invalidate any pending RSO and generate wrong gimple
    8220                 :             :                  during inlining.  */
    8221                 :        4724 :               && !((TREE_CODE (var) == RESULT_DECL
    8222                 :        3076 :                     || TREE_CODE (var) == PARM_DECL)
    8223                 :         186 :                    && DECL_BY_REFERENCE (var)))
    8224                 :             :             {
    8225                 :        3005 :               x = build_sender_ref (ovar, ctx);
    8226                 :        3005 :               gimplify_assign (var, x, olist);
    8227                 :             :             }
    8228                 :             :         }
    8229                 :             :     }
    8230                 :             : }
    8231                 :             : 
    8232                 :             : /* Emit an OpenACC head marker call, encapulating the partitioning and
    8233                 :             :    other information that must be processed by the target compiler.
    8234                 :             :    Return the maximum number of dimensions the associated loop might
    8235                 :             :    be partitioned over.  */
    8236                 :             : 
    8237                 :             : static unsigned
    8238                 :        8725 : lower_oacc_head_mark (location_t loc, tree ddvar, tree clauses,
    8239                 :             :                       gimple_seq *seq, omp_context *ctx)
    8240                 :             : {
    8241                 :        8725 :   unsigned levels = 0;
    8242                 :        8725 :   unsigned tag = 0;
    8243                 :        8725 :   tree gang_static = NULL_TREE;
    8244                 :        8725 :   auto_vec<tree, 5> args;
    8245                 :             : 
    8246                 :       17450 :   args.quick_push (build_int_cst
    8247                 :        8725 :                    (integer_type_node, IFN_UNIQUE_OACC_HEAD_MARK));
    8248                 :        8725 :   args.quick_push (ddvar);
    8249                 :       28122 :   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    8250                 :             :     {
    8251                 :       19397 :       switch (OMP_CLAUSE_CODE (c))
    8252                 :             :         {
    8253                 :        1802 :         case OMP_CLAUSE_GANG:
    8254                 :        1802 :           tag |= OLF_DIM_GANG;
    8255                 :        1802 :           gang_static = OMP_CLAUSE_GANG_STATIC_EXPR (c);
    8256                 :             :           /* static:* is represented by -1, and we can ignore it, as
    8257                 :             :              scheduling is always static.  */
    8258                 :        1802 :           if (gang_static && integer_minus_onep (gang_static))
    8259                 :          58 :             gang_static = NULL_TREE;
    8260                 :        1802 :           levels++;
    8261                 :        1802 :           break;
    8262                 :             : 
    8263                 :        1297 :         case OMP_CLAUSE_WORKER:
    8264                 :        1297 :           tag |= OLF_DIM_WORKER;
    8265                 :        1297 :           levels++;
    8266                 :        1297 :           break;
    8267                 :             : 
    8268                 :        1508 :         case OMP_CLAUSE_VECTOR:
    8269                 :        1508 :           tag |= OLF_DIM_VECTOR;
    8270                 :        1508 :           levels++;
    8271                 :        1508 :           break;
    8272                 :             : 
    8273                 :         264 :         case OMP_CLAUSE_SEQ:
    8274                 :         264 :           tag |= OLF_SEQ;
    8275                 :         264 :           break;
    8276                 :             : 
    8277                 :         380 :         case OMP_CLAUSE_AUTO:
    8278                 :         380 :           tag |= OLF_AUTO;
    8279                 :         380 :           break;
    8280                 :             : 
    8281                 :         216 :         case OMP_CLAUSE_INDEPENDENT:
    8282                 :         216 :           tag |= OLF_INDEPENDENT;
    8283                 :         216 :           break;
    8284                 :             : 
    8285                 :         146 :         case OMP_CLAUSE_TILE:
    8286                 :         146 :           tag |= OLF_TILE;
    8287                 :         146 :           break;
    8288                 :             : 
    8289                 :        3433 :         case OMP_CLAUSE_REDUCTION:
    8290                 :        3433 :           tag |= OLF_REDUCTION;
    8291                 :        3433 :           break;
    8292                 :             : 
    8293                 :       10351 :         default:
    8294                 :       10351 :           continue;
    8295                 :             :         }
    8296                 :             :     }
    8297                 :             : 
    8298                 :        8725 :   if (gang_static)
    8299                 :             :     {
    8300                 :         131 :       if (DECL_P (gang_static))
    8301                 :          16 :         gang_static = build_outer_var_ref (gang_static, ctx);
    8302                 :         131 :       tag |= OLF_GANG_STATIC;
    8303                 :             :     }
    8304                 :             : 
    8305                 :        8725 :   omp_context *tgt = enclosing_target_ctx (ctx);
    8306                 :        8725 :   if (!tgt || is_oacc_parallel_or_serial (tgt))
    8307                 :             :     ;
    8308                 :          83 :   else if (is_oacc_kernels (tgt))
    8309                 :             :     /* Not using this loops handling inside OpenACC 'kernels' regions.  */
    8310                 :           0 :     gcc_unreachable ();
    8311                 :          83 :   else if (is_oacc_kernels_decomposed_part (tgt))
    8312                 :             :     ;
    8313                 :             :   else
    8314                 :           0 :     gcc_unreachable ();
    8315                 :             : 
    8316                 :             :   /* In a parallel region, loops are implicitly INDEPENDENT.  */
    8317                 :        8725 :   if (!tgt || is_oacc_parallel_or_serial (tgt))
    8318                 :        8642 :     tag |= OLF_INDEPENDENT;
    8319                 :             : 
    8320                 :             :   /* Loops inside OpenACC 'kernels' decomposed parts' regions are expected to
    8321                 :             :      have an explicit 'seq' or 'independent' clause, and no 'auto' clause.  */
    8322                 :        8725 :   if (tgt && is_oacc_kernels_decomposed_part (tgt))
    8323                 :             :     {
    8324                 :          83 :       gcc_assert (tag & (OLF_SEQ | OLF_INDEPENDENT));
    8325                 :          83 :       gcc_assert (!(tag & OLF_AUTO));
    8326                 :             :     }
    8327                 :             : 
    8328                 :        8725 :   if (tag & OLF_TILE)
    8329                 :             :     /* Tiling could use all 3 levels.  */ 
    8330                 :             :     levels = 3;
    8331                 :             :   else
    8332                 :             :     {
    8333                 :             :       /* A loop lacking SEQ, GANG, WORKER and/or VECTOR could be AUTO.
    8334                 :             :          Ensure at least one level, or 2 for possible auto
    8335                 :             :          partitioning */
    8336                 :        8579 :       bool maybe_auto = !(tag & (((GOMP_DIM_MASK (GOMP_DIM_MAX) - 1)
    8337                 :             :                                   << OLF_DIM_BASE) | OLF_SEQ));
    8338                 :             : 
    8339                 :        8579 :       if (levels < 1u + maybe_auto)
    8340                 :             :         levels = 1u + maybe_auto;
    8341                 :             :     }
    8342                 :             : 
    8343                 :        8725 :   args.quick_push (build_int_cst (integer_type_node, levels));
    8344                 :        8725 :   args.quick_push (build_int_cst (integer_type_node, tag));
    8345                 :        8725 :   if (gang_static)
    8346                 :         131 :     args.quick_push (gang_static);
    8347                 :             : 
    8348                 :        8725 :   gcall *call = gimple_build_call_internal_vec (IFN_UNIQUE, args);
    8349                 :        8725 :   gimple_set_location (call, loc);
    8350                 :        8725 :   gimple_set_lhs (call, ddvar);
    8351                 :        8725 :   gimple_seq_add_stmt (seq, call);
    8352                 :             : 
    8353                 :        8725 :   return levels;
    8354                 :        8725 : }
    8355                 :             : 
    8356                 :             : /* Emit an OpenACC lopp head or tail marker to SEQ.  LEVEL is the
    8357                 :             :    partitioning level of the enclosed region.  */ 
    8358                 :             : 
    8359                 :             : static void
    8360                 :       38475 : lower_oacc_loop_marker (location_t loc, tree ddvar, bool head,
    8361                 :             :                         tree tofollow, gimple_seq *seq)
    8362                 :             : {
    8363                 :       38475 :   int marker_kind = (head ? IFN_UNIQUE_OACC_HEAD_MARK
    8364                 :             :                      : IFN_UNIQUE_OACC_TAIL_MARK);
    8365                 :       38475 :   tree marker = build_int_cst (integer_type_node, marker_kind);
    8366                 :       38475 :   int nargs = 2 + (tofollow != NULL_TREE);
    8367                 :       38475 :   gcall *call = gimple_build_call_internal (IFN_UNIQUE, nargs,
    8368                 :             :                                             marker, ddvar, tofollow);
    8369                 :       38475 :   gimple_set_location (call, loc);
    8370                 :       38475 :   gimple_set_lhs (call, ddvar);
    8371                 :       38475 :   gimple_seq_add_stmt (seq, call);
    8372                 :       38475 : }
    8373                 :             : 
    8374                 :             : /* Generate the before and after OpenACC loop sequences.  CLAUSES are
    8375                 :             :    the loop clauses, from which we extract reductions.  Initialize
    8376                 :             :    HEAD and TAIL.  */
    8377                 :             : 
    8378                 :             : static void
    8379                 :        8725 : lower_oacc_head_tail (location_t loc, tree clauses, gcall *private_marker,
    8380                 :             :                       gimple_seq *head, gimple_seq *tail, omp_context *ctx)
    8381                 :             : {
    8382                 :        8725 :   bool inner = false;
    8383                 :        8725 :   tree ddvar = create_tmp_var (integer_type_node, ".data_dep");
    8384                 :        8725 :   gimple_seq_add_stmt (head, gimple_build_assign (ddvar, integer_zero_node));
    8385                 :             : 
    8386                 :        8725 :   unsigned count = lower_oacc_head_mark (loc, ddvar, clauses, head, ctx);
    8387                 :             : 
    8388                 :        8725 :   if (private_marker)
    8389                 :             :     {
    8390                 :         228 :       gimple_set_location (private_marker, loc);
    8391                 :         228 :       gimple_call_set_lhs (private_marker, ddvar);
    8392                 :         228 :       gimple_call_set_arg (private_marker, 1, ddvar);
    8393                 :             :     }
    8394                 :             : 
    8395                 :        8725 :   tree fork_kind = build_int_cst (unsigned_type_node, IFN_UNIQUE_OACC_FORK);
    8396                 :        8725 :   tree join_kind = build_int_cst (unsigned_type_node, IFN_UNIQUE_OACC_JOIN);
    8397                 :             : 
    8398                 :        8725 :   gcc_assert (count);
    8399                 :       23600 :   for (unsigned done = 1; count; count--, done++)
    8400                 :             :     {
    8401                 :       14875 :       gimple_seq fork_seq = NULL;
    8402                 :       14875 :       gimple_seq join_seq = NULL;
    8403                 :             : 
    8404                 :       14875 :       tree place = build_int_cst (integer_type_node, -1);
    8405                 :       14875 :       gcall *fork = gimple_build_call_internal (IFN_UNIQUE, 3,
    8406                 :             :                                                 fork_kind, ddvar, place);
    8407                 :       14875 :       gimple_set_location (fork, loc);
    8408                 :       14875 :       gimple_set_lhs (fork, ddvar);
    8409                 :             : 
    8410                 :       14875 :       gcall *join = gimple_build_call_internal (IFN_UNIQUE, 3,
    8411                 :             :                                                 join_kind, ddvar, place);
    8412                 :       14875 :       gimple_set_location (join, loc);
    8413                 :       14875 :       gimple_set_lhs (join, ddvar);
    8414                 :             : 
    8415                 :             :       /* Mark the beginning of this level sequence.  */
    8416                 :       14875 :       if (inner)
    8417                 :        6150 :         lower_oacc_loop_marker (loc, ddvar, true,
    8418                 :             :                                 build_int_cst (integer_type_node, count),
    8419                 :             :                                 &fork_seq);
    8420                 :       14875 :       lower_oacc_loop_marker (loc, ddvar, false,
    8421                 :             :                               build_int_cst (integer_type_node, done),
    8422                 :             :                               &join_seq);
    8423                 :             : 
    8424                 :       21025 :       lower_oacc_reductions (loc, clauses, place, inner,
    8425                 :             :                              fork, (count == 1) ? private_marker : NULL,
    8426                 :             :                              join, &fork_seq, &join_seq,  ctx);
    8427                 :             : 
    8428                 :             :       /* Append this level to head. */
    8429                 :       14875 :       gimple_seq_add_seq (head, fork_seq);
    8430                 :             :       /* Prepend it to tail.  */
    8431                 :       14875 :       gimple_seq_add_seq (&join_seq, *tail);
    8432                 :       14875 :       *tail = join_seq;
    8433                 :             : 
    8434                 :       14875 :       inner = true;
    8435                 :             :     }
    8436                 :             : 
    8437                 :             :   /* Mark the end of the sequence.  */
    8438                 :        8725 :   lower_oacc_loop_marker (loc, ddvar, true, NULL_TREE, head);
    8439                 :        8725 :   lower_oacc_loop_marker (loc, ddvar, false, NULL_TREE, tail);
    8440                 :        8725 : }
    8441                 :             : 
    8442                 :             : /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
    8443                 :             :    catch handler and return it.  This prevents programs from violating the
    8444                 :             :    structured block semantics with throws.  */
    8445                 :             : 
    8446                 :             : static gimple_seq
    8447                 :       93139 : maybe_catch_exception (gimple_seq body)
    8448                 :             : {
    8449                 :       93139 :   gimple *g;
    8450                 :       93139 :   tree decl;
    8451                 :             : 
    8452                 :       93139 :   if (!flag_exceptions)
    8453                 :             :     return body;
    8454                 :             : 
    8455                 :       44186 :   if (lang_hooks.eh_protect_cleanup_actions != NULL)
    8456                 :       44158 :     decl = lang_hooks.eh_protect_cleanup_actions ();
    8457                 :             :   else
    8458                 :          28 :     decl = builtin_decl_explicit (BUILT_IN_TRAP);
    8459                 :             : 
    8460                 :       44186 :   g = gimple_build_eh_must_not_throw (decl);
    8461                 :       44186 :   g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
    8462                 :             :                         GIMPLE_TRY_CATCH);
    8463                 :             : 
    8464                 :       44186 :  return gimple_seq_alloc_with_stmt (g);
    8465                 :             : }
    8466                 :             : 
    8467                 :             : 
    8468                 :             : /* Routines to lower OMP directives into OMP-GIMPLE.  */
    8469                 :             : 
    8470                 :             : /* If ctx is a worksharing context inside of a cancellable parallel
    8471                 :             :    region and it isn't nowait, add lhs to its GIMPLE_OMP_RETURN
    8472                 :             :    and conditional branch to parallel's cancel_label to handle
    8473                 :             :    cancellation in the implicit barrier.  */
    8474                 :             : 
    8475                 :             : static void
    8476                 :       48412 : maybe_add_implicit_barrier_cancel (omp_context *ctx, gimple *omp_return,
    8477                 :             :                                    gimple_seq *body)
    8478                 :             : {
    8479                 :       48412 :   gcc_assert (gimple_code (omp_return) == GIMPLE_OMP_RETURN);
    8480                 :       48412 :   if (gimple_omp_return_nowait_p (omp_return))
    8481                 :             :     return;
    8482                 :       19009 :   for (omp_context *outer = ctx->outer; outer; outer = outer->outer)
    8483                 :       15271 :     if (gimple_code (outer->stmt) == GIMPLE_OMP_PARALLEL
    8484                 :       15271 :         && outer->cancellable)
    8485                 :             :       {
    8486                 :          69 :         tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
    8487                 :          69 :         tree c_bool_type = TREE_TYPE (TREE_TYPE (fndecl));
    8488                 :          69 :         tree lhs = create_tmp_var (c_bool_type);
    8489                 :          69 :         gimple_omp_return_set_lhs (omp_return, lhs);
    8490                 :          69 :         tree fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
    8491                 :          69 :         gimple *g = gimple_build_cond (NE_EXPR, lhs,
    8492                 :             :                                        fold_convert (c_bool_type,
    8493                 :             :                                                      boolean_false_node),
    8494                 :             :                                        outer->cancel_label, fallthru_label);
    8495                 :          69 :         gimple_seq_add_stmt (body, g);
    8496                 :          69 :         gimple_seq_add_stmt (body, gimple_build_label (fallthru_label));
    8497                 :             :       }
    8498                 :       15202 :     else if (gimple_code (outer->stmt) != GIMPLE_OMP_TASKGROUP
    8499                 :       15202 :              && gimple_code (outer->stmt) != GIMPLE_OMP_SCOPE)
    8500                 :             :       return;
    8501                 :             : }
    8502                 :             : 
    8503                 :             : /* Find the first task_reduction or reduction clause or return NULL
    8504                 :             :    if there are none.  */
    8505                 :             : 
    8506                 :             : static inline tree
    8507                 :       48742 : omp_task_reductions_find_first (tree clauses, enum tree_code code,
    8508                 :             :                                 enum omp_clause_code ccode)
    8509                 :             : {
    8510                 :       63626 :   while (1)
    8511                 :             :     {
    8512                 :       56184 :       clauses = omp_find_clause (clauses, ccode);
    8513                 :       56184 :       if (clauses == NULL_TREE)
    8514                 :             :         return NULL_TREE;
    8515                 :        8999 :       if (ccode != OMP_CLAUSE_REDUCTION
    8516                 :        8999 :           || code == OMP_TASKLOOP
    8517                 :        8999 :           || OMP_CLAUSE_REDUCTION_TASK (clauses))
    8518                 :        1557 :         return clauses;
    8519                 :        7442 :       clauses = OMP_CLAUSE_CHAIN (clauses);
    8520                 :             :     }
    8521                 :             : }
    8522                 :             : 
    8523                 :             : static void lower_omp_task_reductions (omp_context *, enum tree_code, tree,
    8524                 :             :                                        gimple_seq *, gimple_seq *);
    8525                 :             : 
    8526                 :             : /* Lower the OpenMP sections directive in the current statement in GSI_P.
    8527                 :             :    CTX is the enclosing OMP context for the current statement.  */
    8528                 :             : 
    8529                 :             : static void
    8530                 :         433 : lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
    8531                 :             : {
    8532                 :         433 :   tree block, control;
    8533                 :         433 :   gimple_stmt_iterator tgsi;
    8534                 :         433 :   gomp_sections *stmt;
    8535                 :         433 :   gimple *t;
    8536                 :         433 :   gbind *new_stmt, *bind;
    8537                 :         433 :   gimple_seq ilist, dlist, olist, tred_dlist = NULL, clist = NULL, new_body;
    8538                 :             : 
    8539                 :         433 :   stmt = as_a <gomp_sections *> (gsi_stmt (*gsi_p));
    8540                 :             : 
    8541                 :         433 :   push_gimplify_context ();
    8542                 :             : 
    8543                 :         433 :   dlist = NULL;
    8544                 :         433 :   ilist = NULL;
    8545                 :             : 
    8546                 :         433 :   tree rclauses
    8547                 :         433 :     = omp_task_reductions_find_first (gimple_omp_sections_clauses (stmt),
    8548                 :             :                                       OMP_SECTIONS, OMP_CLAUSE_REDUCTION);
    8549                 :         433 :   tree rtmp = NULL_TREE;
    8550                 :         433 :   if (rclauses)
    8551                 :             :     {
    8552                 :           9 :       tree type = build_pointer_type (pointer_sized_int_node);
    8553                 :           9 :       tree temp = create_tmp_var (type);
    8554                 :           9 :       tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
    8555                 :           9 :       OMP_CLAUSE_DECL (c) = temp;
    8556                 :           9 :       OMP_CLAUSE_CHAIN (c) = gimple_omp_sections_clauses (stmt);
    8557                 :           9 :       gimple_omp_sections_set_clauses (stmt, c);
    8558                 :           9 :       lower_omp_task_reductions (ctx, OMP_SECTIONS,
    8559                 :             :                                  gimple_omp_sections_clauses (stmt),
    8560                 :             :                                  &ilist, &tred_dlist);
    8561                 :           9 :       rclauses = c;
    8562                 :           9 :       rtmp = make_ssa_name (type);
    8563                 :           9 :       gimple_seq_add_stmt (&ilist, gimple_build_assign (rtmp, temp));
    8564                 :             :     }
    8565                 :             : 
    8566                 :         433 :   tree *clauses_ptr = gimple_omp_sections_clauses_ptr (stmt);
    8567                 :         433 :   lower_lastprivate_conditional_clauses (clauses_ptr, ctx);
    8568                 :             : 
    8569                 :         433 :   lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
    8570                 :             :                            &ilist, &dlist, ctx, NULL);
    8571                 :             : 
    8572                 :         433 :   control = create_tmp_var (unsigned_type_node, ".section");
    8573                 :         433 :   gimple_omp_sections_set_control (stmt, control);
    8574                 :             : 
    8575                 :         433 :   new_body = gimple_omp_body (stmt);
    8576                 :         433 :   gimple_omp_set_body (stmt, NULL);
    8577                 :         433 :   tgsi = gsi_start (new_body);
    8578                 :        1388 :   for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
    8579                 :             :     {
    8580                 :         955 :       omp_context *sctx;
    8581                 :         955 :       gimple *sec_start;
    8582                 :             : 
    8583                 :         955 :       sec_start = gsi_stmt (tgsi);
    8584                 :         955 :       sctx = maybe_lookup_ctx (sec_start);
    8585                 :         955 :       gcc_assert (sctx);
    8586                 :             : 
    8587                 :         955 :       lower_omp (gimple_omp_body_ptr (sec_start), sctx);
    8588                 :         955 :       gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
    8589                 :             :                             GSI_CONTINUE_LINKING);
    8590                 :         955 :       gimple_omp_set_body (sec_start, NULL);
    8591                 :             : 
    8592                 :         955 :       if (gsi_one_before_end_p (tgsi))
    8593                 :             :         {
    8594                 :         433 :           gimple_seq l = NULL;
    8595                 :         433 :           lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
    8596                 :             :                                      &ilist, &l, &clist, ctx);
    8597                 :         433 :           gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
    8598                 :         433 :           gimple_omp_section_set_last (sec_start);
    8599                 :             :         }
    8600                 :             : 
    8601                 :         955 :       gsi_insert_after (&tgsi, gimple_build_omp_return (false),
    8602                 :             :                         GSI_CONTINUE_LINKING);
    8603                 :             :     }
    8604                 :             : 
    8605                 :         433 :   block = make_node (BLOCK);
    8606                 :         433 :   bind = gimple_build_bind (NULL, new_body, block);
    8607                 :             : 
    8608                 :         433 :   olist = NULL;
    8609                 :         433 :   lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist,
    8610                 :             :                            &clist, ctx);
    8611                 :         433 :   if (clist)
    8612                 :             :     {
    8613                 :          10 :       tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
    8614                 :          10 :       gcall *g = gimple_build_call (fndecl, 0);
    8615                 :          10 :       gimple_seq_add_stmt (&olist, g);
    8616                 :          10 :       gimple_seq_add_seq (&olist, clist);
    8617                 :          10 :       fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
    8618                 :          10 :       g = gimple_build_call (fndecl, 0);
    8619                 :          10 :       gimple_seq_add_stmt (&olist, g);
    8620                 :             :     }
    8621                 :             : 
    8622                 :         433 :   block = make_node (BLOCK);
    8623                 :         433 :   new_stmt = gimple_build_bind (NULL, NULL, block);
    8624                 :         433 :   gsi_replace (gsi_p, new_stmt, true);
    8625                 :             : 
    8626                 :         433 :   pop_gimplify_context (new_stmt);
    8627                 :         433 :   gimple_bind_append_vars (new_stmt, ctx->block_vars);
    8628                 :         433 :   BLOCK_VARS (block) = gimple_bind_vars (bind);
    8629                 :         433 :   if (BLOCK_VARS (block))
    8630                 :           0 :     TREE_USED (block) = 1;
    8631                 :             : 
    8632                 :         433 :   new_body = NULL;
    8633                 :         433 :   gimple_seq_add_seq (&new_body, ilist);
    8634                 :         433 :   gimple_seq_add_stmt (&new_body, stmt);
    8635                 :         433 :   gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
    8636                 :         433 :   gimple_seq_add_stmt (&new_body, bind);
    8637                 :             : 
    8638                 :         433 :   t = gimple_build_omp_continue (control, control);
    8639                 :         433 :   gimple_seq_add_stmt (&new_body, t);
    8640                 :             : 
    8641                 :         433 :   gimple_seq_add_seq (&new_body, olist);
    8642                 :         433 :   if (ctx->cancellable)
    8643                 :          21 :     gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
    8644                 :         433 :   gimple_seq_add_seq (&new_body, dlist);
    8645                 :             : 
    8646                 :         433 :   new_body = maybe_catch_exception (new_body);
    8647                 :             : 
    8648                 :         433 :   bool nowait = omp_find_clause (gimple_omp_sections_clauses (stmt),
    8649                 :         433 :                                  OMP_CLAUSE_NOWAIT) != NULL_TREE;
    8650                 :         433 :   t = gimple_build_omp_return (nowait);
    8651                 :         433 :   gimple_seq_add_stmt (&new_body, t);
    8652                 :         433 :   gimple_seq_add_seq (&new_body, tred_dlist);
    8653                 :         433 :   maybe_add_implicit_barrier_cancel (ctx, t, &new_body);
    8654                 :             : 
    8655                 :         433 :   if (rclauses)
    8656                 :           9 :     OMP_CLAUSE_DECL (rclauses) = rtmp;
    8657                 :             : 
    8658                 :         433 :   gimple_bind_set_body (new_stmt, new_body);
    8659                 :         433 : }
    8660                 :             : 
    8661                 :             : 
    8662                 :             : /* A subroutine of lower_omp_single.  Expand the simple form of
    8663                 :             :    a GIMPLE_OMP_SINGLE, without a copyprivate clause:
    8664                 :             : 
    8665                 :             :         if (GOMP_single_start ())
    8666                 :             :           BODY;
    8667                 :             :         [ GOMP_barrier (); ]    -> unless 'nowait' is present.
    8668                 :             : 
    8669                 :             :   FIXME.  It may be better to delay expanding the logic of this until
    8670                 :             :   pass_expand_omp.  The expanded logic may make the job more difficult
    8671                 :             :   to a synchronization analysis pass.  */
    8672                 :             : 
    8673                 :             : static void
    8674                 :        1037 : lower_omp_single_simple (gomp_single *single_stmt, gimple_seq *pre_p)
    8675                 :             : {
    8676                 :        1037 :   location_t loc = gimple_location (single_stmt);
    8677                 :        1037 :   tree tlabel = create_artificial_label (loc);
    8678                 :        1037 :   tree flabel = create_artificial_label (loc);
    8679                 :        1037 :   gimple *call, *cond;
    8680                 :        1037 :   tree lhs, decl;
    8681                 :             : 
    8682                 :        1037 :   decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
    8683                 :        1037 :   lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)));
    8684                 :        1037 :   call = gimple_build_call (decl, 0);
    8685                 :        1037 :   gimple_call_set_lhs (call, lhs);
    8686                 :        1037 :   gimple_seq_add_stmt (pre_p, call);
    8687                 :             : 
    8688                 :        1037 :   cond = gimple_build_cond (EQ_EXPR, lhs,
    8689                 :        1037 :                             fold_convert_loc (loc, TREE_TYPE (lhs),
    8690                 :             :                                               boolean_true_node),
    8691                 :             :                             tlabel, flabel);
    8692                 :        1037 :   gimple_seq_add_stmt (pre_p, cond);
    8693                 :        1037 :   gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
    8694                 :        1037 :   gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
    8695                 :        1037 :   gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
    8696                 :        1037 : }
    8697                 :             : 
    8698                 :             : 
    8699                 :             : /* A subroutine of lower_omp_single.  Expand the simple form of
    8700                 :             :    a GIMPLE_OMP_SINGLE, with a copyprivate clause:
    8701                 :             : 
    8702                 :             :         #pragma omp single copyprivate (a, b, c)
    8703                 :             : 
    8704                 :             :    Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
    8705                 :             : 
    8706                 :             :       {
    8707                 :             :         if ((copyout_p = GOMP_single_copy_start ()) == NULL)
    8708                 :             :           {
    8709                 :             :             BODY;
    8710                 :             :             copyout.a = a;
    8711                 :             :             copyout.b = b;
    8712                 :             :             copyout.c = c;
    8713                 :             :             GOMP_single_copy_end (&copyout);
    8714                 :             :           }
    8715                 :             :         else
    8716                 :             :           {
    8717                 :             :             a = copyout_p->a;
    8718                 :             :             b = copyout_p->b;
    8719                 :             :             c = copyout_p->c;
    8720                 :             :           }
    8721                 :             :         GOMP_barrier ();
    8722                 :             :       }
    8723                 :             : 
    8724                 :             :   FIXME.  It may be better to delay expanding the logic of this until
    8725                 :             :   pass_expand_omp.  The expanded logic may make the job more difficult
    8726                 :             :   to a synchronization analysis pass.  */
    8727                 :             : 
    8728                 :             : static void
    8729                 :         119 : lower_omp_single_copy (gomp_single *single_stmt, gimple_seq *pre_p,
    8730                 :             :                        omp_context *ctx)
    8731                 :             : {
    8732                 :         119 :   tree ptr_type, t, l0, l1, l2, bfn_decl;
    8733                 :         119 :   gimple_seq copyin_seq;
    8734                 :         119 :   location_t loc = gimple_location (single_stmt);
    8735                 :             : 
    8736                 :         119 :   ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
    8737                 :             : 
    8738                 :         119 :   ptr_type = build_pointer_type (ctx->record_type);
    8739                 :         119 :   ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
    8740                 :             : 
    8741                 :         119 :   l0 = create_artificial_label (loc);
    8742                 :         119 :   l1 = create_artificial_label (loc);
    8743                 :         119 :   l2 = create_artificial_label (loc);
    8744                 :             : 
    8745                 :         119 :   bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
    8746                 :         119 :   t = build_call_expr_loc (loc, bfn_decl, 0);
    8747                 :         119 :   t = fold_convert_loc (loc, ptr_type, t);
    8748                 :         119 :   gimplify_assign (ctx->receiver_decl, t, pre_p);
    8749                 :             : 
    8750                 :         119 :   t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
    8751                 :         119 :               build_int_cst (ptr_type, 0));
    8752                 :         119 :   t = build3 (COND_EXPR, void_type_node, t,
    8753                 :             :               build_and_jump (&l0), build_and_jump (&l1));
    8754                 :         119 :   gimplify_and_add (t, pre_p);
    8755                 :             : 
    8756                 :         119 :   gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
    8757                 :             : 
    8758                 :         119 :   gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
    8759                 :             : 
    8760                 :         119 :   copyin_seq = NULL;
    8761                 :         119 :   lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
    8762                 :             :                               &copyin_seq, ctx);
    8763                 :             : 
    8764                 :         119 :   t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
    8765                 :         119 :   bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
    8766                 :         119 :   t = build_call_expr_loc (loc, bfn_decl, 1, t);
    8767                 :         119 :   gimplify_and_add (t, pre_p);
    8768                 :             : 
    8769                 :         119 :   t = build_and_jump (&l2);
    8770                 :         119 :   gimplify_and_add (t, pre_p);
    8771                 :             : 
    8772                 :         119 :   gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
    8773                 :             : 
    8774                 :         119 :   gimple_seq_add_seq (pre_p, copyin_seq);
    8775                 :             : 
    8776                 :         119 :   gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
    8777                 :         119 : }
    8778                 :             : 
    8779                 :             : 
    8780                 :             : /* Expand code for an OpenMP single directive.  */
    8781                 :             : 
    8782                 :             : static void
    8783                 :        1156 : lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
    8784                 :             : {
    8785                 :        1156 :   tree block;
    8786                 :        1156 :   gomp_single *single_stmt = as_a <gomp_single *> (gsi_stmt (*gsi_p));
    8787                 :        1156 :   gbind *bind;
    8788                 :        1156 :   gimple_seq bind_body, bind_body_tail = NULL, dlist;
    8789                 :             : 
    8790                 :        1156 :   push_gimplify_context ();
    8791                 :             : 
    8792                 :        1156 :   block = make_node (BLOCK);
    8793                 :        1156 :   bind = gimple_build_bind (NULL, NULL, block);
    8794                 :        1156 :   gsi_replace (gsi_p, bind, true);
    8795                 :        1156 :   bind_body = NULL;
    8796                 :        1156 :   dlist = NULL;
    8797                 :        1156 :   lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
    8798                 :             :                            &bind_body, &dlist, ctx, NULL);
    8799                 :        1156 :   lower_omp (gimple_omp_body_ptr (single_stmt), ctx);
    8800                 :             : 
    8801                 :        1156 :   gimple_seq_add_stmt (&bind_body, single_stmt);
    8802                 :             : 
    8803                 :        1156 :   if (ctx->record_type)
    8804                 :         119 :     lower_omp_single_copy (single_stmt, &bind_body, ctx);
    8805                 :             :   else
    8806                 :        1037 :     lower_omp_single_simple (single_stmt, &bind_body);
    8807                 :             : 
    8808                 :        1156 :   gimple_omp_set_body (single_stmt, NULL);
    8809                 :             : 
    8810                 :        1156 :   gimple_seq_add_seq (&bind_body, dlist);
    8811                 :             : 
    8812                 :        1156 :   bind_body = maybe_catch_exception (bind_body);
    8813                 :             : 
    8814                 :        1156 :   bool nowait = omp_find_clause (gimple_omp_single_clauses (single_stmt),
    8815                 :        1156 :                                  OMP_CLAUSE_NOWAIT) != NULL_TREE;
    8816                 :        1156 :   gimple *g = gimple_build_omp_return (nowait);
    8817                 :        1156 :   gimple_seq_add_stmt (&bind_body_tail, g);
    8818                 :        1156 :   maybe_add_implicit_barrier_cancel (ctx, g, &bind_body_tail);
    8819                 :        1156 :   if (ctx->record_type)
    8820                 :             :     {
    8821                 :         119 :       gimple_stmt_iterator gsi = gsi_start (bind_body_tail);
    8822                 :         119 :       tree clobber = build_clobber (ctx->record_type);
    8823                 :         119 :       gsi_insert_after (&gsi, gimple_build_assign (ctx->sender_decl,
    8824                 :             :                                                    clobber), GSI_SAME_STMT);
    8825                 :             :     }
    8826                 :        1156 :   gimple_seq_add_seq (&bind_body, bind_body_tail);
    8827                 :        1156 :   gimple_bind_set_body (bind, bind_body);
    8828                 :             : 
    8829                 :        1156 :   pop_gimplify_context (bind);
    8830                 :             : 
    8831                 :        1156 :   gimple_bind_append_vars (bind, ctx->block_vars);
    8832                 :        1156 :   BLOCK_VARS (block) = ctx->block_vars;
    8833                 :        1156 :   if (BLOCK_VARS (block))
    8834                 :          26 :     TREE_USED (block) = 1;
    8835                 :        1156 : }
    8836                 :             : 
    8837                 :             : 
    8838                 :             : /* Lower code for an OMP scope directive.  */
    8839                 :             : 
    8840                 :             : static void
    8841                 :         148 : lower_omp_scope (gimple_stmt_iterator *gsi_p, omp_context *ctx)
    8842                 :             : {
    8843                 :         148 :   tree block;
    8844                 :         148 :   gimple *scope_stmt = gsi_stmt (*gsi_p);
    8845                 :         148 :   gbind *bind;
    8846                 :         148 :   gimple_seq bind_body, bind_body_tail = NULL, dlist;
    8847                 :         148 :   gimple_seq tred_dlist = NULL;
    8848                 :             : 
    8849                 :         148 :   push_gimplify_context ();
    8850                 :             : 
    8851                 :         148 :   block = make_node (BLOCK);
    8852                 :         148 :   bind = gimple_build_bind (NULL, NULL, block);
    8853                 :         148 :   gsi_replace (gsi_p, bind, true);
    8854                 :         148 :   bind_body = NULL;
    8855                 :         148 :   dlist = NULL;
    8856                 :             : 
    8857                 :         148 :   tree rclauses
    8858                 :         148 :     = omp_task_reductions_find_first (gimple_omp_scope_clauses (scope_stmt),
    8859                 :             :                                       OMP_SCOPE, OMP_CLAUSE_REDUCTION);
    8860                 :         148 :   if (rclauses)
    8861                 :             :     {
    8862                 :          52 :       tree type = build_pointer_type (pointer_sized_int_node);
    8863                 :          52 :       tree temp = create_tmp_var (type);
    8864                 :          52 :       tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
    8865                 :          52 :       OMP_CLAUSE_DECL (c) = temp;
    8866                 :          52 :       OMP_CLAUSE_CHAIN (c) = gimple_omp_scope_clauses (scope_stmt);
    8867                 :          52 :       gimple_omp_scope_set_clauses (scope_stmt, c);
    8868                 :          52 :       lower_omp_task_reductions (ctx, OMP_SCOPE,
    8869                 :             :                                  gimple_omp_scope_clauses (scope_stmt),
    8870                 :             :                                  &bind_body, &tred_dlist);
    8871                 :          52 :       rclauses = c;
    8872                 :          52 :       tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_SCOPE_START);
    8873                 :          52 :       gimple *stmt = gimple_build_call (fndecl, 1, temp);
    8874                 :          52 :       gimple_seq_add_stmt (&bind_body, stmt);
    8875                 :             :     }
    8876                 :             : 
    8877                 :         148 :   lower_rec_input_clauses (gimple_omp_scope_clauses (scope_stmt),
    8878                 :             :                            &bind_body, &dlist, ctx, NULL);
    8879                 :         148 :   lower_omp (gimple_omp_body_ptr (scope_stmt), ctx);
    8880                 :             : 
    8881                 :         148 :   gimple_seq_add_stmt (&bind_body, scope_stmt);
    8882                 :             : 
    8883                 :         148 :   gimple_seq_add_seq (&bind_body, gimple_omp_body (scope_stmt));
    8884                 :             : 
    8885                 :         148 :   gimple_omp_set_body (scope_stmt, NULL);
    8886                 :             : 
    8887                 :         148 :   gimple_seq clist = NULL;
    8888                 :         148 :   lower_reduction_clauses (gimple_omp_scope_clauses (scope_stmt),
    8889                 :             :                            &bind_body, &clist, ctx);
    8890                 :         148 :   if (clist)
    8891                 :             :     {
    8892                 :           0 :       tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
    8893                 :           0 :       gcall *g = gimple_build_call (fndecl, 0);
    8894                 :           0 :       gimple_seq_add_stmt (&bind_body, g);
    8895                 :           0 :       gimple_seq_add_seq (&bind_body, clist);
    8896                 :           0 :       fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
    8897                 :           0 :       g = gimple_build_call (fndecl, 0);
    8898                 :           0 :       gimple_seq_add_stmt (&bind_body, g);
    8899                 :             :     }
    8900                 :             : 
    8901                 :         148 :   gimple_seq_add_seq (&bind_body, dlist);
    8902                 :             : 
    8903                 :         148 :   bind_body = maybe_catch_exception (bind_body);
    8904                 :             : 
    8905                 :         148 :   bool nowait = omp_find_clause (gimple_omp_scope_clauses (scope_stmt),
    8906                 :         148 :                                  OMP_CLAUSE_NOWAIT) != NULL_TREE;
    8907                 :         148 :   gimple *g = gimple_build_omp_return (nowait);
    8908                 :         148 :   gimple_seq_add_stmt (&bind_body_tail, g);
    8909                 :         148 :   gimple_seq_add_seq (&bind_body_tail, tred_dlist);
    8910                 :         148 :   maybe_add_implicit_barrier_cancel (ctx, g, &bind_body_tail);
    8911                 :         148 :   if (ctx->record_type)
    8912                 :             :     {
    8913                 :           0 :       gimple_stmt_iterator gsi = gsi_start (bind_body_tail);
    8914                 :           0 :       tree clobber = build_clobber (ctx->record_type);
    8915                 :           0 :       gsi_insert_after (&gsi, gimple_build_assign (ctx->sender_decl,
    8916                 :             :                                                    clobber), GSI_SAME_STMT);
    8917                 :             :     }
    8918                 :         148 :   gimple_seq_add_seq (&bind_body, bind_body_tail);
    8919                 :             : 
    8920                 :         148 :   gimple_bind_set_body (bind, bind_body);
    8921                 :             : 
    8922                 :         148 :   pop_gimplify_context (bind);
    8923                 :             : 
    8924                 :         148 :   gimple_bind_append_vars (bind, ctx->block_vars);
    8925                 :         148 :   BLOCK_VARS (block) = ctx->block_vars;
    8926                 :         148 :   if (BLOCK_VARS (block))
    8927                 :         118 :     TREE_USED (block) = 1;
    8928                 :         148 : }
    8929                 :             : /* Expand code for an OpenMP master or masked directive.  */
    8930                 :             : 
    8931                 :             : static void
    8932                 :        1152 : lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
    8933                 :             : {
    8934                 :        1152 :   tree block, lab = NULL, x, bfn_decl;
    8935                 :        1152 :   gimple *stmt = gsi_stmt (*gsi_p);
    8936                 :        1152 :   gbind *bind;
    8937                 :        1152 :   location_t loc = gimple_location (stmt);
    8938                 :        1152 :   gimple_seq tseq;
    8939                 :        1152 :   tree filter = integer_zero_node;
    8940                 :             : 
    8941                 :        1152 :   push_gimplify_context ();
    8942                 :             : 
    8943                 :        1152 :   if (gimple_code (stmt) == GIMPLE_OMP_MASKED)
    8944                 :             :     {
    8945                 :         342 :       filter = omp_find_clause (gimple_omp_masked_clauses (stmt),
    8946                 :             :                                 OMP_CLAUSE_FILTER);
    8947                 :         342 :       if (filter)
    8948                 :         280 :         filter = fold_convert (integer_type_node,
    8949                 :             :                                OMP_CLAUSE_FILTER_EXPR (filter));
    8950                 :             :       else
    8951                 :          62 :         filter = integer_zero_node;
    8952                 :             :     }
    8953                 :        1152 :   block = make_node (BLOCK);
    8954                 :        1152 :   bind = gimple_build_bind (NULL, NULL, block);
    8955                 :        1152 :   gsi_replace (gsi_p, bind, true);
    8956                 :        1152 :   gimple_bind_add_stmt (bind, stmt);
    8957                 :             : 
    8958                 :        1152 :   bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
    8959                 :        1152 :   x = build_call_expr_loc (loc, bfn_decl, 0);
    8960                 :        1152 :   x = build2 (EQ_EXPR, boolean_type_node, x, filter);
    8961                 :        1152 :   x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
    8962                 :        1152 :   tseq = NULL;
    8963                 :        1152 :   gimplify_and_add (x, &tseq);
    8964                 :        1152 :   gimple_bind_add_seq (bind, tseq);
    8965                 :             : 
    8966                 :        1152 :   lower_omp (gimple_omp_body_ptr (stmt), ctx);
    8967                 :        1152 :   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
    8968                 :        1152 :   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
    8969                 :        1152 :   gimple_omp_set_body (stmt, NULL);
    8970                 :             : 
    8971                 :        1152 :   gimple_bind_add_stmt (bind, gimple_build_label (lab));
    8972                 :             : 
    8973                 :        1152 :   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
    8974                 :             : 
    8975                 :        1152 :   pop_gimplify_context (bind);
    8976                 :             : 
    8977                 :        1152 :   gimple_bind_append_vars (bind, ctx->block_vars);
    8978                 :        1152 :   BLOCK_VARS (block) = ctx->block_vars;
    8979                 :        1152 : }
    8980                 :             : 
    8981                 :             : /* Helper function for lower_omp_task_reductions.  For a specific PASS
    8982                 :             :    find out the current clause it should be processed, or return false
    8983                 :             :    if all have been processed already.  */
    8984                 :             : 
    8985                 :             : static inline bool
    8986                 :        8570 : omp_task_reduction_iterate (int pass, enum tree_code code,
    8987                 :             :                             enum omp_clause_code ccode, tree *c, tree *decl,
    8988                 :             :                             tree *type, tree *next)
    8989                 :             : {
    8990                 :       12128 :   for (; *c; *c = omp_find_clause (OMP_CLAUSE_CHAIN (*c), ccode))
    8991                 :             :     {
    8992                 :        7116 :       if (ccode == OMP_CLAUSE_REDUCTION
    8993                 :        7060 :           && code != OMP_TASKLOOP
    8994                 :        7060 :           && !OMP_CLAUSE_REDUCTION_TASK (*c))
    8995                 :          56 :         continue;
    8996                 :        7004 :       *decl = OMP_CLAUSE_DECL (*c);
    8997                 :        7004 :       *type = TREE_TYPE (*decl);
    8998                 :        7004 :       if (TREE_CODE (*decl) == MEM_REF)
    8999                 :             :         {
    9000                 :        1992 :           if (pass != 1)
    9001                 :         996 :             continue;
    9002                 :             :         }
    9003                 :             :       else
    9004                 :             :         {
    9005                 :        5012 :           if (omp_privatize_by_reference (*decl))
    9006                 :         208 :             *type = TREE_TYPE (*type);
    9007                 :        5012 :           if (pass != (!TREE_CONSTANT (TYPE_SIZE_UNIT (*type))))
    9008                 :        2506 :             continue;
    9009                 :             :         }
    9010                 :        3502 :       *next = omp_find_clause (OMP_CLAUSE_CHAIN (*c), ccode);
    9011                 :        3502 :       return true;
    9012                 :             :     }
    9013                 :        5068 :   *decl = NULL_TREE;
    9014                 :        5068 :   *type = NULL_TREE;
    9015                 :        5068 :   *next = NULL_TREE;
    9016                 :        5068 :   return false;
    9017                 :             : }
    9018                 :             : 
    9019                 :             : /* Lower task_reduction and reduction clauses (the latter unless CODE is
    9020                 :             :    OMP_TASKGROUP only with task modifier).  Register mapping of those in
    9021                 :             :    START sequence and reducing them and unregister them in the END sequence.  */
    9022                 :             : 
    9023                 :             : static void
    9024                 :        1486 : lower_omp_task_reductions (omp_context *ctx, enum tree_code code, tree clauses,
    9025                 :             :                            gimple_seq *start, gimple_seq *end)
    9026                 :             : {
    9027                 :        2972 :   enum omp_clause_code ccode
    9028                 :             :     = (code == OMP_TASKGROUP
    9029                 :        1486 :        ? OMP_CLAUSE_TASK_REDUCTION : OMP_CLAUSE_REDUCTION);
    9030                 :        1486 :   tree cancellable = NULL_TREE;
    9031                 :        1486 :   clauses = omp_task_reductions_find_first (clauses, code, ccode);
    9032                 :        1486 :   if (clauses == NULL_TREE)
    9033                 :         219 :     return;
    9034                 :        1267 :   if (code == OMP_FOR || code == OMP_SECTIONS || code == OMP_SCOPE)
    9035                 :             :     {
    9036                 :         329 :       for (omp_context *outer = ctx->outer; outer; outer = outer->outer)
    9037                 :         245 :         if (gimple_code (outer->stmt) == GIMPLE_OMP_PARALLEL
    9038                 :         245 :             && outer->cancellable)
    9039                 :             :           {
    9040                 :          17 :             cancellable = error_mark_node;
    9041                 :          17 :             break;
    9042                 :             :           }
    9043                 :         228 :         else if (gimple_code (outer->stmt) != GIMPLE_OMP_TASKGROUP
    9044                 :         228 :                  && gimple_code (outer->stmt) != GIMPLE_OMP_SCOPE)
    9045                 :             :           break;
    9046                 :             :     }
    9047                 :        1267 :   tree record_type = lang_hooks.types.make_type (RECORD_TYPE);
    9048                 :        1267 :   tree *last = &TYPE_FIELDS (record_type);
    9049                 :        1267 :   unsigned cnt = 0;
    9050                 :        1267 :   if (cancellable)
    9051                 :             :     {
    9052                 :          17 :       tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
    9053                 :             :                                ptr_type_node);
    9054                 :          17 :       tree ifield = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
    9055                 :             :                                 integer_type_node);
    9056                 :          17 :       *last = field;
    9057                 :          17 :       DECL_CHAIN (field) = ifield;
    9058                 :          17 :       last = &DECL_CHAIN (ifield);
    9059                 :          17 :       DECL_CONTEXT (field) = record_type;
    9060                 :          17 :       if (TYPE_ALIGN (record_type) < DECL_ALIGN (field))
    9061                 :           0 :         SET_TYPE_ALIGN (record_type, DECL_ALIGN (field));
    9062                 :          17 :       DECL_CONTEXT (ifield) = record_type;
    9063                 :          17 :       if (TYPE_ALIGN (record_type) < DECL_ALIGN (ifield))
    9064                 :           0 :         SET_TYPE_ALIGN (record_type, DECL_ALIGN (ifield));
    9065                 :             :     }
    9066                 :        3801 :   for (int pass = 0; pass < 2; pass++)
    9067                 :             :     {
    9068                 :        2534 :       tree decl, type, next;
    9069                 :        2534 :       for (tree c = clauses;
    9070                 :        4285 :            omp_task_reduction_iterate (pass, code, ccode,
    9071                 :        1751 :                                        &c, &decl, &type, &next); c = next)
    9072                 :             :         {
    9073                 :        1751 :           ++cnt;
    9074                 :        1751 :           tree new_type = type;
    9075                 :        1751 :           if (ctx->outer)
    9076                 :        1236 :             new_type = remap_type (type, &ctx->outer->cb);
    9077                 :        1751 :           tree field
    9078                 :        1751 :             = build_decl (OMP_CLAUSE_LOCATION (c), FIELD_DECL,
    9079                 :        1751 :                           DECL_P (decl) ? DECL_NAME (decl) : NULL_TREE,
    9080                 :             :                           new_type);
    9081                 :        1751 :           if (DECL_P (decl) && type == TREE_TYPE (decl))
    9082                 :             :             {
    9083                 :        1201 :               SET_DECL_ALIGN (field, DECL_ALIGN (decl));
    9084                 :        1201 :               DECL_USER_ALIGN (field) = DECL_USER_ALIGN (decl);
    9085                 :        1201 :               TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (decl);
    9086                 :             :             }
    9087                 :             :           else
    9088                 :         550 :             SET_DECL_ALIGN (field, TYPE_ALIGN (type));
    9089                 :        1751 :           DECL_CONTEXT (field) = record_type;
    9090                 :        1751 :           if (TYPE_ALIGN (record_type) < DECL_ALIGN (field))
    9091                 :        1286 :             SET_TYPE_ALIGN (record_type, DECL_ALIGN (field));
    9092                 :        1751 :           *last = field;
    9093                 :        1751 :           last = &DECL_CHAIN (field);
    9094                 :        1751 :           tree bfield
    9095                 :        1751 :             = build_decl (OMP_CLAUSE_LOCATION (c), FIELD_DECL, NULL_TREE,
    9096                 :             :                           boolean_type_node);
    9097                 :        1751 :           DECL_CONTEXT (bfield) = record_type;
    9098                 :        1751 :           if (TYPE_ALIGN (record_type) < DECL_ALIGN (bfield))
    9099                 :           0 :             SET_TYPE_ALIGN (record_type, DECL_ALIGN (bfield));
    9100                 :        1751 :           *last = bfield;
    9101                 :        1751 :           last = &DECL_CHAIN (bfield);
    9102                 :             :         }
    9103                 :             :     }
    9104                 :        1267 :   *last = NULL_TREE;
    9105                 :        1267 :   layout_type (record_type);
    9106                 :             : 
    9107                 :             :   /* Build up an array which registers with the runtime all the reductions
    9108                 :             :      and deregisters them at the end.  Format documented in libgomp/task.c.  */
    9109                 :        1267 :   tree atype = build_array_type_nelts (pointer_sized_int_node, 7 + cnt * 3);
    9110                 :        1267 :   tree avar = create_tmp_var_raw (atype);
    9111                 :        1267 :   gimple_add_tmp_var (avar);
    9112                 :        1267 :   TREE_ADDRESSABLE (avar) = 1;
    9113                 :        1267 :   tree r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_zero_node,
    9114                 :             :                    NULL_TREE, NULL_TREE);
    9115                 :        1267 :   tree t = build_int_cst (pointer_sized_int_node, cnt);
    9116                 :        1267 :   gimple_seq_add_stmt (start, gimple_build_assign (r, t));
    9117                 :        1267 :   gimple_seq seq = NULL;
    9118                 :        1267 :   tree sz = fold_convert (pointer_sized_int_node,
    9119                 :             :                           TYPE_SIZE_UNIT (record_type));
    9120                 :        1267 :   int cachesz = 64;
    9121                 :        1267 :   sz = fold_build2 (PLUS_EXPR, pointer_sized_int_node, sz,
    9122                 :             :                     build_int_cst (pointer_sized_int_node, cachesz - 1));
    9123                 :        1267 :   sz = fold_build2 (BIT_AND_EXPR, pointer_sized_int_node, sz,
    9124                 :             :                     build_int_cst (pointer_sized_int_node, ~(cachesz - 1)));
    9125                 :        1267 :   ctx->task_reductions.create (1 + cnt);
    9126                 :        1267 :   ctx->task_reduction_map = new hash_map<tree, unsigned>;
    9127                 :        2534 :   ctx->task_reductions.quick_push (TREE_CODE (sz) == INTEGER_CST
    9128                 :        1307 :                                    ? sz : NULL_TREE);
    9129                 :        1267 :   sz = force_gimple_operand (sz, &seq, true, NULL_TREE);
    9130                 :        1267 :   gimple_seq_add_seq (start, seq);
    9131                 :        1267 :   r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_one_node,
    9132                 :             :               NULL_TREE, NULL_TREE);
    9133                 :        1267 :   gimple_seq_add_stmt (start, gimple_build_assign (r, sz));
    9134                 :        1267 :   r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_int (2),
    9135                 :             :               NULL_TREE, NULL_TREE);
    9136                 :        1267 :   t = build_int_cst (pointer_sized_int_node,
    9137                 :        1267 :                      MAX (TYPE_ALIGN_UNIT (record_type), (unsigned) cachesz));
    9138                 :        1267 :   gimple_seq_add_stmt (start, gimple_build_assign (r, t));
    9139                 :        1267 :   r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_int (3),
    9140                 :             :               NULL_TREE, NULL_TREE);
    9141                 :        1267 :   t = build_int_cst (pointer_sized_int_node, -1);
    9142                 :        1267 :   gimple_seq_add_stmt (start, gimple_build_assign (r, t));
    9143                 :        1267 :   r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_int (4),
    9144                 :             :               NULL_TREE, NULL_TREE);
    9145                 :        1267 :   t = build_int_cst (pointer_sized_int_node, 0);
    9146                 :        1267 :   gimple_seq_add_stmt (start, gimple_build_assign (r, t));
    9147                 :             : 
    9148                 :             :   /* In end, build a loop that iterates from 0 to < omp_get_num_threads ()
    9149                 :             :      and for each task reduction checks a bool right after the private variable
    9150                 :             :      within that thread's chunk; if the bool is clear, it hasn't been
    9151                 :             :      initialized and thus isn't going to be reduced nor destructed, otherwise
    9152                 :             :      reduce and destruct it.  */
    9153                 :        1267 :   tree idx = create_tmp_var (size_type_node);
    9154                 :        1267 :   gimple_seq_add_stmt (end, gimple_build_assign (idx, size_zero_node));
    9155                 :        1267 :   tree num_thr_sz = create_tmp_var (size_type_node);
    9156                 :        1267 :   tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
    9157                 :        1267 :   tree lab2 = create_artificial_label (UNKNOWN_LOCATION);
    9158                 :        1267 :   tree lab3 = NULL_TREE, lab7 = NULL_TREE;
    9159                 :        1267 :   gimple *g;
    9160                 :        1267 :   if (code == OMP_FOR || code == OMP_SECTIONS || code == OMP_SCOPE)
    9161                 :             :     {
    9162                 :             :       /* For worksharing constructs or scope, only perform it in the master
    9163                 :             :          thread, with the exception of cancelled implicit barriers - then only
    9164                 :             :          handle the current thread.  */
    9165                 :         290 :       tree lab4 = create_artificial_label (UNKNOWN_LOCATION);
    9166                 :         290 :       t = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
    9167                 :         290 :       tree thr_num = create_tmp_var (integer_type_node);
    9168                 :         290 :       g = gimple_build_call (t, 0);
    9169                 :         290 :       gimple_call_set_lhs (g, thr_num);
    9170                 :         290 :       gimple_seq_add_stmt (end, g);
    9171                 :         290 :       if (cancellable)
    9172                 :             :         {
    9173                 :          17 :           tree c;
    9174                 :          17 :           tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
    9175                 :          17 :           tree lab6 = create_artificial_label (UNKNOWN_LOCATION);
    9176                 :          17 :           lab3 = create_artificial_label (UNKNOWN_LOCATION);
    9177                 :          17 :           if (code == OMP_FOR)
    9178                 :           5 :             c = gimple_omp_for_clauses (ctx->stmt);
    9179                 :          12 :           else if (code == OMP_SECTIONS)
    9180                 :           0 :             c = gimple_omp_sections_clauses (ctx->stmt);
    9181                 :             :           else /* if (code == OMP_SCOPE) */
    9182                 :          12 :             c = gimple_omp_scope_clauses (ctx->stmt);
    9183                 :          17 :           c = OMP_CLAUSE_DECL (omp_find_clause (c, OMP_CLAUSE__REDUCTEMP_));
    9184                 :          17 :           cancellable = c;
    9185                 :          17 :           g = gimple_build_cond (NE_EXPR, c, build_zero_cst (TREE_TYPE (c)),
    9186                 :             :                                  lab5, lab6);
    9187                 :          17 :           gimple_seq_add_stmt (end, g);
    9188                 :          17 :           gimple_seq_add_stmt (end, gimple_build_label (lab5));
    9189                 :          17 :           g = gimple_build_assign (idx, NOP_EXPR, thr_num);
    9190                 :          17 :           gimple_seq_add_stmt (end, g);
    9191                 :          17 :           g = gimple_build_assign (num_thr_sz, PLUS_EXPR, idx,
    9192                 :          17 :                                    build_one_cst (TREE_TYPE (idx)));
    9193                 :          17 :           gimple_seq_add_stmt (end, g);
    9194                 :          17 :           gimple_seq_add_stmt (end, gimple_build_goto (lab3));
    9195                 :          17 :           gimple_seq_add_stmt (end, gimple_build_label (lab6));
    9196                 :             :         }
    9197                 :         290 :       g = gimple_build_cond (NE_EXPR, thr_num, integer_zero_node, lab2, lab4);
    9198                 :         290 :       gimple_seq_add_stmt (end, g);
    9199                 :         290 :       gimple_seq_add_stmt (end, gimple_build_label (lab4));
    9200                 :             :     }
    9201                 :        1267 :   if (code != OMP_PARALLEL)
    9202                 :             :     {
    9203                 :        1202 :       t = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
    9204                 :        1202 :       tree num_thr = create_tmp_var (integer_type_node);
    9205                 :        1202 :       g = gimple_build_call (t, 0);
    9206                 :        1202 :       gimple_call_set_lhs (g, num_thr);
    9207                 :        1202 :       gimple_seq_add_stmt (end, g);
    9208                 :        1202 :       g = gimple_build_assign (num_thr_sz, NOP_EXPR, num_thr);
    9209                 :        1202 :       gimple_seq_add_stmt (end, g);
    9210                 :        1202 :       if (cancellable)
    9211                 :          17 :         gimple_seq_add_stmt (end, gimple_build_label (lab3));
    9212                 :             :     }
    9213                 :             :   else
    9214                 :             :     {
    9215                 :          65 :       tree c = omp_find_clause (gimple_omp_parallel_clauses (ctx->stmt),
    9216                 :             :                                 OMP_CLAUSE__REDUCTEMP_);
    9217                 :          65 :       t = fold_convert (pointer_sized_int_node, OMP_CLAUSE_DECL (c));
    9218                 :          65 :       t = fold_convert (size_type_node, t);
    9219                 :          65 :       gimplify_assign (num_thr_sz, t, end);
    9220                 :             :     }
    9221                 :        1267 :   t = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_int (2),
    9222                 :             :               NULL_TREE, NULL_TREE);
    9223                 :        1267 :   tree data = create_tmp_var (pointer_sized_int_node);
    9224                 :        1267 :   gimple_seq_add_stmt (end, gimple_build_assign (data, t));
    9225                 :        1267 :   if (code == OMP_TASKLOOP)
    9226                 :             :     {
    9227                 :         559 :       lab7 = create_artificial_label (UNKNOWN_LOCATION);
    9228                 :         559 :       g = gimple_build_cond (NE_EXPR, data,
    9229                 :             :                              build_zero_cst (pointer_sized_int_node),
    9230                 :             :                              lab1, lab7);
    9231                 :         559 :       gimple_seq_add_stmt (end, g);
    9232                 :             :     }
    9233                 :        1267 :   gimple_seq_add_stmt (end, gimple_build_label (lab1));
    9234                 :        1267 :   tree ptr;
    9235                 :        1267 :   if (TREE_CODE (TYPE_SIZE_UNIT (record_type)) == INTEGER_CST)
    9236                 :        1227 :     ptr = create_tmp_var (build_pointer_type (record_type));
    9237                 :             :   else
    9238                 :          40 :     ptr = create_tmp_var (ptr_type_node);
    9239                 :        1267 :   gimple_seq_add_stmt (end, gimple_build_assign (ptr, NOP_EXPR, data));
    9240                 :             : 
    9241                 :        1267 :   tree field = TYPE_FIELDS (record_type);
    9242                 :        1267 :   cnt = 0;
    9243                 :        1267 :   if (cancellable)
    9244                 :          17 :     field = DECL_CHAIN (DECL_CHAIN (field));
    9245                 :        3801 :   for (int pass = 0; pass < 2; pass++)
    9246                 :             :     {
    9247                 :        2534 :       tree decl, type, next;
    9248                 :        2534 :       for (tree c = clauses;
    9249                 :        4285 :            omp_task_reduction_iterate (pass, code, ccode,
    9250                 :        1751 :                                        &c, &decl, &type, &next); c = next)
    9251                 :             :         {
    9252                 :        1751 :           tree var = decl, ref;
    9253                 :        1751 :           if (TREE_CODE (decl) == MEM_REF)
    9254                 :             :             {
    9255                 :         498 :               var = TREE_OPERAND (var, 0);
    9256                 :         498 :               if (TREE_CODE (var) == POINTER_PLUS_EXPR)
    9257                 :         109 :                 var = TREE_OPERAND (var, 0);
    9258                 :         498 :               tree v = var;
    9259                 :         498 :               if (TREE_CODE (var) == ADDR_EXPR)
    9260                 :         268 :                 var = TREE_OPERAND (var, 0);
    9261                 :         230 :               else if (INDIRECT_REF_P (var))
    9262                 :          18 :                 var = TREE_OPERAND (var, 0);
    9263                 :         498 :               tree orig_var = var;
    9264                 :         498 :               if (is_variable_sized (var))
    9265                 :             :                 {
    9266                 :          31 :                   gcc_assert (DECL_HAS_VALUE_EXPR_P (var));
    9267                 :          31 :                   var = DECL_VALUE_EXPR (var);
    9268                 :          31 :                   gcc_assert (INDIRECT_REF_P (var));
    9269                 :          31 :                   var = TREE_OPERAND (var, 0);
    9270                 :          31 :                   gcc_assert (DECL_P (var));
    9271                 :             :                 }
    9272                 :         498 :               t = ref = maybe_lookup_decl_in_outer_ctx (var, ctx);
    9273                 :         498 :               if (orig_var != var)
    9274                 :          31 :                 gcc_assert (TREE_CODE (v) == ADDR_EXPR);
    9275                 :         467 :               else if (TREE_CODE (v) == ADDR_EXPR)
    9276                 :         237 :                 t = build_fold_addr_expr (t);
    9277                 :         230 :               else if (INDIRECT_REF_P (v))
    9278                 :          18 :                 t = build_fold_indirect_ref (t);
    9279                 :         498 :               if (TREE_CODE (TREE_OPERAND (decl, 0)) == POINTER_PLUS_EXPR)
    9280                 :             :                 {
    9281                 :         109 :                   tree b = TREE_OPERAND (TREE_OPERAND (decl, 0), 1);
    9282                 :         109 :                   b = maybe_lookup_decl_in_outer_ctx (b, ctx);
    9283                 :         109 :                   t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, b);
    9284                 :             :                 }
    9285                 :         498 :               if (!integer_zerop (TREE_OPERAND (decl, 1)))
    9286                 :         229 :                 t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t,
    9287                 :             :                                  fold_convert (size_type_node,
    9288                 :             :                                                TREE_OPERAND (decl, 1)));
    9289                 :             :             }
    9290                 :             :           else
    9291                 :             :             {
    9292                 :        1253 :               t = ref = maybe_lookup_decl_in_outer_ctx (var, ctx);
    9293                 :        1253 :               if (!omp_privatize_by_reference (decl))
    9294                 :        1201 :                 t = build_fold_addr_expr (t);
    9295                 :             :             }
    9296                 :        1751 :           t = fold_convert (pointer_sized_int_node, t);
    9297                 :        1751 :           seq = NULL;
    9298                 :        1751 :           t = force_gimple_operand (t, &seq, true, NULL_TREE);
    9299                 :        1751 :           gimple_seq_add_seq (start, seq);
    9300                 :        1751 :           r = build4 (ARRAY_REF, pointer_sized_int_node, avar,
    9301                 :        1751 :                       size_int (7 + cnt * 3), NULL_TREE, NULL_TREE);
    9302                 :        1751 :           gimple_seq_add_stmt (start, gimple_build_assign (r, t));
    9303                 :        1751 :           t = unshare_expr (byte_position (field));
    9304                 :        1751 :           t = fold_convert (pointer_sized_int_node, t);
    9305                 :        1751 :           ctx->task_reduction_map->put (c, cnt);
    9306                 :        3502 :           ctx->task_reductions.quick_push (TREE_CODE (t) == INTEGER_CST
    9307                 :        2123 :                                            ? t : NULL_TREE);
    9308                 :        1751 :           seq = NULL;
    9309                 :        1751 :           t = force_gimple_operand (t, &seq, true, NULL_TREE);
    9310                 :        1751 :           gimple_seq_add_seq (start, seq);
    9311                 :        1751 :           r = build4 (ARRAY_REF, pointer_sized_int_node, avar,
    9312                 :        1751 :                       size_int (7 + cnt * 3 + 1), NULL_TREE, NULL_TREE);
    9313                 :        1751 :           gimple_seq_add_stmt (start, gimple_build_assign (r, t));
    9314                 :             : 
    9315                 :        1751 :           tree bfield = DECL_CHAIN (field);
    9316                 :        1751 :           tree cond;
    9317                 :        1751 :           if (code == OMP_PARALLEL
    9318                 :        1751 :               || code == OMP_FOR
    9319                 :             :               || code == OMP_SECTIONS
    9320                 :             :               || code == OMP_SCOPE)
    9321                 :             :             /* In parallel, worksharing or scope all threads unconditionally
    9322                 :             :                initialize all their task reduction private variables.  */
    9323                 :         565 :             cond = boolean_true_node;
    9324                 :        1186 :           else if (TREE_TYPE (ptr) == ptr_type_node)
    9325                 :             :             {
    9326                 :         261 :               cond = build2 (POINTER_PLUS_EXPR, ptr_type_node, ptr,
    9327                 :             :                              unshare_expr (byte_position (bfield)));
    9328                 :         261 :               seq = NULL;
    9329                 :         261 :               cond = force_gimple_operand (cond, &seq, true, NULL_TREE);
    9330                 :         261 :               gimple_seq_add_seq (end, seq);
    9331                 :         261 :               tree pbool = build_pointer_type (TREE_TYPE (bfield));
    9332                 :         261 :               cond = build2 (MEM_REF, TREE_TYPE (bfield), cond,
    9333                 :         261 :                              build_int_cst (pbool, 0));
    9334                 :             :             }
    9335                 :             :           else
    9336                 :         925 :             cond = build3 (COMPONENT_REF, TREE_TYPE (bfield),
    9337                 :             :                            build_simple_mem_ref (ptr), bfield, NULL_TREE);
    9338                 :        1751 :           tree lab3 = create_artificial_label (UNKNOWN_LOCATION);
    9339                 :        1751 :           tree lab4 = create_artificial_label (UNKNOWN_LOCATION);
    9340                 :        1751 :           tree condv = create_tmp_var (boolean_type_node);
    9341                 :        1751 :           gimple_seq_add_stmt (end, gimple_build_assign (condv, cond));
    9342                 :        1751 :           g = gimple_build_cond (NE_EXPR, condv, boolean_false_node,
    9343                 :             :                                  lab3, lab4);
    9344                 :        1751 :           gimple_seq_add_stmt (end, g);
    9345                 :        1751 :           gimple_seq_add_stmt (end, gimple_build_label (lab3));
    9346                 :        1751 :           if (cancellable && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == NULL_TREE)
    9347                 :             :             {
    9348                 :             :               /* If this reduction doesn't need destruction and parallel
    9349                 :             :                  has been cancelled, there is nothing to do for this
    9350                 :             :                  reduction, so jump around the merge operation.  */
    9351                 :          22 :               tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
    9352                 :          22 :               g = gimple_build_cond (NE_EXPR, cancellable,
    9353                 :          22 :                                      build_zero_cst (TREE_TYPE (cancellable)),
    9354                 :             :                                      lab4, lab5);
    9355                 :          22 :               gimple_seq_add_stmt (end, g);
    9356                 :          22 :               gimple_seq_add_stmt (end, gimple_build_label (lab5));
    9357                 :             :             }
    9358                 :             : 
    9359                 :        1751 :           tree new_var;
    9360                 :        1751 :           if (TREE_TYPE (ptr) == ptr_type_node)
    9361                 :             :             {
    9362                 :         428 :               new_var = build2 (POINTER_PLUS_EXPR, ptr_type_node, ptr,
    9363                 :             :                                 unshare_expr (byte_position (field)));
    9364                 :         428 :               seq = NULL;
    9365                 :         428 :               new_var = force_gimple_operand (new_var, &seq, true, NULL_TREE);
    9366                 :         428 :               gimple_seq_add_seq (end, seq);
    9367                 :         428 :               tree pbool = build_pointer_type (TREE_TYPE (field));
    9368                 :         428 :               new_var = build2 (MEM_REF, TREE_TYPE (field), new_var,
    9369                 :         428 :                                 build_int_cst (pbool, 0));
    9370                 :             :             }
    9371                 :             :           else
    9372                 :        1323 :             new_var = build3 (COMPONENT_REF, TREE_TYPE (field),
    9373                 :             :                               build_simple_mem_ref (ptr), field, NULL_TREE);
    9374                 :             : 
    9375                 :        1751 :           enum tree_code rcode = OMP_CLAUSE_REDUCTION_CODE (c);
    9376                 :        1751 :           if (TREE_CODE (decl) != MEM_REF
    9377                 :        1751 :               && omp_privatize_by_reference (decl))
    9378                 :          52 :             ref = build_simple_mem_ref (ref);
    9379                 :             :           /* reduction(-:var) sums up the partial results, so it acts
    9380                 :             :              identically to reduction(+:var).  */
    9381                 :        1751 :           if (rcode == MINUS_EXPR)
    9382                 :           0 :             rcode = PLUS_EXPR;
    9383                 :        1751 :           if (TREE_CODE (decl) == MEM_REF)
    9384                 :             :             {
    9385                 :         498 :               tree type = TREE_TYPE (new_var);
    9386                 :         498 :               tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
    9387                 :         498 :               tree i = create_tmp_var (TREE_TYPE (v));
    9388                 :         498 :               tree ptype = build_pointer_type (TREE_TYPE (type));
    9389                 :         498 :               if (DECL_P (v))
    9390                 :             :                 {
    9391                 :         142 :                   v = maybe_lookup_decl_in_outer_ctx (v, ctx);
    9392                 :         142 :                   tree vv = create_tmp_var (TREE_TYPE (v));
    9393                 :         142 :                   gimplify_assign (vv, v, start);
    9394                 :         142 :                   v = vv;
    9395                 :             :                 }
    9396                 :         498 :               ref = build4 (ARRAY_REF, pointer_sized_int_node, avar,
    9397                 :         498 :                             size_int (7 + cnt * 3), NULL_TREE, NULL_TREE);
    9398                 :         498 :               new_var = build_fold_addr_expr (new_var);
    9399                 :         498 :               new_var = fold_convert (ptype, new_var);
    9400                 :         498 :               ref = fold_convert (ptype, ref);
    9401                 :         498 :               tree m = create_tmp_var (ptype);
    9402                 :         498 :               gimplify_assign (m, new_var, end);
    9403                 :         498 :               new_var = m;
    9404                 :         498 :               m = create_tmp_var (ptype);
    9405                 :         498 :               gimplify_assign (m, ref, end);
    9406                 :         498 :               ref = m;
    9407                 :         498 :               gimplify_assign (i, build_int_cst (TREE_TYPE (v), 0), end);
    9408                 :         498 :               tree body = create_artificial_label (UNKNOWN_LOCATION);
    9409                 :         498 :               tree endl = create_artificial_label (UNKNOWN_LOCATION);
    9410                 :         498 :               gimple_seq_add_stmt (end, gimple_build_label (body));
    9411                 :         498 :               tree priv = build_simple_mem_ref (new_var);
    9412                 :         498 :               tree out = build_simple_mem_ref (ref);
    9413                 :         498 :               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    9414                 :             :                 {
    9415                 :         162 :                   tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
    9416                 :         162 :                   tree decl_placeholder
    9417                 :         162 :                     = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c);
    9418                 :         162 :                   tree lab6 = NULL_TREE;
    9419                 :         162 :                   if (cancellable)
    9420                 :             :                     {
    9421                 :             :                       /* If this reduction needs destruction and parallel
    9422                 :             :                          has been cancelled, jump around the merge operation
    9423                 :             :                          to the destruction.  */
    9424                 :           5 :                       tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
    9425                 :           5 :                       lab6 = create_artificial_label (UNKNOWN_LOCATION);
    9426                 :           5 :                       tree zero = build_zero_cst (TREE_TYPE (cancellable));
    9427                 :           5 :                       g = gimple_build_cond (NE_EXPR, cancellable, zero,
    9428                 :             :                                              lab6, lab5);
    9429                 :           5 :                       gimple_seq_add_stmt (end, g);
    9430                 :           5 :                       gimple_seq_add_stmt (end, gimple_build_label (lab5));
    9431                 :             :                     }
    9432                 :         162 :                   SET_DECL_VALUE_EXPR (placeholder, out);
    9433                 :         162 :                   DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
    9434                 :         162 :                   SET_DECL_VALUE_EXPR (decl_placeholder, priv);
    9435                 :         162 :                   DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 1;
    9436                 :         162 :                   lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
    9437                 :         324 :                   gimple_seq_add_seq (end,
    9438                 :         162 :                                       OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
    9439                 :         162 :                   OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    9440                 :         162 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
    9441                 :             :                     {
    9442                 :          56 :                       OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
    9443                 :          56 :                       OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) = NULL;
    9444                 :             :                     }
    9445                 :         162 :                   if (cancellable)
    9446                 :           5 :                     gimple_seq_add_stmt (end, gimple_build_label (lab6));
    9447                 :         162 :                   tree x = lang_hooks.decls.omp_clause_dtor (c, priv);
    9448                 :         162 :                   if (x)
    9449                 :             :                     {
    9450                 :         138 :                       gimple_seq tseq = NULL;
    9451                 :         138 :                       gimplify_stmt (&x, &tseq);
    9452                 :         138 :                       gimple_seq_add_seq (end, tseq);
    9453                 :             :                     }
    9454                 :             :                 }
    9455                 :             :               else
    9456                 :             :                 {
    9457                 :         336 :                   tree x = build2 (rcode, TREE_TYPE (out), out, priv);
    9458                 :         336 :                   out = unshare_expr (out);
    9459                 :         336 :                   gimplify_assign (out, x, end);
    9460                 :             :                 }
    9461                 :         498 :               gimple *g
    9462                 :         498 :                 = gimple_build_assign (new_var, POINTER_PLUS_EXPR, new_var,
    9463                 :         498 :                                        TYPE_SIZE_UNIT (TREE_TYPE (type)));
    9464                 :         498 :               gimple_seq_add_stmt (end, g);
    9465                 :         498 :               g = gimple_build_assign (ref, POINTER_PLUS_EXPR, ref,
    9466                 :         498 :                                        TYPE_SIZE_UNIT (TREE_TYPE (type)));
    9467                 :         498 :               gimple_seq_add_stmt (end, g);
    9468                 :         498 :               g = gimple_build_assign (i, PLUS_EXPR, i,
    9469                 :         498 :                                        build_int_cst (TREE_TYPE (i), 1));
    9470                 :         498 :               gimple_seq_add_stmt (end, g);
    9471                 :         498 :               g = gimple_build_cond (LE_EXPR, i, v, body, endl);
    9472                 :         498 :               gimple_seq_add_stmt (end, g);
    9473                 :         498 :               gimple_seq_add_stmt (end, gimple_build_label (endl));
    9474                 :             :             }
    9475                 :        1253 :           else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
    9476                 :             :             {
    9477                 :         127 :               tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
    9478                 :         127 :               tree oldv = NULL_TREE;
    9479                 :         127 :               tree lab6 = NULL_TREE;
    9480                 :         127 :               if (cancellable)
    9481                 :             :                 {
    9482                 :             :                   /* If this reduction needs destruction and parallel
    9483                 :             :                      has been cancelled, jump around the merge operation
    9484                 :             :                      to the destruction.  */
    9485                 :           5 :                   tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
    9486                 :           5 :                   lab6 = create_artificial_label (UNKNOWN_LOCATION);
    9487                 :           5 :                   tree zero = build_zero_cst (TREE_TYPE (cancellable));
    9488                 :           5 :                   g = gimple_build_cond (NE_EXPR, cancellable, zero,
    9489                 :             :                                          lab6, lab5);
    9490                 :           5 :                   gimple_seq_add_stmt (end, g);
    9491                 :           5 :                   gimple_seq_add_stmt (end, gimple_build_label (lab5));
    9492                 :             :                 }
    9493                 :         127 :               if (omp_privatize_by_reference (decl)
    9494                 :         145 :                   && !useless_type_conversion_p (TREE_TYPE (placeholder),
    9495                 :          18 :                                                  TREE_TYPE (ref)))
    9496                 :           0 :                 ref = build_fold_addr_expr_loc (OMP_CLAUSE_LOCATION (c), ref);
    9497                 :         127 :               ref = build_fold_addr_expr_loc (OMP_CLAUSE_LOCATION (c), ref);
    9498                 :         127 :               tree refv = create_tmp_var (TREE_TYPE (ref));
    9499                 :         127 :               gimplify_assign (refv, ref, end);
    9500                 :         127 :               ref = build_simple_mem_ref_loc (OMP_CLAUSE_LOCATION (c), refv);
    9501                 :         127 :               SET_DECL_VALUE_EXPR (placeholder, ref);
    9502                 :         127 :               DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
    9503                 :         127 :               tree d = maybe_lookup_decl (decl, ctx);
    9504                 :         127 :               gcc_assert (d);
    9505                 :         127 :               if (DECL_HAS_VALUE_EXPR_P (d))
    9506                 :           7 :                 oldv = DECL_VALUE_EXPR (d);
    9507                 :         127 :               if (omp_privatize_by_reference (var))
    9508                 :             :                 {
    9509                 :          18 :                   tree v = fold_convert (TREE_TYPE (d),
    9510                 :             :                                          build_fold_addr_expr (new_var));
    9511                 :          18 :                   SET_DECL_VALUE_EXPR (d, v);
    9512                 :             :                 }
    9513                 :             :               else
    9514                 :         109 :                 SET_DECL_VALUE_EXPR (d, new_var);
    9515                 :         127 :               DECL_HAS_VALUE_EXPR_P (d) = 1;
    9516                 :         127 :               lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
    9517                 :         127 :               if (oldv)
    9518                 :           7 :                 SET_DECL_VALUE_EXPR (d, oldv);
    9519                 :             :               else
    9520                 :             :                 {
    9521                 :         120 :                   SET_DECL_VALUE_EXPR (d, NULL_TREE);
    9522                 :         120 :                   DECL_HAS_VALUE_EXPR_P (d) = 0;
    9523                 :             :                 }
    9524                 :         127 :               gimple_seq_add_seq (end, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
    9525                 :         127 :               OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
    9526                 :         127 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
    9527                 :          24 :                 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
    9528                 :         127 :               if (cancellable)
    9529                 :           5 :                 gimple_seq_add_stmt (end, gimple_build_label (lab6));
    9530                 :         127 :               tree x = lang_hooks.decls.omp_clause_dtor (c, new_var);
    9531                 :         127 :               if (x)
    9532                 :             :                 {
    9533                 :          29 :                   gimple_seq tseq = NULL;
    9534                 :          29 :                   gimplify_stmt (&x, &tseq);
    9535                 :          29 :                   gimple_seq_add_seq (end, tseq);
    9536                 :             :                 }
    9537                 :             :             }
    9538                 :             :           else
    9539                 :             :             {
    9540                 :        1126 :               tree x = build2 (rcode, TREE_TYPE (ref), ref, new_var);
    9541                 :        1126 :               ref = unshare_expr (ref);
    9542                 :        1126 :               gimplify_assign (ref, x, end);
    9543                 :             :             }
    9544                 :        1751 :           gimple_seq_add_stmt (end, gimple_build_label (lab4));
    9545                 :        1751 :           ++cnt;
    9546                 :        1751 :           field = DECL_CHAIN (bfield);
    9547                 :             :         }
    9548                 :             :     }
    9549                 :             : 
    9550                 :        1267 :   if (code == OMP_TASKGROUP)
    9551                 :             :     {
    9552                 :         353 :       t = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_REDUCTION_REGISTER);
    9553                 :         353 :       g = gimple_build_call (t, 1, build_fold_addr_expr (avar));
    9554                 :         353 :       gimple_seq_add_stmt (start, g);
    9555                 :             :     }
    9556                 :             :   else
    9557                 :             :     {
    9558                 :         914 :       tree c;
    9559                 :         914 :       if (code == OMP_FOR)
    9560                 :         229 :         c = gimple_omp_for_clauses (ctx->stmt);
    9561                 :         685 :       else if (code == OMP_SECTIONS)
    9562                 :           9 :         c = gimple_omp_sections_clauses (ctx->stmt);
    9563                 :         676 :       else if (code == OMP_SCOPE)
    9564                 :          52 :         c = gimple_omp_scope_clauses (ctx->stmt);
    9565                 :             :       else
    9566                 :         624 :         c = gimple_omp_taskreg_clauses (ctx->stmt);
    9567                 :         914 :       c = omp_find_clause (c, OMP_CLAUSE__REDUCTEMP_);
    9568                 :         914 :       t = fold_convert (TREE_TYPE (OMP_CLAUSE_DECL (c)),
    9569                 :             :                         build_fold_addr_expr (avar));
    9570                 :         914 :       gimplify_assign (OMP_CLAUSE_DECL (c), t, start);
    9571                 :             :     }
    9572                 :             : 
    9573                 :        1267 :   gimple_seq_add_stmt (end, gimple_build_assign (data, PLUS_EXPR, data, sz));
    9574                 :        1267 :   gimple_seq_add_stmt (end, gimple_build_assign (idx, PLUS_EXPR, idx,
    9575                 :             :                                                  size_one_node));
    9576                 :        1267 :   g = gimple_build_cond (NE_EXPR, idx, num_thr_sz, lab1, lab2);
    9577                 :        1267 :   gimple_seq_add_stmt (end, g);
    9578                 :        1267 :   gimple_seq_add_stmt (end, gimple_build_label (lab2));
    9579                 :        1267 :   if (code == OMP_FOR || code == OMP_SECTIONS || code == OMP_SCOPE)
    9580                 :             :     {
    9581                 :         290 :       enum built_in_function bfn
    9582                 :             :         = BUILT_IN_GOMP_WORKSHARE_TASK_REDUCTION_UNREGISTER;
    9583                 :         290 :       t = builtin_decl_explicit (bfn);
    9584                 :         290 :       tree c_bool_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (t)));
    9585                 :         290 :       tree arg;
    9586                 :         290 :       if (cancellable)
    9587                 :             :         {
    9588                 :          17 :           arg = create_tmp_var (c_bool_type);
    9589                 :          17 :           gimple_seq_add_stmt (end, gimple_build_assign (arg, NOP_EXPR,
    9590                 :             :                                                          cancellable));
    9591                 :             :         }
    9592                 :             :       else
    9593                 :         273 :         arg = build_int_cst (c_bool_type, 0);
    9594                 :         290 :       g = gimple_build_call (t, 1, arg);
    9595                 :         290 :     }
    9596                 :             :   else
    9597                 :             :     {
    9598                 :         977 :       t = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_REDUCTION_UNREGISTER);
    9599                 :         977 :       g = gimple_build_call (t, 1, build_fold_addr_expr (avar));
    9600                 :             :     }
    9601                 :        1267 :   gimple_seq_add_stmt (end, g);
    9602                 :        1267 :   if (lab7)
    9603                 :         559 :     gimple_seq_add_stmt (end, gimple_build_label (lab7));
    9604                 :        1267 :   t = build_constructor (atype, NULL);
    9605                 :        1267 :   TREE_THIS_VOLATILE (t) = 1;
    9606                 :        1267 :   gimple_seq_add_stmt (end, gimple_build_assign (avar, t));
    9607                 :             : }
    9608                 :             : 
    9609                 :             : /* Expand code for an OpenMP taskgroup directive.  */
    9610                 :             : 
    9611                 :             : static void
    9612                 :         572 : lower_omp_taskgroup (gimple_stmt_iterator *gsi_p, omp_context *ctx)
    9613                 :             : {
    9614                 :         572 :   gimple *stmt = gsi_stmt (*gsi_p);
    9615                 :         572 :   gcall *x;
    9616                 :         572 :   gbind *bind;
    9617                 :         572 :   gimple_seq dseq = NULL;
    9618                 :         572 :   tree block = make_node (BLOCK);
    9619                 :             : 
    9620                 :         572 :   bind = gimple_build_bind (NULL, NULL, block);
    9621                 :         572 :   gsi_replace (gsi_p, bind, true);
    9622                 :         572 :   gimple_bind_add_stmt (bind, stmt);
    9623                 :             : 
    9624                 :         572 :   push_gimplify_context ();
    9625                 :             : 
    9626                 :         572 :   x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_START),
    9627                 :             :                          0);
    9628                 :         572 :   gimple_bind_add_stmt (bind, x);
    9629                 :             : 
    9630                 :         572 :   lower_omp_task_reductions (ctx, OMP_TASKGROUP,
    9631                 :             :                              gimple_omp_taskgroup_clauses (stmt),
    9632                 :             :                              gimple_bind_body_ptr (bind), &dseq);
    9633                 :             : 
    9634                 :         572 :   lower_omp (gimple_omp_body_ptr (stmt), ctx);
    9635                 :         572 :   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
    9636                 :         572 :   gimple_omp_set_body (stmt, NULL);
    9637                 :             : 
    9638                 :         572 :   gimple_bind_add_seq (bind, dseq);
    9639                 :             : 
    9640                 :         572 :   pop_gimplify_context (bind);
    9641                 :             : 
    9642                 :         572 :   gimple_bind_append_vars (bind, ctx->block_vars);
    9643                 :         572 :   BLOCK_VARS (block) = ctx->block_vars;
    9644                 :         572 : }
    9645                 :             : 
    9646                 :             : 
    9647                 :             : /* Fold the OMP_ORDERED_CLAUSES for the OMP_ORDERED in STMT if possible.  */
    9648                 :             : 
    9649                 :             : static void
    9650                 :           0 : lower_omp_ordered_clauses (gimple_stmt_iterator *gsi_p, gomp_ordered *ord_stmt,
    9651                 :             :                            omp_context *ctx)
    9652                 :             : {
    9653                 :           0 :   struct omp_for_data fd;
    9654                 :           0 :   if (!ctx->outer || gimple_code (ctx->outer->stmt) != GIMPLE_OMP_FOR)
    9655                 :           0 :     return;
    9656                 :             : 
    9657                 :           0 :   unsigned int len = gimple_omp_for_collapse (ctx->outer->stmt);
    9658                 :           0 :   struct omp_for_data_loop *loops = XALLOCAVEC (struct omp_for_data_loop, len);
    9659                 :           0 :   omp_extract_for_data (as_a <gomp_for *> (ctx->outer->stmt), &fd, loops);
    9660                 :           0 :   if (!fd.ordered)
    9661                 :             :     return;
    9662                 :             : 
    9663                 :           0 :   tree *list_p = gimple_omp_ordered_clauses_ptr (ord_stmt);
    9664                 :           0 :   tree c = gimple_omp_ordered_clauses (ord_stmt);
    9665                 :           0 :   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
    9666                 :           0 :       && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
    9667                 :             :     {
    9668                 :             :       /* Merge depend clauses from multiple adjacent
    9669                 :             :          #pragma omp ordered depend(sink:...) constructs
    9670                 :             :          into one #pragma omp ordered depend(sink:...), so that
    9671                 :             :          we can optimize them together.  */
    9672                 :           0 :       gimple_stmt_iterator gsi = *gsi_p;
    9673                 :           0 :       gsi_next (&gsi);
    9674                 :           0 :       while (!gsi_end_p (gsi))
    9675                 :             :         {
    9676                 :           0 :           gimple *stmt = gsi_stmt (gsi);
    9677                 :           0 :           if (is_gimple_debug (stmt)
    9678                 :           0 :               || gimple_code (stmt) == GIMPLE_NOP)
    9679                 :             :             {
    9680                 :           0 :               gsi_next (&gsi);
    9681                 :           0 :               continue;
    9682                 :             :             }
    9683                 :           0 :           if (gimple_code (stmt) != GIMPLE_OMP_ORDERED)
    9684                 :             :             break;
    9685                 :           0 :           gomp_ordered *ord_stmt2 = as_a <gomp_ordered *> (stmt);
    9686                 :           0 :           c = gimple_omp_ordered_clauses (ord_stmt2);
    9687                 :           0 :           if (c == NULL_TREE
    9688                 :           0 :               || OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DOACROSS
    9689                 :           0 :               || OMP_CLAUSE_DOACROSS_KIND (c) != OMP_CLAUSE_DOACROSS_SINK)
    9690                 :             :             break;
    9691                 :           0 :           while (*list_p)
    9692                 :           0 :             list_p = &OMP_CLAUSE_CHAIN (*list_p);
    9693                 :           0 :           *list_p = c;
    9694                 :           0 :           gsi_remove (&gsi, true);
    9695                 :             :         }
    9696                 :             :     }
    9697                 :             : 
    9698                 :             :   /* Canonicalize sink dependence clauses into one folded clause if
    9699                 :             :      possible.
    9700                 :             : 
    9701                 :             :      The basic algorithm is to create a sink vector whose first
    9702                 :             :      element is the GCD of all the first elements, and whose remaining
    9703                 :             :      elements are the minimum of the subsequent columns.
    9704                 :             : 
    9705                 :             :      We ignore dependence vectors whose first element is zero because
    9706                 :             :      such dependencies are known to be executed by the same thread.
    9707                 :             : 
    9708                 :             :      We take into account the direction of the loop, so a minimum
    9709                 :             :      becomes a maximum if the loop is iterating forwards.  We also
    9710                 :             :      ignore sink clauses where the loop direction is unknown, or where
    9711                 :             :      the offsets are clearly invalid because they are not a multiple
    9712                 :             :      of the loop increment.
    9713                 :             : 
    9714                 :             :      For example:
    9715                 :             : 
    9716                 :             :         #pragma omp for ordered(2)
    9717                 :             :         for (i=0; i < N; ++i)
    9718                 :             :           for (j=0; j < M; ++j)
    9719                 :             :             {
    9720                 :             :               #pragma omp ordered \
    9721                 :             :                 depend(sink:i-8,j-2) \
    9722                 :             :                 depend(sink:i,j-1) \    // Completely ignored because i+0.
    9723                 :             :                 depend(sink:i-4,j-3) \
    9724                 :             :                 depend(sink:i-6,j-4)
    9725                 :             :               #pragma omp ordered depend(source)
    9726                 :             :             }
    9727                 :             : 
    9728                 :             :      Folded clause is:
    9729                 :             : 
    9730                 :             :         depend(sink:-gcd(8,4,6),-min(2,3,4))
    9731                 :             :           -or-
    9732                 :             :         depend(sink:-2,-2)
    9733                 :             :   */
    9734                 :             : 
    9735                 :             :   /* FIXME: Computing GCD's where the first element is zero is
    9736                 :             :      non-trivial in the presence of collapsed loops.  Do this later.  */
    9737                 :           0 :   if (fd.collapse > 1)
    9738                 :             :     return;
    9739                 :             : 
    9740                 :           0 :   wide_int *folded_deps = XALLOCAVEC (wide_int, 2 * len - 1);
    9741                 :             : 
    9742                 :             :   /* wide_int is not a POD so it must be default-constructed.  */
    9743                 :           0 :   for (unsigned i = 0; i != 2 * len - 1; ++i)
    9744                 :           0 :     new (static_cast<void*>(folded_deps + i)) wide_int ();
    9745                 :             : 
    9746                 :             :   tree folded_dep = NULL_TREE;
    9747                 :             :   /* TRUE if the first dimension's offset is negative.  */
    9748                 :             :   bool neg_offset_p = false;
    9749                 :             : 
    9750                 :             :   list_p = gimple_omp_ordered_clauses_ptr (ord_stmt);
    9751                 :             :   unsigned int i;
    9752                 :           0 :   while ((c = *list_p) != NULL)
    9753                 :             :     {
    9754                 :           0 :       bool remove = false;
    9755                 :             : 
    9756                 :           0 :       gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS);
    9757                 :           0 :       if (OMP_CLAUSE_DOACROSS_KIND (c) != OMP_CLAUSE_DOACROSS_SINK)
    9758                 :           0 :         goto next_ordered_clause;
    9759                 :             : 
    9760                 :           0 :       tree vec;
    9761                 :           0 :       for (vec = OMP_CLAUSE_DECL (c), i = 0;
    9762                 :           0 :            vec && TREE_CODE (vec) == TREE_LIST;
    9763                 :           0 :            vec = TREE_CHAIN (vec), ++i)
    9764                 :             :         {
    9765                 :           0 :           gcc_assert (i < len);
    9766                 :             : 
    9767                 :             :           /* omp_extract_for_data has canonicalized the condition.  */
    9768                 :           0 :           gcc_assert (fd.loops[i].cond_code == LT_EXPR
    9769                 :             :                       || fd.loops[i].cond_code == GT_EXPR);
    9770                 :           0 :           bool forward = fd.loops[i].cond_code == LT_EXPR;
    9771                 :           0 :           bool maybe_lexically_later = true;
    9772                 :             : 
    9773                 :             :           /* While the committee makes up its mind, bail if we have any
    9774                 :             :              non-constant steps.  */
    9775                 :           0 :           if (TREE_CODE (fd.loops[i].step) != INTEGER_CST)
    9776                 :           0 :             goto lower_omp_ordered_ret;
    9777                 :             : 
    9778                 :           0 :           tree itype = TREE_TYPE (TREE_VALUE (vec));
    9779                 :           0 :           if (POINTER_TYPE_P (itype))
    9780                 :           0 :             itype = sizetype;
    9781                 :           0 :           wide_int offset = wide_int::from (wi::to_wide (TREE_PURPOSE (vec)),
    9782                 :           0 :                                             TYPE_PRECISION (itype),
    9783                 :           0 :                                             TYPE_SIGN (itype));
    9784                 :             : 
    9785                 :             :           /* Ignore invalid offsets that are not multiples of the step.  */
    9786                 :           0 :           if (!wi::multiple_of_p (wi::abs (offset),
    9787                 :           0 :                                   wi::abs (wi::to_wide (fd.loops[i].step)),
    9788                 :             :                                   UNSIGNED))
    9789                 :             :             {
    9790                 :           0 :               warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
    9791                 :             :                           "ignoring %<sink%> clause with offset that is not "
    9792                 :             :                           "a multiple of the loop step");
    9793                 :           0 :               remove = true;
    9794                 :           0 :               goto next_ordered_clause;
    9795                 :             :             }
    9796                 :             : 
    9797                 :             :           /* Calculate the first dimension.  The first dimension of
    9798                 :             :              the folded dependency vector is the GCD of the first
    9799                 :             :              elements, while ignoring any first elements whose offset
    9800                 :             :              is 0.  */
    9801                 :           0 :           if (i == 0)
    9802                 :             :             {
    9803                 :             :               /* Ignore dependence vectors whose first dimension is 0.  */
    9804                 :           0 :               if (offset == 0)
    9805                 :             :                 {
    9806                 :           0 :                   remove = true;
    9807                 :           0 :                   goto next_ordered_clause;
    9808                 :             :                 }
    9809                 :             :               else
    9810                 :             :                 {
    9811                 :           0 :                   if (!TYPE_UNSIGNED (itype) && (forward ^ wi::neg_p (offset)))
    9812                 :             :                     {
    9813                 :           0 :                       error_at (OMP_CLAUSE_LOCATION (c),
    9814                 :             :                                 "first offset must be in opposite direction "
    9815                 :             :                                 "of loop iterations");
    9816                 :           0 :                       goto lower_omp_ordered_ret;
    9817                 :             :                     }
    9818                 :           0 :                   if (forward)
    9819                 :           0 :                     offset = -offset;
    9820                 :           0 :                   neg_offset_p = forward;
    9821                 :             :                   /* Initialize the first time around.  */
    9822                 :           0 :                   if (folded_dep == NULL_TREE)
    9823                 :             :                     {
    9824                 :           0 :                       folded_dep = c;
    9825                 :           0 :                       folded_deps[0] = offset;
    9826                 :             :                     }
    9827                 :             :                   else
    9828                 :           0 :                     folded_deps[0] = wi::gcd (folded_deps[0],
    9829                 :           0 :                                               offset, UNSIGNED);
    9830                 :             :                 }
    9831                 :             :             }
    9832                 :             :           /* Calculate minimum for the remaining dimensions.  */
    9833                 :             :           else
    9834                 :             :             {
    9835                 :           0 :               folded_deps[len + i - 1] = offset;
    9836                 :           0 :               if (folded_dep == c)
    9837                 :           0 :                 folded_deps[i] = offset;
    9838                 :           0 :               else if (maybe_lexically_later
    9839                 :           0 :                        && !wi::eq_p (folded_deps[i], offset))
    9840                 :             :                 {
    9841                 :           0 :                   if (forward ^ wi::gts_p (folded_deps[i], offset))
    9842                 :             :                     {
    9843                 :             :                       unsigned int j;
    9844                 :           0 :                       folded_dep = c;
    9845                 :           0 :                       for (j = 1; j <= i; j++)
    9846                 :           0 :                         folded_deps[j] = folded_deps[len + j - 1];
    9847                 :             :                     }
    9848                 :             :                   else
    9849                 :           0 :                     maybe_lexically_later = false;
    9850                 :             :                 }
    9851                 :             :             }
    9852                 :           0 :         }
    9853                 :           0 :       gcc_assert (i == len);
    9854                 :             : 
    9855                 :             :       remove = true;
    9856                 :             : 
    9857                 :           0 :     next_ordered_clause:
    9858                 :           0 :       if (remove)
    9859                 :           0 :         *list_p = OMP_CLAUSE_CHAIN (c);
    9860                 :             :       else
    9861                 :           0 :         list_p = &OMP_CLAUSE_CHAIN (c);
    9862                 :             :     }
    9863                 :             : 
    9864                 :           0 :   if (folded_dep)
    9865                 :             :     {
    9866                 :           0 :       if (neg_offset_p)
    9867                 :           0 :         folded_deps[0] = -folded_deps[0];
    9868                 :             : 
    9869                 :           0 :       tree itype = TREE_TYPE (TREE_VALUE (OMP_CLAUSE_DECL (folded_dep)));
    9870                 :           0 :       if (POINTER_TYPE_P (itype))
    9871                 :           0 :         itype = sizetype;
    9872                 :             : 
    9873                 :           0 :       TREE_PURPOSE (OMP_CLAUSE_DECL (folded_dep))
    9874                 :           0 :         = wide_int_to_tree (itype, folded_deps[0]);
    9875                 :           0 :       OMP_CLAUSE_CHAIN (folded_dep) = gimple_omp_ordered_clauses (ord_stmt);
    9876                 :           0 :       *gimple_omp_ordered_clauses_ptr (ord_stmt) = folded_dep;
    9877                 :             :     }
    9878                 :             : 
    9879                 :           0 :  lower_omp_ordered_ret:
    9880                 :             : 
    9881                 :             :   /* Ordered without clauses is #pragma omp threads, while we want
    9882                 :             :      a nop instead if we remove all clauses.  */
    9883                 :           0 :   if (gimple_omp_ordered_clauses (ord_stmt) == NULL_TREE)
    9884                 :           0 :     gsi_replace (gsi_p, gimple_build_nop (), true);
    9885                 :             : }
    9886                 :             : 
    9887                 :             : 
    9888                 :             : /* Expand code for an OpenMP ordered directive.  */
    9889                 :             : 
    9890                 :             : static void
    9891                 :        1209 : lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
    9892                 :             : {
    9893                 :        1209 :   tree block;
    9894                 :        1209 :   gimple *stmt = gsi_stmt (*gsi_p), *g;
    9895                 :        1209 :   gomp_ordered *ord_stmt = as_a <gomp_ordered *> (stmt);
    9896                 :        1209 :   gcall *x;
    9897                 :        1209 :   gbind *bind;
    9898                 :        1209 :   bool simd = omp_find_clause (gimple_omp_ordered_clauses (ord_stmt),
    9899                 :        1209 :                                OMP_CLAUSE_SIMD);
    9900                 :             :   /* FIXME: this should check presence of OMP_CLAUSE__SIMT_ on the enclosing
    9901                 :             :      loop.  */
    9902                 :        1209 :   bool maybe_simt
    9903                 :        1209 :     = simd && omp_maybe_offloaded_ctx (ctx) && omp_max_simt_vf () > 1;
    9904                 :        1209 :   bool threads = omp_find_clause (gimple_omp_ordered_clauses (ord_stmt),
    9905                 :        1209 :                                   OMP_CLAUSE_THREADS);
    9906                 :             : 
    9907                 :        1209 :   if (gimple_omp_ordered_standalone_p (ord_stmt))
    9908                 :             :     {
    9909                 :             :       /* FIXME: This is needs to be moved to the expansion to verify various
    9910                 :             :          conditions only testable on cfg with dominators computed, and also
    9911                 :             :          all the depend clauses to be merged still might need to be available
    9912                 :             :          for the runtime checks.  */
    9913                 :             :       if (0)
    9914                 :             :         lower_omp_ordered_clauses (gsi_p, ord_stmt, ctx);
    9915                 :        1209 :       return;
    9916                 :             :     }
    9917                 :             : 
    9918                 :         449 :   push_gimplify_context ();
    9919                 :             : 
    9920                 :         449 :   block = make_node (BLOCK);
    9921                 :         449 :   bind = gimple_build_bind (NULL, NULL, block);
    9922                 :         449 :   gsi_replace (gsi_p, bind, true);
    9923                 :         449 :   gimple_bind_add_stmt (bind, stmt);
    9924                 :             : 
    9925                 :         449 :   if (simd)
    9926                 :             :     {
    9927                 :          96 :       x = gimple_build_call_internal (IFN_GOMP_SIMD_ORDERED_START, 1,
    9928                 :             :                                       build_int_cst (NULL_TREE, threads));
    9929                 :          96 :       cfun->has_simduid_loops = true;
    9930                 :             :     }
    9931                 :             :   else
    9932                 :         353 :     x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
    9933                 :             :                            0);
    9934                 :         449 :   gimple_bind_add_stmt (bind, x);
    9935                 :             : 
    9936                 :         449 :   tree counter = NULL_TREE, test = NULL_TREE, body = NULL_TREE;
    9937                 :         449 :   if (maybe_simt)
    9938                 :             :     {
    9939                 :           0 :       counter = create_tmp_var (integer_type_node);
    9940                 :           0 :       g = gimple_build_call_internal (IFN_GOMP_SIMT_LANE, 0);
    9941                 :           0 :       gimple_call_set_lhs (g, counter);
    9942                 :           0 :       gimple_bind_add_stmt (bind, g);
    9943                 :             : 
    9944                 :           0 :       body = create_artificial_label (UNKNOWN_LOCATION);
    9945                 :           0 :       test = create_artificial_label (UNKNOWN_LOCATION);
    9946                 :           0 :       gimple_bind_add_stmt (bind, gimple_build_label (body));
    9947                 :             : 
    9948                 :           0 :       tree simt_pred = create_tmp_var (integer_type_node);
    9949                 :           0 :       g = gimple_build_call_internal (IFN_GOMP_SIMT_ORDERED_PRED, 1, counter);
    9950                 :           0 :       gimple_call_set_lhs (g, simt_pred);
    9951                 :           0 :       gimple_bind_add_stmt (bind, g);
    9952                 :             : 
    9953                 :           0 :       tree t = create_artificial_label (UNKNOWN_LOCATION);
    9954                 :           0 :       g = gimple_build_cond (EQ_EXPR, simt_pred, integer_zero_node, t, test);
    9955                 :           0 :       gimple_bind_add_stmt (bind, g);
    9956                 :             : 
    9957                 :           0 :       gimple_bind_add_stmt (bind, gimple_build_label (t));
    9958                 :             :     }
    9959                 :         449 :   lower_omp (gimple_omp_body_ptr (stmt), ctx);
    9960                 :         449 :   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
    9961                 :         449 :   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
    9962                 :         449 :   gimple_omp_set_body (stmt, NULL);
    9963                 :             : 
    9964                 :         449 :   if (maybe_simt)
    9965                 :             :     {
    9966                 :           0 :       gimple_bind_add_stmt (bind, gimple_build_label (test));
    9967                 :           0 :       g = gimple_build_assign (counter, MINUS_EXPR, counter, integer_one_node);
    9968                 :           0 :       gimple_bind_add_stmt (bind, g);
    9969                 :             : 
    9970                 :           0 :       tree c = build2 (GE_EXPR, boolean_type_node, counter, integer_zero_node);
    9971                 :           0 :       tree nonneg = create_tmp_var (integer_type_node);
    9972                 :           0 :       gimple_seq tseq = NULL;
    9973                 :           0 :       gimplify_assign (nonneg, fold_convert (integer_type_node, c), &tseq);
    9974                 :           0 :       gimple_bind_add_seq (bind, tseq);
    9975                 :             : 
    9976                 :           0 :       g = gimple_build_call_internal (IFN_GOMP_SIMT_VOTE_ANY, 1, nonneg);
    9977                 :           0 :       gimple_call_set_lhs (g, nonneg);
    9978                 :           0 :       gimple_bind_add_stmt (bind, g);
    9979                 :             : 
    9980                 :           0 :       tree end = create_artificial_label (UNKNOWN_LOCATION);
    9981                 :           0 :       g = gimple_build_cond (NE_EXPR, nonneg, integer_zero_node, body, end);
    9982                 :           0 :       gimple_bind_add_stmt (bind, g);
    9983                 :             : 
    9984                 :           0 :       gimple_bind_add_stmt (bind, gimple_build_label (end));
    9985                 :             :     }
    9986                 :         449 :   if (simd)
    9987                 :          96 :     x = gimple_build_call_internal (IFN_GOMP_SIMD_ORDERED_END, 1,
    9988                 :             :                                     build_int_cst (NULL_TREE, threads));
    9989                 :             :   else
    9990                 :         353 :     x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END),
    9991                 :             :                            0);
    9992                 :         449 :   gimple_bind_add_stmt (bind, x);
    9993                 :             : 
    9994                 :         449 :   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
    9995                 :             : 
    9996                 :         449 :   pop_gimplify_context (bind);
    9997                 :             : 
    9998                 :         449 :   gimple_bind_append_vars (bind, ctx->block_vars);
    9999                 :         449 :   BLOCK_VARS (block) = gimple_bind_vars (bind);
   10000                 :             : }
   10001                 :             : 
   10002                 :             : 
   10003                 :             : /* Expand code for an OpenMP scan directive and the structured block
   10004                 :             :    before the scan directive.  */
   10005                 :             : 
   10006                 :             : static void
   10007                 :        1644 : lower_omp_scan (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   10008                 :             : {
   10009                 :        1644 :   gimple *stmt = gsi_stmt (*gsi_p);
   10010                 :        1644 :   bool has_clauses
   10011                 :        1644 :     = gimple_omp_scan_clauses (as_a <gomp_scan *> (stmt)) != NULL;
   10012                 :        1644 :   tree lane = NULL_TREE;
   10013                 :        1644 :   gimple_seq before = NULL;
   10014                 :        1644 :   omp_context *octx = ctx->outer;
   10015                 :        1644 :   gcc_assert (octx);
   10016                 :        1644 :   if (octx->scan_exclusive && !has_clauses)
   10017                 :             :     {
   10018                 :         576 :       gimple_stmt_iterator gsi2 = *gsi_p;
   10019                 :         576 :       gsi_next (&gsi2);
   10020                 :         576 :       gimple *stmt2 = gsi_stmt (gsi2);
   10021                 :             :       /* For exclusive scan, swap GIMPLE_OMP_SCAN without clauses
   10022                 :             :          with following GIMPLE_OMP_SCAN with clauses, so that input_phase,
   10023                 :             :          the one with exclusive clause(s), comes first.  */
   10024                 :         576 :       if (stmt2
   10025                 :         294 :           && gimple_code (stmt2) == GIMPLE_OMP_SCAN
   10026                 :         864 :           && gimple_omp_scan_clauses (as_a <gomp_scan *> (stmt2)) != NULL)
   10027                 :             :         {
   10028                 :         288 :           gsi_remove (gsi_p, false);
   10029                 :         288 :           gsi_insert_after (gsi_p, stmt, GSI_SAME_STMT);
   10030                 :         288 :           ctx = maybe_lookup_ctx (stmt2);
   10031                 :         288 :           gcc_assert (ctx);
   10032                 :         288 :           lower_omp_scan (gsi_p, ctx);
   10033                 :         288 :           return;
   10034                 :             :         }
   10035                 :             :     }
   10036                 :             : 
   10037                 :        1356 :   bool input_phase = has_clauses ^ octx->scan_inclusive;
   10038                 :        1356 :   bool is_simd = (gimple_code (octx->stmt) == GIMPLE_OMP_FOR
   10039                 :        1356 :                   && gimple_omp_for_kind (octx->stmt) == GF_OMP_FOR_KIND_SIMD);
   10040                 :        1356 :   bool is_for = (gimple_code (octx->stmt) == GIMPLE_OMP_FOR
   10041                 :        1356 :                  && gimple_omp_for_kind (octx->stmt) == GF_OMP_FOR_KIND_FOR
   10042                 :        1708 :                  && !gimple_omp_for_combined_p (octx->stmt));
   10043                 :        1356 :   bool is_for_simd = is_simd && gimple_omp_for_combined_into_p (octx->stmt);
   10044                 :         336 :   if (is_for_simd && octx->for_simd_scan_phase)
   10045                 :             :     is_simd = false;
   10046                 :        1188 :   if (is_simd)
   10047                 :         836 :     if (tree c = omp_find_clause (gimple_omp_for_clauses (octx->stmt),
   10048                 :             :                                   OMP_CLAUSE__SIMDUID_))
   10049                 :             :       {
   10050                 :         404 :         tree uid = OMP_CLAUSE__SIMDUID__DECL (c);
   10051                 :         404 :         lane = create_tmp_var (unsigned_type_node);
   10052                 :         404 :         tree t = build_int_cst (integer_type_node,
   10053                 :         606 :                                 input_phase ? 1
   10054                 :         202 :                                 : octx->scan_inclusive ? 2 : 3);
   10055                 :         404 :         gimple *g
   10056                 :         404 :           = gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 2, uid, t);
   10057                 :         404 :         gimple_call_set_lhs (g, lane);
   10058                 :         404 :         gimple_seq_add_stmt (&before, g);
   10059                 :             :       }
   10060                 :             : 
   10061                 :        1356 :   if (is_simd || is_for)
   10062                 :             :     {
   10063                 :        5388 :       for (tree c = gimple_omp_for_clauses (octx->stmt);
   10064                 :        5388 :            c; c = OMP_CLAUSE_CHAIN (c))
   10065                 :        4368 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   10066                 :        4368 :             && OMP_CLAUSE_REDUCTION_INSCAN (c))
   10067                 :             :           {
   10068                 :        1244 :             location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   10069                 :        1244 :             tree var = OMP_CLAUSE_DECL (c);
   10070                 :        1244 :             tree new_var = lookup_decl (var, octx);
   10071                 :        1244 :             tree val = new_var;
   10072                 :        1244 :             tree var2 = NULL_TREE;
   10073                 :        1244 :             tree var3 = NULL_TREE;
   10074                 :        1244 :             tree var4 = NULL_TREE;
   10075                 :        1244 :             tree lane0 = NULL_TREE;
   10076                 :        1244 :             tree new_vard = new_var;
   10077                 :        1244 :             if (omp_privatize_by_reference (var))
   10078                 :             :               {
   10079                 :         320 :                 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
   10080                 :         320 :                 val = new_var;
   10081                 :             :               }
   10082                 :        1244 :             if (DECL_HAS_VALUE_EXPR_P (new_vard))
   10083                 :             :               {
   10084                 :         500 :                 val = DECL_VALUE_EXPR (new_vard);
   10085                 :         500 :                 if (new_vard != new_var)
   10086                 :             :                   {
   10087                 :         136 :                     gcc_assert (TREE_CODE (val) == ADDR_EXPR);
   10088                 :         136 :                     val = TREE_OPERAND (val, 0);
   10089                 :             :                   }
   10090                 :         500 :                 if (TREE_CODE (val) == ARRAY_REF
   10091                 :         500 :                     && VAR_P (TREE_OPERAND (val, 0)))
   10092                 :             :                   {
   10093                 :         500 :                     tree v = TREE_OPERAND (val, 0);
   10094                 :         500 :                     if (lookup_attribute ("omp simd array",
   10095                 :         500 :                                           DECL_ATTRIBUTES (v)))
   10096                 :             :                       {
   10097                 :         500 :                         val = unshare_expr (val);
   10098                 :         500 :                         lane0 = TREE_OPERAND (val, 1);
   10099                 :         500 :                         TREE_OPERAND (val, 1) = lane;
   10100                 :         500 :                         var2 = lookup_decl (v, octx);
   10101                 :         500 :                         if (octx->scan_exclusive)
   10102                 :         244 :                           var4 = lookup_decl (var2, octx);
   10103                 :         500 :                         if (input_phase
   10104                 :         500 :                             && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   10105                 :         142 :                           var3 = maybe_lookup_decl (var4 ? var4 : var2, octx);
   10106                 :         500 :                         if (!input_phase)
   10107                 :             :                           {
   10108                 :         250 :                             var2 = build4 (ARRAY_REF, TREE_TYPE (val),
   10109                 :             :                                            var2, lane, NULL_TREE, NULL_TREE);
   10110                 :         250 :                             TREE_THIS_NOTRAP (var2) = 1;
   10111                 :         250 :                             if (octx->scan_exclusive)
   10112                 :             :                               {
   10113                 :         122 :                                 var4 = build4 (ARRAY_REF, TREE_TYPE (val),
   10114                 :             :                                                var4, lane, NULL_TREE,
   10115                 :             :                                                NULL_TREE);
   10116                 :         122 :                                 TREE_THIS_NOTRAP (var4) = 1;
   10117                 :             :                               }
   10118                 :             :                           }
   10119                 :             :                         else
   10120                 :             :                           var2 = val;
   10121                 :             :                       }
   10122                 :             :                   }
   10123                 :         500 :                 gcc_assert (var2);
   10124                 :             :               }
   10125                 :             :             else
   10126                 :             :               {
   10127                 :         744 :                 var2 = build_outer_var_ref (var, octx);
   10128                 :         744 :                 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   10129                 :             :                   {
   10130                 :         248 :                     var3 = maybe_lookup_decl (new_vard, octx);
   10131                 :         248 :                     if (var3 == new_vard || var3 == NULL_TREE)
   10132                 :             :                       var3 = NULL_TREE;
   10133                 :         128 :                     else if (is_simd && octx->scan_exclusive && !input_phase)
   10134                 :             :                       {
   10135                 :          20 :                         var4 = maybe_lookup_decl (var3, octx);
   10136                 :          20 :                         if (var4 == var3 || var4 == NULL_TREE)
   10137                 :             :                           {
   10138                 :           0 :                             if (TREE_ADDRESSABLE (TREE_TYPE (new_var)))
   10139                 :             :                               {
   10140                 :             :                                 var4 = var3;
   10141                 :             :                                 var3 = NULL_TREE;
   10142                 :             :                               }
   10143                 :             :                             else
   10144                 :          76 :                               var4 = NULL_TREE;
   10145                 :             :                           }
   10146                 :             :                       }
   10147                 :             :                   }
   10148                 :         744 :                 if (is_simd
   10149                 :         528 :                     && octx->scan_exclusive
   10150                 :         266 :                     && !input_phase
   10151                 :         266 :                     && var4 == NULL_TREE)
   10152                 :         113 :                   var4 = create_tmp_var (TREE_TYPE (val));
   10153                 :             :               }
   10154                 :        1244 :             if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   10155                 :             :               {
   10156                 :         432 :                 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
   10157                 :         432 :                 if (input_phase)
   10158                 :             :                   {
   10159                 :         216 :                     if (var3)
   10160                 :             :                       {
   10161                 :             :                         /* If we've added a separate identity element
   10162                 :             :                            variable, copy it over into val.  */
   10163                 :         112 :                         tree x = lang_hooks.decls.omp_clause_assign_op (c, val,
   10164                 :             :                                                                         var3);
   10165                 :         112 :                         gimplify_and_add (x, &before);
   10166                 :             :                       }
   10167                 :         104 :                     else if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
   10168                 :             :                       {
   10169                 :             :                         /* Otherwise, assign to it the identity element.  */
   10170                 :         104 :                         gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
   10171                 :         104 :                         if (is_for)
   10172                 :          16 :                           tseq = copy_gimple_seq_and_replace_locals (tseq);
   10173                 :         104 :                         tree ref = build_outer_var_ref (var, octx);
   10174                 :         104 :                         tree x = (DECL_HAS_VALUE_EXPR_P (new_vard)
   10175                 :         104 :                                   ? DECL_VALUE_EXPR (new_vard) : NULL_TREE);
   10176                 :          44 :                         if (x)
   10177                 :             :                           {
   10178                 :          44 :                             if (new_vard != new_var)
   10179                 :          20 :                               val = build_fold_addr_expr_loc (clause_loc, val);
   10180                 :          44 :                             SET_DECL_VALUE_EXPR (new_vard, val);
   10181                 :             :                           }
   10182                 :         104 :                         SET_DECL_VALUE_EXPR (placeholder, ref);
   10183                 :         104 :                         DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
   10184                 :         104 :                         lower_omp (&tseq, octx);
   10185                 :         104 :                         if (x)
   10186                 :          44 :                           SET_DECL_VALUE_EXPR (new_vard, x);
   10187                 :         104 :                         SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
   10188                 :         104 :                         DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
   10189                 :         104 :                         gimple_seq_add_seq (&before, tseq);
   10190                 :         104 :                         if (is_simd)
   10191                 :          88 :                           OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
   10192                 :             :                       }
   10193                 :             :                   }
   10194                 :         216 :                 else if (is_simd)
   10195                 :             :                   {
   10196                 :         184 :                     tree x;
   10197                 :         184 :                     if (octx->scan_exclusive)
   10198                 :             :                       {
   10199                 :          84 :                         tree v4 = unshare_expr (var4);
   10200                 :          84 :                         tree v2 = unshare_expr (var2);
   10201                 :          84 :                         x = lang_hooks.decls.omp_clause_assign_op (c, v4, v2);
   10202                 :          84 :                         gimplify_and_add (x, &before);
   10203                 :             :                       }
   10204                 :         184 :                     gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
   10205                 :         184 :                     x = (DECL_HAS_VALUE_EXPR_P (new_vard)
   10206                 :         184 :                          ? DECL_VALUE_EXPR (new_vard) : NULL_TREE);
   10207                 :         184 :                     tree vexpr = val;
   10208                 :         184 :                     if (x && new_vard != new_var)
   10209                 :          48 :                       vexpr = build_fold_addr_expr_loc (clause_loc, val);
   10210                 :         184 :                     if (x)
   10211                 :          92 :                       SET_DECL_VALUE_EXPR (new_vard, vexpr);
   10212                 :         184 :                     SET_DECL_VALUE_EXPR (placeholder, var2);
   10213                 :         184 :                     DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
   10214                 :         184 :                     lower_omp (&tseq, octx);
   10215                 :         184 :                     gimple_seq_add_seq (&before, tseq);
   10216                 :         184 :                     OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
   10217                 :         184 :                     if (x)
   10218                 :          92 :                       SET_DECL_VALUE_EXPR (new_vard, x);
   10219                 :         184 :                     SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
   10220                 :         184 :                     DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
   10221                 :         184 :                     if (octx->scan_inclusive)
   10222                 :             :                       {
   10223                 :         100 :                         x = lang_hooks.decls.omp_clause_assign_op (c, val,
   10224                 :             :                                                                    var2);
   10225                 :         100 :                         gimplify_and_add (x, &before);
   10226                 :             :                       }
   10227                 :          84 :                     else if (lane0 == NULL_TREE)
   10228                 :             :                       {
   10229                 :          42 :                         x = lang_hooks.decls.omp_clause_assign_op (c, val,
   10230                 :             :                                                                    var4);
   10231                 :          42 :                         gimplify_and_add (x, &before);
   10232                 :             :                       }
   10233                 :             :                   }
   10234                 :             :               }
   10235                 :             :             else
   10236                 :             :               {
   10237                 :         812 :                 if (input_phase)
   10238                 :             :                   {
   10239                 :             :                     /* input phase.  Set val to initializer before
   10240                 :             :                        the body.  */
   10241                 :         406 :                     tree x = omp_reduction_init (c, TREE_TYPE (new_var));
   10242                 :         406 :                     gimplify_assign (val, x, &before);
   10243                 :             :                   }
   10244                 :         406 :                 else if (is_simd)
   10245                 :             :                   {
   10246                 :             :                     /* scan phase.  */
   10247                 :         330 :                     enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
   10248                 :         330 :                     if (code == MINUS_EXPR)
   10249                 :           0 :                       code = PLUS_EXPR;
   10250                 :             : 
   10251                 :         330 :                     tree x = build2 (code, TREE_TYPE (var2),
   10252                 :             :                                      unshare_expr (var2), unshare_expr (val));
   10253                 :         330 :                     if (octx->scan_inclusive)
   10254                 :             :                       {
   10255                 :         159 :                         gimplify_assign (unshare_expr (var2), x, &before);
   10256                 :         159 :                         gimplify_assign (val, var2, &before);
   10257                 :             :                       }
   10258                 :             :                     else
   10259                 :             :                       {
   10260                 :         171 :                         gimplify_assign (unshare_expr (var4),
   10261                 :             :                                          unshare_expr (var2), &before);
   10262                 :         171 :                         gimplify_assign (var2, x, &before);
   10263                 :         171 :                         if (lane0 == NULL_TREE)
   10264                 :          91 :                           gimplify_assign (val, var4, &before);
   10265                 :             :                       }
   10266                 :             :                   }
   10267                 :             :               }
   10268                 :        1244 :             if (octx->scan_exclusive && !input_phase && lane0)
   10269                 :             :               {
   10270                 :         122 :                 tree vexpr = unshare_expr (var4);
   10271                 :         122 :                 TREE_OPERAND (vexpr, 1) = lane0;
   10272                 :         122 :                 if (new_vard != new_var)
   10273                 :          30 :                   vexpr = build_fold_addr_expr_loc (clause_loc, vexpr);
   10274                 :         122 :                 SET_DECL_VALUE_EXPR (new_vard, vexpr);
   10275                 :             :               }
   10276                 :             :           }
   10277                 :             :     }
   10278                 :        1356 :   if (is_simd && !is_for_simd)
   10279                 :             :     {
   10280                 :         668 :       gsi_insert_seq_after (gsi_p, gimple_omp_body (stmt), GSI_SAME_STMT);
   10281                 :         668 :       gsi_insert_seq_after (gsi_p, before, GSI_SAME_STMT);
   10282                 :         668 :       gsi_replace (gsi_p, gimple_build_nop (), true);
   10283                 :         668 :       return;
   10284                 :             :     }
   10285                 :         688 :   lower_omp (gimple_omp_body_ptr (stmt), octx);
   10286                 :         688 :   if (before)
   10287                 :             :     {
   10288                 :         260 :       gimple_stmt_iterator gsi = gsi_start (*gimple_omp_body_ptr (stmt));
   10289                 :         260 :       gsi_insert_seq_before (&gsi, before, GSI_SAME_STMT);
   10290                 :             :     }
   10291                 :             : }
   10292                 :             : 
   10293                 :             : 
   10294                 :             : /* Gimplify a GIMPLE_OMP_CRITICAL statement.  This is a relatively simple
   10295                 :             :    substitution of a couple of function calls.  But in the NAMED case,
   10296                 :             :    requires that languages coordinate a symbol name.  It is therefore
   10297                 :             :    best put here in common code.  */
   10298                 :             : 
   10299                 :             : static GTY(()) hash_map<tree, tree> *critical_name_mutexes;
   10300                 :             : 
   10301                 :             : static void
   10302                 :         334 : lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   10303                 :             : {
   10304                 :         334 :   tree block;
   10305                 :         334 :   tree name, lock, unlock;
   10306                 :         334 :   gomp_critical *stmt = as_a <gomp_critical *> (gsi_stmt (*gsi_p));
   10307                 :         334 :   gbind *bind;
   10308                 :         334 :   location_t loc = gimple_location (stmt);
   10309                 :         334 :   gimple_seq tbody;
   10310                 :             : 
   10311                 :         334 :   name = gimple_omp_critical_name (stmt);
   10312                 :         334 :   if (name)
   10313                 :             :     {
   10314                 :          95 :       tree decl;
   10315                 :             : 
   10316                 :          95 :       if (!critical_name_mutexes)
   10317                 :          52 :         critical_name_mutexes = hash_map<tree, tree>::create_ggc (10);
   10318                 :             : 
   10319                 :          95 :       tree *n = critical_name_mutexes->get (name);
   10320                 :          95 :       if (n == NULL)
   10321                 :             :         {
   10322                 :          74 :           char *new_str;
   10323                 :             : 
   10324                 :          74 :           decl = create_tmp_var_raw (ptr_type_node);
   10325                 :             : 
   10326                 :          74 :           new_str = ACONCAT ((".gomp_critical_user_",
   10327                 :             :                               IDENTIFIER_POINTER (name), NULL));
   10328                 :          74 :           DECL_NAME (decl) = get_identifier (new_str);
   10329                 :          74 :           TREE_PUBLIC (decl) = 1;
   10330                 :          74 :           TREE_STATIC (decl) = 1;
   10331                 :          74 :           DECL_COMMON (decl) = 1;
   10332                 :          74 :           DECL_ARTIFICIAL (decl) = 1;
   10333                 :          74 :           DECL_IGNORED_P (decl) = 1;
   10334                 :             : 
   10335                 :          74 :           varpool_node::finalize_decl (decl);
   10336                 :             : 
   10337                 :          74 :           critical_name_mutexes->put (name, decl);
   10338                 :             :         }
   10339                 :             :       else
   10340                 :          21 :         decl = *n;
   10341                 :             : 
   10342                 :             :       /* If '#pragma omp critical' is inside offloaded region or
   10343                 :             :          inside function marked as offloadable, the symbol must be
   10344                 :             :          marked as offloadable too.  */
   10345                 :          95 :       omp_context *octx;
   10346                 :          95 :       if (cgraph_node::get (current_function_decl)->offloadable)
   10347                 :           1 :         varpool_node::get_create (decl)->offloadable = 1;
   10348                 :             :       else
   10349                 :         181 :         for (octx = ctx->outer; octx; octx = octx->outer)
   10350                 :          88 :           if (is_gimple_omp_offloaded (octx->stmt))
   10351                 :             :             {
   10352                 :           1 :               varpool_node::get_create (decl)->offloadable = 1;
   10353                 :           1 :               break;
   10354                 :             :             }
   10355                 :             : 
   10356                 :          95 :       lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
   10357                 :          95 :       lock = build_call_expr_loc (loc, lock, 1,
   10358                 :             :                                   build_fold_addr_expr_loc (loc, decl));
   10359                 :             : 
   10360                 :          95 :       unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
   10361                 :          95 :       unlock = build_call_expr_loc (loc, unlock, 1,
   10362                 :             :                                 build_fold_addr_expr_loc (loc, decl));
   10363                 :             :     }
   10364                 :             :   else
   10365                 :             :     {
   10366                 :         239 :       lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
   10367                 :         239 :       lock = build_call_expr_loc (loc, lock, 0);
   10368                 :             : 
   10369                 :         239 :       unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
   10370                 :         239 :       unlock = build_call_expr_loc (loc, unlock, 0);
   10371                 :             :     }
   10372                 :             : 
   10373                 :         334 :   push_gimplify_context ();
   10374                 :             : 
   10375                 :         334 :   block = make_node (BLOCK);
   10376                 :         334 :   bind = gimple_build_bind (NULL, NULL, block);
   10377                 :         334 :   gsi_replace (gsi_p, bind, true);
   10378                 :         334 :   gimple_bind_add_stmt (bind, stmt);
   10379                 :             : 
   10380                 :         334 :   tbody = gimple_bind_body (bind);
   10381                 :         334 :   gimplify_and_add (lock, &tbody);
   10382                 :         334 :   gimple_bind_set_body (bind, tbody);
   10383                 :             : 
   10384                 :         334 :   lower_omp (gimple_omp_body_ptr (stmt), ctx);
   10385                 :         334 :   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
   10386                 :         334 :   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
   10387                 :         334 :   gimple_omp_set_body (stmt, NULL);
   10388                 :             : 
   10389                 :         334 :   tbody = gimple_bind_body (bind);
   10390                 :         334 :   gimplify_and_add (unlock, &tbody);
   10391                 :         334 :   gimple_bind_set_body (bind, tbody);
   10392                 :             : 
   10393                 :         334 :   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
   10394                 :             : 
   10395                 :         334 :   pop_gimplify_context (bind);
   10396                 :         334 :   gimple_bind_append_vars (bind, ctx->block_vars);
   10397                 :         334 :   BLOCK_VARS (block) = gimple_bind_vars (bind);
   10398                 :         334 : }
   10399                 :             : 
   10400                 :             : /* A subroutine of lower_omp_for.  Generate code to emit the predicate
   10401                 :             :    for a lastprivate clause.  Given a loop control predicate of (V
   10402                 :             :    cond N2), we gate the clause on (!(V cond N2)).  The lowered form
   10403                 :             :    is appended to *DLIST, iterator initialization is appended to
   10404                 :             :    *BODY_P.  *CLIST is for lastprivate(conditional:) code that needs
   10405                 :             :    to be emitted in a critical section.  */
   10406                 :             : 
   10407                 :             : static void
   10408                 :       46675 : lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
   10409                 :             :                            gimple_seq *dlist, gimple_seq *clist,
   10410                 :             :                            struct omp_context *ctx)
   10411                 :             : {
   10412                 :       46675 :   tree clauses, cond, vinit;
   10413                 :       46675 :   enum tree_code cond_code;
   10414                 :       46675 :   gimple_seq stmts;
   10415                 :             : 
   10416                 :       46675 :   cond_code = fd->loop.cond_code;
   10417                 :       46675 :   cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
   10418                 :             : 
   10419                 :             :   /* When possible, use a strict equality expression.  This can let VRP
   10420                 :             :      type optimizations deduce the value and remove a copy.  */
   10421                 :       46675 :   if (tree_fits_shwi_p (fd->loop.step))
   10422                 :             :     {
   10423                 :       44413 :       HOST_WIDE_INT step = tree_to_shwi (fd->loop.step);
   10424                 :       44413 :       if (step == 1 || step == -1)
   10425                 :       46675 :         cond_code = EQ_EXPR;
   10426                 :             :     }
   10427                 :             : 
   10428                 :       46675 :   tree n2 = fd->loop.n2;
   10429                 :       46675 :   if (fd->collapse > 1
   10430                 :       11078 :       && TREE_CODE (n2) != INTEGER_CST
   10431                 :       52694 :       && gimple_omp_for_combined_into_p (fd->for_stmt))
   10432                 :             :     {
   10433                 :        2623 :       struct omp_context *taskreg_ctx = NULL;
   10434                 :        2623 :       if (gimple_code (ctx->outer->stmt) == GIMPLE_OMP_FOR)
   10435                 :             :         {
   10436                 :        1213 :           gomp_for *gfor = as_a <gomp_for *> (ctx->outer->stmt);
   10437                 :        1213 :           if (gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_FOR
   10438                 :        1213 :               || gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_DISTRIBUTE)
   10439                 :             :             {
   10440                 :        1191 :               if (gimple_omp_for_combined_into_p (gfor))
   10441                 :             :                 {
   10442                 :         667 :                   gcc_assert (ctx->outer->outer
   10443                 :             :                               && is_parallel_ctx (ctx->outer->outer));
   10444                 :             :                   taskreg_ctx = ctx->outer->outer;
   10445                 :             :                 }
   10446                 :             :               else
   10447                 :             :                 {
   10448                 :         524 :                   struct omp_for_data outer_fd;
   10449                 :         524 :                   omp_extract_for_data (gfor, &outer_fd, NULL);
   10450                 :         524 :                   n2 = fold_convert (TREE_TYPE (n2), outer_fd.loop.n2);
   10451                 :             :                 }
   10452                 :             :             }
   10453                 :          22 :           else if (gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_TASKLOOP)
   10454                 :          22 :             taskreg_ctx = ctx->outer->outer;
   10455                 :             :         }
   10456                 :        1410 :       else if (is_taskreg_ctx (ctx->outer))
   10457                 :             :         taskreg_ctx = ctx->outer;
   10458                 :        2623 :       if (taskreg_ctx)
   10459                 :             :         {
   10460                 :        2099 :           int i;
   10461                 :        2099 :           tree taskreg_clauses
   10462                 :        2099 :             = gimple_omp_taskreg_clauses (taskreg_ctx->stmt);
   10463                 :        2099 :           tree innerc = omp_find_clause (taskreg_clauses,
   10464                 :             :                                          OMP_CLAUSE__LOOPTEMP_);
   10465                 :        2099 :           gcc_assert (innerc);
   10466                 :        2099 :           int count = fd->collapse;
   10467                 :        2099 :           if (fd->non_rect
   10468                 :          24 :               && fd->last_nonrect == fd->first_nonrect + 1)
   10469                 :          12 :             if (tree v = gimple_omp_for_index (fd->for_stmt, fd->last_nonrect))
   10470                 :          12 :               if (!TYPE_UNSIGNED (TREE_TYPE (v)))
   10471                 :          12 :                 count += 4;
   10472                 :        8359 :           for (i = 0; i < count; i++)
   10473                 :             :             {
   10474                 :        6260 :               innerc = omp_find_clause (OMP_CLAUSE_CHAIN (innerc),
   10475                 :             :                                         OMP_CLAUSE__LOOPTEMP_);
   10476                 :        6260 :               gcc_assert (innerc);
   10477                 :             :             }
   10478                 :        2099 :           innerc = omp_find_clause (OMP_CLAUSE_CHAIN (innerc),
   10479                 :             :                                     OMP_CLAUSE__LOOPTEMP_);
   10480                 :        2099 :           if (innerc)
   10481                 :        1411 :             n2 = fold_convert (TREE_TYPE (n2),
   10482                 :             :                                lookup_decl (OMP_CLAUSE_DECL (innerc),
   10483                 :             :                                             taskreg_ctx));
   10484                 :             :         }
   10485                 :             :     }
   10486                 :       46675 :   cond = build2 (cond_code, boolean_type_node, fd->loop.v, n2);
   10487                 :             : 
   10488                 :       46675 :   clauses = gimple_omp_for_clauses (fd->for_stmt);
   10489                 :       46675 :   stmts = NULL;
   10490                 :       46675 :   lower_lastprivate_clauses (clauses, cond, body_p, &stmts, clist, ctx);
   10491                 :       46675 :   if (!gimple_seq_empty_p (stmts))
   10492                 :             :     {
   10493                 :       17102 :       gimple_seq_add_seq (&stmts, *dlist);
   10494                 :       17102 :       *dlist = stmts;
   10495                 :             : 
   10496                 :             :       /* Optimize: v = 0; is usually cheaper than v = some_other_constant.  */
   10497                 :       17102 :       vinit = fd->loop.n1;
   10498                 :       17102 :       if (cond_code == EQ_EXPR
   10499                 :       15147 :           && tree_fits_shwi_p (fd->loop.n2)
   10500                 :       27437 :           && ! integer_zerop (fd->loop.n2))
   10501                 :        9119 :         vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
   10502                 :             :       else
   10503                 :        7983 :         vinit = unshare_expr (vinit);
   10504                 :             : 
   10505                 :             :       /* Initialize the iterator variable, so that threads that don't execute
   10506                 :             :          any iterations don't execute the lastprivate clauses by accident.  */
   10507                 :       17102 :       gimplify_assign (fd->loop.v, vinit, body_p);
   10508                 :             :     }
   10509                 :       46675 : }
   10510                 :             : 
   10511                 :             : /* OpenACC privatization.
   10512                 :             : 
   10513                 :             :    Or, in other words, *sharing* at the respective OpenACC level of
   10514                 :             :    parallelism.
   10515                 :             : 
   10516                 :             :    From a correctness perspective, a non-addressable variable can't be accessed
   10517                 :             :    outside the current thread, so it can go in a (faster than shared memory)
   10518                 :             :    register -- though that register may need to be broadcast in some
   10519                 :             :    circumstances.  A variable can only meaningfully be "shared" across workers
   10520                 :             :    or vector lanes if its address is taken, e.g. by a call to an atomic
   10521                 :             :    builtin.
   10522                 :             : 
   10523                 :             :    From an optimisation perspective, the answer might be fuzzier: maybe
   10524                 :             :    sometimes, using shared memory directly would be faster than
   10525                 :             :    broadcasting.  */
   10526                 :             : 
   10527                 :             : static void
   10528                 :       18966 : oacc_privatization_begin_diagnose_var (const dump_flags_t l_dump_flags,
   10529                 :             :                                        const location_t loc, const tree c,
   10530                 :             :                                        const tree decl)
   10531                 :             : {
   10532                 :       18966 :   const dump_user_location_t d_u_loc
   10533                 :       18966 :     = dump_user_location_t::from_location_t (loc);
   10534                 :             : /* PR100695 "Format decoder, quoting in 'dump_printf' etc." */
   10535                 :             : #if __GNUC__ >= 10
   10536                 :       18966 : # pragma GCC diagnostic push
   10537                 :       18966 : # pragma GCC diagnostic ignored "-Wformat"
   10538                 :             : #endif
   10539                 :       18966 :   dump_printf_loc (l_dump_flags, d_u_loc,
   10540                 :             :                    "variable %<%T%> ", decl);
   10541                 :             : #if __GNUC__ >= 10
   10542                 :       18966 : # pragma GCC diagnostic pop
   10543                 :             : #endif
   10544                 :       18966 :   if (c)
   10545                 :        2812 :     dump_printf (l_dump_flags,
   10546                 :             :                  "in %qs clause ",
   10547                 :        2812 :                  omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
   10548                 :             :   else
   10549                 :       16154 :     dump_printf (l_dump_flags,
   10550                 :             :                  "declared in block ");
   10551                 :       18966 : }
   10552                 :             : 
   10553                 :             : static bool
   10554                 :       39979 : oacc_privatization_candidate_p (const location_t loc, const tree c,
   10555                 :             :                                 const tree decl)
   10556                 :             : {
   10557                 :       39979 :   dump_flags_t l_dump_flags = get_openacc_privatization_dump_flags ();
   10558                 :             : 
   10559                 :             :   /* There is some differentiation depending on block vs. clause.  */
   10560                 :       39979 :   bool block = !c;
   10561                 :             : 
   10562                 :       39979 :   bool res = true;
   10563                 :             : 
   10564                 :       39979 :   if (res && !VAR_P (decl))
   10565                 :             :     {
   10566                 :             :       /* A PARM_DECL (appearing in a 'private' clause) is expected to have been
   10567                 :             :          privatized into a new VAR_DECL.  */
   10568                 :         588 :       gcc_checking_assert (TREE_CODE (decl) != PARM_DECL);
   10569                 :             : 
   10570                 :         588 :       res = false;
   10571                 :             : 
   10572                 :         588 :       if (dump_enabled_p ())
   10573                 :             :         {
   10574                 :         577 :           oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
   10575                 :         577 :           dump_printf (l_dump_flags,
   10576                 :             :                        "potentially has improper OpenACC privatization level: %qs\n",
   10577                 :         577 :                        get_tree_code_name (TREE_CODE (decl)));
   10578                 :             :         }
   10579                 :             :     }
   10580                 :             : 
   10581                 :       39979 :   if (res && block && TREE_STATIC (decl))
   10582                 :             :     {
   10583                 :          37 :       res = false;
   10584                 :             : 
   10585                 :          37 :       if (dump_enabled_p ())
   10586                 :             :         {
   10587                 :          31 :           oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
   10588                 :          31 :           dump_printf (l_dump_flags,
   10589                 :             :                        "isn%'t candidate for adjusting OpenACC privatization level: %s\n",
   10590                 :             :                        "static");
   10591                 :             :         }
   10592                 :             :     }
   10593                 :             : 
   10594                 :       39979 :   if (res && block && DECL_EXTERNAL (decl))
   10595                 :             :     {
   10596                 :          15 :       res = false;
   10597                 :             : 
   10598                 :          15 :       if (dump_enabled_p ())
   10599                 :             :         {
   10600                 :          15 :           oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
   10601                 :          15 :           dump_printf (l_dump_flags,
   10602                 :             :                        "isn%'t candidate for adjusting OpenACC privatization level: %s\n",
   10603                 :             :                        "external");
   10604                 :             :         }
   10605                 :             :     }
   10606                 :             : 
   10607                 :       39979 :   if (res && !TREE_ADDRESSABLE (decl))
   10608                 :             :     {
   10609                 :       38204 :       res = false;
   10610                 :             : 
   10611                 :       38204 :       if (dump_enabled_p ())
   10612                 :             :         {
   10613                 :       17478 :           oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
   10614                 :       17478 :           dump_printf (l_dump_flags,
   10615                 :             :                        "isn%'t candidate for adjusting OpenACC privatization level: %s\n",
   10616                 :             :                        "not addressable");
   10617                 :             :         }
   10618                 :             :     }
   10619                 :             : 
   10620                 :             :   /* If an artificial variable has been added to a bind, e.g.
   10621                 :             :      a compiler-generated temporary structure used by the Fortran front-end, do
   10622                 :             :      not consider it as a privatization candidate.  Note that variables on
   10623                 :             :      the stack are private per-thread by default: making them "gang-private"
   10624                 :             :      for OpenACC actually means to share a single instance of a variable
   10625                 :             :      amongst all workers and threads spawned within each gang.
   10626                 :             :      At present, no compiler-generated artificial variables require such
   10627                 :             :      sharing semantics, so this is safe.  */
   10628                 :             : 
   10629                 :       39979 :   if (res && block && DECL_ARTIFICIAL (decl))
   10630                 :             :     {
   10631                 :         547 :       res = false;
   10632                 :             : 
   10633                 :         547 :       if (dump_enabled_p ())
   10634                 :             :         {
   10635                 :         360 :           oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
   10636                 :         360 :           dump_printf (l_dump_flags,
   10637                 :             :                        "isn%'t candidate for adjusting OpenACC privatization "
   10638                 :             :                        "level: %s\n", "artificial");
   10639                 :             :         }
   10640                 :             :     }
   10641                 :             : 
   10642                 :       39792 :   if (res)
   10643                 :             :     {
   10644                 :         588 :       if (dump_enabled_p ())
   10645                 :             :         {
   10646                 :         505 :           oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
   10647                 :         505 :           dump_printf (l_dump_flags,
   10648                 :             :                        "is candidate for adjusting OpenACC privatization level\n");
   10649                 :             :         }
   10650                 :             :     }
   10651                 :             : 
   10652                 :       39979 :   if (dump_file && (dump_flags & TDF_DETAILS))
   10653                 :             :     {
   10654                 :           0 :       print_generic_decl (dump_file, decl, dump_flags);
   10655                 :           0 :       fprintf (dump_file, "\n");
   10656                 :             :     }
   10657                 :             : 
   10658                 :       39979 :   return res;
   10659                 :             : }
   10660                 :             : 
   10661                 :             : /* Scan CLAUSES for candidates for adjusting OpenACC privatization level in
   10662                 :             :    CTX.  */
   10663                 :             : 
   10664                 :             : static void
   10665                 :       10589 : oacc_privatization_scan_clause_chain (omp_context *ctx, tree clauses)
   10666                 :             : {
   10667                 :       32950 :   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   10668                 :       22361 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE)
   10669                 :             :       {
   10670                 :       12212 :         tree decl = OMP_CLAUSE_DECL (c);
   10671                 :             : 
   10672                 :       12212 :         tree new_decl = lookup_decl (decl, ctx);
   10673                 :             : 
   10674                 :       12212 :         if (!oacc_privatization_candidate_p (OMP_CLAUSE_LOCATION (c), c,
   10675                 :             :                                              new_decl))
   10676                 :       11863 :           continue;
   10677                 :             : 
   10678                 :         349 :         gcc_checking_assert
   10679                 :             :           (!ctx->oacc_privatization_candidates.contains (new_decl));
   10680                 :         349 :         ctx->oacc_privatization_candidates.safe_push (new_decl);
   10681                 :             :       }
   10682                 :       10589 : }
   10683                 :             : 
   10684                 :             : /* Scan DECLS for candidates for adjusting OpenACC privatization level in
   10685                 :             :    CTX.  */
   10686                 :             : 
   10687                 :             : static void
   10688                 :       22459 : oacc_privatization_scan_decl_chain (omp_context *ctx, tree decls)
   10689                 :             : {
   10690                 :       50226 :   for (tree decl = decls; decl; decl = DECL_CHAIN (decl))
   10691                 :             :     {
   10692                 :       27767 :       tree new_decl = lookup_decl (decl, ctx);
   10693                 :       27767 :       gcc_checking_assert (new_decl == decl);
   10694                 :             : 
   10695                 :       27767 :       if (!oacc_privatization_candidate_p (gimple_location (ctx->stmt), NULL,
   10696                 :             :                                            new_decl))
   10697                 :       27528 :         continue;
   10698                 :             : 
   10699                 :         239 :       gcc_checking_assert
   10700                 :             :         (!ctx->oacc_privatization_candidates.contains (new_decl));
   10701                 :         239 :       ctx->oacc_privatization_candidates.safe_push (new_decl);
   10702                 :             :     }
   10703                 :       22459 : }
   10704                 :             : 
   10705                 :             : /* Callback for walk_gimple_seq.  Find #pragma omp scan statement.  */
   10706                 :             : 
   10707                 :             : static tree
   10708                 :        2255 : omp_find_scan (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
   10709                 :             :                struct walk_stmt_info *wi)
   10710                 :             : {
   10711                 :        2255 :   gimple *stmt = gsi_stmt (*gsi_p);
   10712                 :             : 
   10713                 :        2255 :   *handled_ops_p = true;
   10714                 :        2255 :   switch (gimple_code (stmt))
   10715                 :             :     {
   10716                 :         426 :     WALK_SUBSTMTS;
   10717                 :             : 
   10718                 :         168 :     case GIMPLE_OMP_FOR:
   10719                 :         168 :       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD
   10720                 :         168 :           && gimple_omp_for_combined_into_p (stmt))
   10721                 :         168 :         *handled_ops_p = false;
   10722                 :             :       break;
   10723                 :             : 
   10724                 :         688 :     case GIMPLE_OMP_SCAN:
   10725                 :         688 :       *(gimple_stmt_iterator *) (wi->info) = *gsi_p;
   10726                 :         688 :       return integer_zero_node;
   10727                 :             :     default:
   10728                 :             :       break;
   10729                 :             :     }
   10730                 :             :   return NULL;
   10731                 :             : }
   10732                 :             : 
   10733                 :             : /* Helper function for lower_omp_for, add transformations for a worksharing
   10734                 :             :    loop with scan directives inside of it.
   10735                 :             :    For worksharing loop not combined with simd, transform:
   10736                 :             :    #pragma omp for reduction(inscan,+:r) private(i)
   10737                 :             :    for (i = 0; i < n; i = i + 1)
   10738                 :             :      {
   10739                 :             :        {
   10740                 :             :          update (r);
   10741                 :             :        }
   10742                 :             :        #pragma omp scan inclusive(r)
   10743                 :             :        {
   10744                 :             :          use (r);
   10745                 :             :        }
   10746                 :             :      }
   10747                 :             : 
   10748                 :             :    into two worksharing loops + code to merge results:
   10749                 :             : 
   10750                 :             :    num_threads = omp_get_num_threads ();
   10751                 :             :    thread_num = omp_get_thread_num ();
   10752                 :             :    if (thread_num == 0) goto <D.2099>; else goto <D.2100>;
   10753                 :             :    <D.2099>:
   10754                 :             :    var2 = r;
   10755                 :             :    goto <D.2101>;
   10756                 :             :    <D.2100>:
   10757                 :             :    // For UDRs this is UDR init, or if ctors are needed, copy from
   10758                 :             :    // var3 that has been constructed to contain the neutral element.
   10759                 :             :    var2 = 0;
   10760                 :             :    <D.2101>:
   10761                 :             :    ivar = 0;
   10762                 :             :    // The _scantemp_ clauses will arrange for rpriva to be initialized to
   10763                 :             :    // a shared array with num_threads elements and rprivb to a local array
   10764                 :             :    // number of elements equal to the number of (contiguous) iterations the
   10765                 :             :    // current thread will perform.  controlb and controlp variables are
   10766                 :             :    // temporaries to handle deallocation of rprivb at the end of second
   10767                 :             :    // GOMP_FOR.
   10768                 :             :    #pragma omp for _scantemp_(rpriva) _scantemp_(rprivb) _scantemp_(controlb) \
   10769                 :             :      _scantemp_(controlp) reduction(inscan,+:r) private(i) nowait
   10770                 :             :    for (i = 0; i < n; i = i + 1)
   10771                 :             :      {
   10772                 :             :        {
   10773                 :             :          // For UDRs this is UDR init or copy from var3.
   10774                 :             :          r = 0;
   10775                 :             :          // This is the input phase from user code.
   10776                 :             :          update (r);
   10777                 :             :        }
   10778                 :             :        {
   10779                 :             :          // For UDRs this is UDR merge.
   10780                 :             :          var2 = var2 + r;
   10781                 :             :          // Rather than handing it over to the user, save to local thread's
   10782                 :             :          // array.
   10783                 :             :          rprivb[ivar] = var2;
   10784                 :             :          // For exclusive scan, the above two statements are swapped.
   10785                 :             :          ivar = ivar + 1;
   10786                 :             :        }
   10787                 :             :      }
   10788                 :             :    // And remember the final value from this thread's into the shared
   10789                 :             :    // rpriva array.
   10790                 :             :    rpriva[(sizetype) thread_num] = var2;
   10791                 :             :    // If more than one thread, compute using Work-Efficient prefix sum
   10792                 :             :    // the inclusive parallel scan of the rpriva array.
   10793                 :             :    if (num_threads > 1) goto <D.2102>; else goto <D.2103>;
   10794                 :             :    <D.2102>:
   10795                 :             :    GOMP_barrier ();
   10796                 :             :    down = 0;
   10797                 :             :    k = 1;
   10798                 :             :    num_threadsu = (unsigned int) num_threads;
   10799                 :             :    thread_numup1 = (unsigned int) thread_num + 1;
   10800                 :             :    <D.2108>:
   10801                 :             :    twok = k << 1;
   10802                 :             :    if (twok > num_threadsu) goto <D.2110>; else goto <D.2111>;
   10803                 :             :    <D.2110>:
   10804                 :             :    down = 4294967295;
   10805                 :             :    k = k >> 1;
   10806                 :             :    if (k == num_threadsu) goto <D.2112>; else goto <D.2111>;
   10807                 :             :    <D.2112>:
   10808                 :             :    k = k >> 1;
   10809                 :             :    <D.2111>:
   10810                 :             :    twok = k << 1;
   10811                 :             :    cplx = .MUL_OVERFLOW (thread_nump1, twok);
   10812                 :             :    mul = REALPART_EXPR <cplx>;
   10813                 :             :    ovf = IMAGPART_EXPR <cplx>;
   10814                 :             :    if (ovf == 0) goto <D.2116>; else goto <D.2117>;
   10815                 :             :    <D.2116>:
   10816                 :             :    andv = k & down;
   10817                 :             :    andvm1 = andv + 4294967295;
   10818                 :             :    l = mul + andvm1;
   10819                 :             :    if (l < num_threadsu) goto <D.2120>; else goto <D.2117>;
   10820                 :             :    <D.2120>:
   10821                 :             :    // For UDRs this is UDR merge, performed using var2 variable as temporary,
   10822                 :             :    // i.e. var2 = rpriva[l - k]; UDR merge (var2, rpriva[l]); rpriva[l] = var2;
   10823                 :             :    rpriva[l] = rpriva[l - k] + rpriva[l];
   10824                 :             :    <D.2117>:
   10825                 :             :    if (down == 0) goto <D.2121>; else goto <D.2122>;
   10826                 :             :    <D.2121>:
   10827                 :             :    k = k << 1;
   10828                 :             :    goto <D.2123>;
   10829                 :             :    <D.2122>:
   10830                 :             :    k = k >> 1;
   10831                 :             :    <D.2123>:
   10832                 :             :    GOMP_barrier ();
   10833                 :             :    if (k != 0) goto <D.2108>; else goto <D.2103>;
   10834                 :             :    <D.2103>:
   10835                 :             :    if (thread_num == 0) goto <D.2124>; else goto <D.2125>;
   10836                 :             :    <D.2124>:
   10837                 :             :    // For UDRs this is UDR init or copy from var3.
   10838                 :             :    var2 = 0;
   10839                 :             :    goto <D.2126>;
   10840                 :             :    <D.2125>:
   10841                 :             :    var2 = rpriva[thread_num - 1];
   10842                 :             :    <D.2126>:
   10843                 :             :    ivar = 0;
   10844                 :             :    #pragma omp for _scantemp_(controlb) _scantemp_(controlp) \
   10845                 :             :      reduction(inscan,+:r) private(i)
   10846                 :             :    for (i = 0; i < n; i = i + 1)
   10847                 :             :      {
   10848                 :             :        {
   10849                 :             :          // For UDRs, this is r = var2; UDR merge (r, rprivb[ivar]);
   10850                 :             :          r = var2 + rprivb[ivar];
   10851                 :             :        }
   10852                 :             :        {
   10853                 :             :          // This is the scan phase from user code.
   10854                 :             :          use (r);
   10855                 :             :          // Plus a bump of the iterator.
   10856                 :             :          ivar = ivar + 1;
   10857                 :             :        }
   10858                 :             :      }  */
   10859                 :             : 
   10860                 :             : static void
   10861                 :         176 : lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
   10862                 :             :                     struct omp_for_data *fd, omp_context *ctx)
   10863                 :             : {
   10864                 :         176 :   bool is_for_simd = gimple_omp_for_combined_p (stmt);
   10865                 :         176 :   gcc_assert (ctx->scan_inclusive || ctx->scan_exclusive);
   10866                 :             : 
   10867                 :         176 :   gimple_seq body = gimple_omp_body (stmt);
   10868                 :         176 :   gimple_stmt_iterator input1_gsi = gsi_none ();
   10869                 :         176 :   struct walk_stmt_info wi;
   10870                 :         176 :   memset (&wi, 0, sizeof (wi));
   10871                 :         176 :   wi.val_only = true;
   10872                 :         176 :   wi.info = (void *) &input1_gsi;
   10873                 :         176 :   walk_gimple_seq_mod (&body, omp_find_scan, NULL, &wi);
   10874                 :         176 :   gcc_assert (!gsi_end_p (input1_gsi));
   10875                 :             : 
   10876                 :         176 :   gimple *input_stmt1 = gsi_stmt (input1_gsi);
   10877                 :         176 :   gimple_stmt_iterator gsi = input1_gsi;
   10878                 :         176 :   gsi_next (&gsi);
   10879                 :         176 :   gimple_stmt_iterator scan1_gsi = gsi;
   10880                 :         176 :   gimple *scan_stmt1 = gsi_stmt (gsi);
   10881                 :         176 :   gcc_assert (scan_stmt1 && gimple_code (scan_stmt1) == GIMPLE_OMP_SCAN);
   10882                 :             : 
   10883                 :         176 :   gimple_seq input_body = gimple_omp_body (input_stmt1);
   10884                 :         176 :   gimple_seq scan_body = gimple_omp_body (scan_stmt1);
   10885                 :         176 :   gimple_omp_set_body (input_stmt1, NULL);
   10886                 :         176 :   gimple_omp_set_body (scan_stmt1, NULL);
   10887                 :         176 :   gimple_omp_set_body (stmt, NULL);
   10888                 :             : 
   10889                 :         176 :   gomp_for *new_stmt = as_a <gomp_for *> (gimple_copy (stmt));
   10890                 :         176 :   gimple_seq new_body = copy_gimple_seq_and_replace_locals (body);
   10891                 :         176 :   gimple_omp_set_body (stmt, body);
   10892                 :         176 :   gimple_omp_set_body (input_stmt1, input_body);
   10893                 :             : 
   10894                 :         176 :   gimple_stmt_iterator input2_gsi = gsi_none ();
   10895                 :         176 :   memset (&wi, 0, sizeof (wi));
   10896                 :         176 :   wi.val_only = true;
   10897                 :         176 :   wi.info = (void *) &input2_gsi;
   10898                 :         176 :   walk_gimple_seq_mod (&new_body, omp_find_scan, NULL, &wi);
   10899                 :         176 :   gcc_assert (!gsi_end_p (input2_gsi));
   10900                 :             : 
   10901                 :         176 :   gimple *input_stmt2 = gsi_stmt (input2_gsi);
   10902                 :         176 :   gsi = input2_gsi;
   10903                 :         176 :   gsi_next (&gsi);
   10904                 :         176 :   gimple_stmt_iterator scan2_gsi = gsi;
   10905                 :         176 :   gimple *scan_stmt2 = gsi_stmt (gsi);
   10906                 :         176 :   gcc_assert (scan_stmt2 && gimple_code (scan_stmt2) == GIMPLE_OMP_SCAN);
   10907                 :         176 :   gimple_omp_set_body (scan_stmt2, scan_body);
   10908                 :             : 
   10909                 :         176 :   gimple_stmt_iterator input3_gsi = gsi_none ();
   10910                 :         176 :   gimple_stmt_iterator scan3_gsi = gsi_none ();
   10911                 :         176 :   gimple_stmt_iterator input4_gsi = gsi_none ();
   10912                 :         176 :   gimple_stmt_iterator scan4_gsi = gsi_none ();
   10913                 :         176 :   gimple *input_stmt3 = NULL, *scan_stmt3 = NULL;
   10914                 :         176 :   gimple *input_stmt4 = NULL, *scan_stmt4 = NULL;
   10915                 :         176 :   omp_context *input_simd_ctx = NULL, *scan_simd_ctx = NULL;
   10916                 :         176 :   if (is_for_simd)
   10917                 :             :     {
   10918                 :          84 :       memset (&wi, 0, sizeof (wi));
   10919                 :          84 :       wi.val_only = true;
   10920                 :          84 :       wi.info = (void *) &input3_gsi;
   10921                 :          84 :       walk_gimple_seq_mod (&input_body, omp_find_scan, NULL, &wi);
   10922                 :          84 :       gcc_assert (!gsi_end_p (input3_gsi));
   10923                 :             : 
   10924                 :          84 :       input_stmt3 = gsi_stmt (input3_gsi);
   10925                 :          84 :       gsi = input3_gsi;
   10926                 :          84 :       gsi_next (&gsi);
   10927                 :          84 :       scan3_gsi = gsi;
   10928                 :          84 :       scan_stmt3 = gsi_stmt (gsi);
   10929                 :          84 :       gcc_assert (scan_stmt3 && gimple_code (scan_stmt3) == GIMPLE_OMP_SCAN);
   10930                 :             : 
   10931                 :          84 :       memset (&wi, 0, sizeof (wi));
   10932                 :          84 :       wi.val_only = true;
   10933                 :          84 :       wi.info = (void *) &input4_gsi;
   10934                 :          84 :       walk_gimple_seq_mod (&scan_body, omp_find_scan, NULL, &wi);
   10935                 :          84 :       gcc_assert (!gsi_end_p (input4_gsi));
   10936                 :             : 
   10937                 :          84 :       input_stmt4 = gsi_stmt (input4_gsi);
   10938                 :          84 :       gsi = input4_gsi;
   10939                 :          84 :       gsi_next (&gsi);
   10940                 :          84 :       scan4_gsi = gsi;
   10941                 :          84 :       scan_stmt4 = gsi_stmt (gsi);
   10942                 :          84 :       gcc_assert (scan_stmt4 && gimple_code (scan_stmt4) == GIMPLE_OMP_SCAN);
   10943                 :             : 
   10944                 :          84 :       input_simd_ctx = maybe_lookup_ctx (input_stmt3)->outer;
   10945                 :          84 :       scan_simd_ctx = maybe_lookup_ctx (input_stmt4)->outer;
   10946                 :             :     }
   10947                 :             : 
   10948                 :         176 :   tree num_threads = create_tmp_var (integer_type_node);
   10949                 :         176 :   tree thread_num = create_tmp_var (integer_type_node);
   10950                 :         176 :   tree nthreads_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
   10951                 :         176 :   tree threadnum_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
   10952                 :         176 :   gimple *g = gimple_build_call (nthreads_decl, 0);
   10953                 :         176 :   gimple_call_set_lhs (g, num_threads);
   10954                 :         176 :   gimple_seq_add_stmt (body_p, g);
   10955                 :         176 :   g = gimple_build_call (threadnum_decl, 0);
   10956                 :         176 :   gimple_call_set_lhs (g, thread_num);
   10957                 :         176 :   gimple_seq_add_stmt (body_p, g);
   10958                 :             : 
   10959                 :         176 :   tree ivar = create_tmp_var (sizetype);
   10960                 :         176 :   tree new_clauses1 = NULL_TREE, new_clauses2 = NULL_TREE;
   10961                 :         176 :   tree *cp1 = &new_clauses1, *cp2 = &new_clauses2;
   10962                 :         176 :   tree k = create_tmp_var (unsigned_type_node);
   10963                 :         176 :   tree l = create_tmp_var (unsigned_type_node);
   10964                 :             : 
   10965                 :         176 :   gimple_seq clist = NULL, mdlist = NULL;
   10966                 :         176 :   gimple_seq thr01_list = NULL, thrn1_list = NULL;
   10967                 :         176 :   gimple_seq thr02_list = NULL, thrn2_list = NULL;
   10968                 :         176 :   gimple_seq scan1_list = NULL, input2_list = NULL;
   10969                 :         176 :   gimple_seq last_list = NULL, reduc_list = NULL;
   10970                 :         683 :   for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
   10971                 :         507 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   10972                 :         507 :         && OMP_CLAUSE_REDUCTION_INSCAN (c))
   10973                 :             :       {
   10974                 :         208 :         location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   10975                 :         208 :         tree var = OMP_CLAUSE_DECL (c);
   10976                 :         208 :         tree new_var = lookup_decl (var, ctx);
   10977                 :         208 :         tree var3 = NULL_TREE;
   10978                 :         208 :         tree new_vard = new_var;
   10979                 :         208 :         if (omp_privatize_by_reference (var))
   10980                 :          48 :           new_var = build_simple_mem_ref_loc (clause_loc, new_var);
   10981                 :         208 :         if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   10982                 :             :           {
   10983                 :          64 :             var3 = maybe_lookup_decl (new_vard, ctx);
   10984                 :          64 :             if (var3 == new_vard)
   10985                 :         176 :               var3 = NULL_TREE;
   10986                 :             :           }
   10987                 :             : 
   10988                 :         208 :         tree ptype = build_pointer_type (TREE_TYPE (new_var));
   10989                 :         208 :         tree rpriva = create_tmp_var (ptype);
   10990                 :         208 :         tree nc = build_omp_clause (clause_loc, OMP_CLAUSE__SCANTEMP_);
   10991                 :         208 :         OMP_CLAUSE_DECL (nc) = rpriva;
   10992                 :         208 :         *cp1 = nc;
   10993                 :         208 :         cp1 = &OMP_CLAUSE_CHAIN (nc);
   10994                 :             : 
   10995                 :         208 :         tree rprivb = create_tmp_var (ptype);
   10996                 :         208 :         nc = build_omp_clause (clause_loc, OMP_CLAUSE__SCANTEMP_);
   10997                 :         208 :         OMP_CLAUSE_DECL (nc) = rprivb;
   10998                 :         208 :         OMP_CLAUSE__SCANTEMP__ALLOC (nc) = 1;
   10999                 :         208 :         *cp1 = nc;
   11000                 :         208 :         cp1 = &OMP_CLAUSE_CHAIN (nc);
   11001                 :             : 
   11002                 :         208 :         tree var2 = create_tmp_var_raw (TREE_TYPE (new_var));
   11003                 :         208 :         if (new_vard != new_var)
   11004                 :          48 :           TREE_ADDRESSABLE (var2) = 1;
   11005                 :         208 :         gimple_add_tmp_var (var2);
   11006                 :             : 
   11007                 :         208 :         tree x = fold_convert_loc (clause_loc, sizetype, thread_num);
   11008                 :         208 :         x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, x,
   11009                 :         208 :                              TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
   11010                 :         208 :         x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rpriva), rpriva, x);
   11011                 :         208 :         tree rpriva_ref = build_simple_mem_ref_loc (clause_loc, x);
   11012                 :             : 
   11013                 :         208 :         x = fold_build2_loc (clause_loc, PLUS_EXPR, integer_type_node,
   11014                 :             :                              thread_num, integer_minus_one_node);
   11015                 :         208 :         x = fold_convert_loc (clause_loc, sizetype, x);
   11016                 :         208 :         x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, x,
   11017                 :         208 :                              TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
   11018                 :         208 :         x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rpriva), rpriva, x);
   11019                 :         208 :         tree rprivam1_ref = build_simple_mem_ref_loc (clause_loc, x);
   11020                 :             : 
   11021                 :         208 :         x = fold_convert_loc (clause_loc, sizetype, l);
   11022                 :         208 :         x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, x,
   11023                 :         208 :                              TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
   11024                 :         208 :         x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rpriva), rpriva, x);
   11025                 :         208 :         tree rprival_ref = build_simple_mem_ref_loc (clause_loc, x);
   11026                 :             : 
   11027                 :         208 :         x = fold_build2_loc (clause_loc, MINUS_EXPR, unsigned_type_node, l, k);
   11028                 :         208 :         x = fold_convert_loc (clause_loc, sizetype, x);
   11029                 :         208 :         x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, x,
   11030                 :         208 :                              TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
   11031                 :         208 :         x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rpriva), rpriva, x);
   11032                 :         208 :         tree rprivalmk_ref = build_simple_mem_ref_loc (clause_loc, x);
   11033                 :             : 
   11034                 :         208 :         x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, ivar,
   11035                 :         208 :                              TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
   11036                 :         208 :         x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rprivb), rprivb, x);
   11037                 :         208 :         tree rprivb_ref = build_simple_mem_ref_loc (clause_loc, x);
   11038                 :             : 
   11039                 :         208 :         tree var4 = is_for_simd ? new_var : var2;
   11040                 :         100 :         tree var5 = NULL_TREE, var6 = NULL_TREE;
   11041                 :         100 :         if (is_for_simd)
   11042                 :             :           {
   11043                 :         100 :             var5 = lookup_decl (var, input_simd_ctx);
   11044                 :         100 :             var6 = lookup_decl (var, scan_simd_ctx);
   11045                 :         100 :             if (new_vard != new_var)
   11046                 :             :               {
   11047                 :          24 :                 var5 = build_simple_mem_ref_loc (clause_loc, var5);
   11048                 :          24 :                 var6 = build_simple_mem_ref_loc (clause_loc, var6);
   11049                 :             :               }
   11050                 :             :           }
   11051                 :         208 :         if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   11052                 :             :           {
   11053                 :          64 :             tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
   11054                 :          64 :             tree val = var2;
   11055                 :             : 
   11056                 :          64 :             x = lang_hooks.decls.omp_clause_default_ctor
   11057                 :          64 :                     (c, var2, build_outer_var_ref (var, ctx));
   11058                 :          64 :             if (x)
   11059                 :          32 :               gimplify_and_add (x, &clist);
   11060                 :             : 
   11061                 :          64 :             x = build_outer_var_ref (var, ctx);
   11062                 :          64 :             x = lang_hooks.decls.omp_clause_assign_op (c, unshare_expr (var4),
   11063                 :             :                                                        x);
   11064                 :          64 :             gimplify_and_add (x, &thr01_list);
   11065                 :             : 
   11066                 :          64 :             tree y = (DECL_HAS_VALUE_EXPR_P (new_vard)
   11067                 :          64 :                       ? DECL_VALUE_EXPR (new_vard) : NULL_TREE);
   11068                 :          64 :             if (var3)
   11069                 :             :               {
   11070                 :          32 :                 x = unshare_expr (var4);
   11071                 :          32 :                 x = lang_hooks.decls.omp_clause_assign_op (c, x, var3);
   11072                 :          32 :                 gimplify_and_add (x, &thrn1_list);
   11073                 :          32 :                 x = unshare_expr (var4);
   11074                 :          32 :                 x = lang_hooks.decls.omp_clause_assign_op (c, x, var3);
   11075                 :          32 :                 gimplify_and_add (x, &thr02_list);
   11076                 :             :               }
   11077                 :          32 :             else if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
   11078                 :             :               {
   11079                 :             :                 /* Otherwise, assign to it the identity element.  */
   11080                 :          32 :                 gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
   11081                 :          32 :                 tseq = copy_gimple_seq_and_replace_locals (tseq);
   11082                 :          32 :                 if (!is_for_simd)
   11083                 :             :                   {
   11084                 :          16 :                     if (new_vard != new_var)
   11085                 :           8 :                       val = build_fold_addr_expr_loc (clause_loc, val);
   11086                 :          16 :                     SET_DECL_VALUE_EXPR (new_vard, val);
   11087                 :          16 :                     DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
   11088                 :             :                   }
   11089                 :          32 :                 SET_DECL_VALUE_EXPR (placeholder, error_mark_node);
   11090                 :          32 :                 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
   11091                 :          32 :                 lower_omp (&tseq, ctx);
   11092                 :          32 :                 gimple_seq_add_seq (&thrn1_list, tseq);
   11093                 :          32 :                 tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
   11094                 :          32 :                 lower_omp (&tseq, ctx);
   11095                 :          32 :                 gimple_seq_add_seq (&thr02_list, tseq);
   11096                 :          32 :                 SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
   11097                 :          32 :                 DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
   11098                 :          32 :                 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
   11099                 :          32 :                 if (y)
   11100                 :           0 :                   SET_DECL_VALUE_EXPR (new_vard, y);
   11101                 :             :                 else
   11102                 :             :                   {
   11103                 :          32 :                     DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
   11104                 :          32 :                     SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
   11105                 :             :                   }
   11106                 :             :               }
   11107                 :             : 
   11108                 :          64 :             x = unshare_expr (var4);
   11109                 :          64 :             x = lang_hooks.decls.omp_clause_assign_op (c, x, rprivam1_ref);
   11110                 :          64 :             gimplify_and_add (x, &thrn2_list);
   11111                 :             : 
   11112                 :          64 :             if (is_for_simd)
   11113                 :             :               {
   11114                 :          32 :                 x = unshare_expr (rprivb_ref);
   11115                 :          32 :                 x = lang_hooks.decls.omp_clause_assign_op (c, x, var5);
   11116                 :          32 :                 gimplify_and_add (x, &scan1_list);
   11117                 :             :               }
   11118                 :             :             else
   11119                 :             :               {
   11120                 :          32 :                 if (ctx->scan_exclusive)
   11121                 :             :                   {
   11122                 :          16 :                     x = unshare_expr (rprivb_ref);
   11123                 :          16 :                     x = lang_hooks.decls.omp_clause_assign_op (c, x, var2);
   11124                 :          16 :                     gimplify_and_add (x, &scan1_list);
   11125                 :             :                   }
   11126                 :             : 
   11127                 :          32 :                 gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
   11128                 :          32 :                 tseq = copy_gimple_seq_and_replace_locals (tseq);
   11129                 :          32 :                 SET_DECL_VALUE_EXPR (placeholder, var2);
   11130                 :          32 :                 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
   11131                 :          32 :                 lower_omp (&tseq, ctx);
   11132                 :          32 :                 gimple_seq_add_seq (&scan1_list, tseq);
   11133                 :             : 
   11134                 :          32 :                 if (ctx->scan_inclusive)
   11135                 :             :                   {
   11136                 :          16 :                     x = unshare_expr (rprivb_ref);
   11137                 :          16 :                     x = lang_hooks.decls.omp_clause_assign_op (c, x, var2);
   11138                 :          16 :                     gimplify_and_add (x, &scan1_list);
   11139                 :             :                   }
   11140                 :             :               }
   11141                 :             : 
   11142                 :          64 :             x = unshare_expr (rpriva_ref);
   11143                 :          64 :             x = lang_hooks.decls.omp_clause_assign_op (c, x,
   11144                 :             :                                                        unshare_expr (var4));
   11145                 :          64 :             gimplify_and_add (x, &mdlist);
   11146                 :             : 
   11147                 :          96 :             x = unshare_expr (is_for_simd ? var6 : new_var);
   11148                 :          64 :             x = lang_hooks.decls.omp_clause_assign_op (c, x, var4);
   11149                 :          64 :             gimplify_and_add (x, &input2_list);
   11150                 :             : 
   11151                 :          64 :             val = rprivb_ref;
   11152                 :          64 :             if (new_vard != new_var)
   11153                 :          32 :               val = build_fold_addr_expr_loc (clause_loc, val);
   11154                 :             : 
   11155                 :          64 :             gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
   11156                 :          64 :             tseq = copy_gimple_seq_and_replace_locals (tseq);
   11157                 :          64 :             SET_DECL_VALUE_EXPR (new_vard, val);
   11158                 :          64 :             DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
   11159                 :          64 :             if (is_for_simd)
   11160                 :             :               {
   11161                 :          32 :                 SET_DECL_VALUE_EXPR (placeholder, var6);
   11162                 :          32 :                 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
   11163                 :             :               }
   11164                 :             :             else
   11165                 :          32 :               DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
   11166                 :          64 :             lower_omp (&tseq, ctx);
   11167                 :          64 :             if (y)
   11168                 :           0 :               SET_DECL_VALUE_EXPR (new_vard, y);
   11169                 :             :             else
   11170                 :             :               {
   11171                 :          64 :                 DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
   11172                 :          64 :                 SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
   11173                 :             :               }
   11174                 :          64 :             if (!is_for_simd)
   11175                 :             :               {
   11176                 :          32 :                 SET_DECL_VALUE_EXPR (placeholder, new_var);
   11177                 :          32 :                 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
   11178                 :          32 :                 lower_omp (&tseq, ctx);
   11179                 :             :               }
   11180                 :          64 :             gimple_seq_add_seq (&input2_list, tseq);
   11181                 :             : 
   11182                 :          64 :             x = build_outer_var_ref (var, ctx);
   11183                 :          64 :             x = lang_hooks.decls.omp_clause_assign_op (c, x, rpriva_ref);
   11184                 :          64 :             gimplify_and_add (x, &last_list);
   11185                 :             : 
   11186                 :          64 :             x = lang_hooks.decls.omp_clause_assign_op (c, var2, rprivalmk_ref);
   11187                 :          64 :             gimplify_and_add (x, &reduc_list);
   11188                 :          64 :             tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
   11189                 :          64 :             tseq = copy_gimple_seq_and_replace_locals (tseq);
   11190                 :          64 :             val = rprival_ref;
   11191                 :          64 :             if (new_vard != new_var)
   11192                 :          32 :               val = build_fold_addr_expr_loc (clause_loc, val);
   11193                 :          64 :             SET_DECL_VALUE_EXPR (new_vard, val);
   11194                 :          64 :             DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
   11195                 :          64 :             SET_DECL_VALUE_EXPR (placeholder, var2);
   11196                 :          64 :             lower_omp (&tseq, ctx);
   11197                 :          64 :             OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
   11198                 :          64 :             SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
   11199                 :          64 :             DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
   11200                 :          64 :             if (y)
   11201                 :           0 :               SET_DECL_VALUE_EXPR (new_vard, y);
   11202                 :             :             else
   11203                 :             :               {
   11204                 :          64 :                 DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
   11205                 :          64 :                 SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
   11206                 :             :               }
   11207                 :          64 :             gimple_seq_add_seq (&reduc_list, tseq);
   11208                 :          64 :             x = lang_hooks.decls.omp_clause_assign_op (c, rprival_ref, var2);
   11209                 :          64 :             gimplify_and_add (x, &reduc_list);
   11210                 :             : 
   11211                 :          64 :             x = lang_hooks.decls.omp_clause_dtor (c, var2);
   11212                 :          64 :             if (x)
   11213                 :          32 :               gimplify_and_add (x, dlist);
   11214                 :             :           }
   11215                 :             :         else
   11216                 :             :           {
   11217                 :         144 :             x = build_outer_var_ref (var, ctx);
   11218                 :         144 :             gimplify_assign (unshare_expr (var4), x, &thr01_list);
   11219                 :             : 
   11220                 :         144 :             x = omp_reduction_init (c, TREE_TYPE (new_var));
   11221                 :         144 :             gimplify_assign (unshare_expr (var4), unshare_expr (x),
   11222                 :             :                              &thrn1_list);
   11223                 :         144 :             gimplify_assign (unshare_expr (var4), x, &thr02_list);
   11224                 :             : 
   11225                 :         144 :             gimplify_assign (unshare_expr (var4), rprivam1_ref, &thrn2_list);
   11226                 :             : 
   11227                 :         144 :             enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
   11228                 :         144 :             if (code == MINUS_EXPR)
   11229                 :           0 :               code = PLUS_EXPR;
   11230                 :             : 
   11231                 :         144 :             if (is_for_simd)
   11232                 :          68 :               gimplify_assign (unshare_expr (rprivb_ref), var5, &scan1_list);
   11233                 :             :             else
   11234                 :             :               {
   11235                 :          76 :                 if (ctx->scan_exclusive)
   11236                 :          28 :                   gimplify_assign (unshare_expr (rprivb_ref), var2,
   11237                 :             :                                    &scan1_list);
   11238                 :          76 :                 x = build2 (code, TREE_TYPE (new_var), var2, new_var);
   11239                 :          76 :                 gimplify_assign (var2, x, &scan1_list);
   11240                 :          76 :                 if (ctx->scan_inclusive)
   11241                 :          48 :                   gimplify_assign (unshare_expr (rprivb_ref), var2,
   11242                 :             :                                    &scan1_list);
   11243                 :             :               }
   11244                 :             : 
   11245                 :         144 :             gimplify_assign (unshare_expr (rpriva_ref), unshare_expr (var4),
   11246                 :             :                              &mdlist);
   11247                 :             : 
   11248                 :         144 :             x = build2 (code, TREE_TYPE (new_var), var4, rprivb_ref);
   11249                 :         220 :             gimplify_assign (is_for_simd ? var6 : new_var, x, &input2_list);
   11250                 :             : 
   11251                 :         144 :             gimplify_assign (build_outer_var_ref (var, ctx), rpriva_ref,
   11252                 :             :                              &last_list);
   11253                 :             : 
   11254                 :         144 :             x = build2 (code, TREE_TYPE (new_var), rprivalmk_ref,
   11255                 :             :                         unshare_expr (rprival_ref));
   11256                 :         144 :             gimplify_assign (rprival_ref, x, &reduc_list);
   11257                 :             :           }
   11258                 :             :       }
   11259                 :             : 
   11260                 :         176 :   g = gimple_build_assign (ivar, PLUS_EXPR, ivar, size_one_node);
   11261                 :         176 :   gimple_seq_add_stmt (&scan1_list, g);
   11262                 :         176 :   g = gimple_build_assign (ivar, PLUS_EXPR, ivar, size_one_node);
   11263                 :         268 :   gimple_seq_add_stmt (gimple_omp_body_ptr (is_for_simd
   11264                 :             :                                             ? scan_stmt4 : scan_stmt2), g);
   11265                 :             : 
   11266                 :         176 :   tree controlb = create_tmp_var (boolean_type_node);
   11267                 :         176 :   tree controlp = create_tmp_var (ptr_type_node);
   11268                 :         176 :   tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SCANTEMP_);
   11269                 :         176 :   OMP_CLAUSE_DECL (nc) = controlb;
   11270                 :         176 :   OMP_CLAUSE__SCANTEMP__CONTROL (nc) = 1;
   11271                 :         176 :   *cp1 = nc;
   11272                 :         176 :   cp1 = &OMP_CLAUSE_CHAIN (nc);
   11273                 :         176 :   nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SCANTEMP_);
   11274                 :         176 :   OMP_CLAUSE_DECL (nc) = controlp;
   11275                 :         176 :   OMP_CLAUSE__SCANTEMP__CONTROL (nc) = 1;
   11276                 :         176 :   *cp1 = nc;
   11277                 :         176 :   cp1 = &OMP_CLAUSE_CHAIN (nc);
   11278                 :         176 :   nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SCANTEMP_);
   11279                 :         176 :   OMP_CLAUSE_DECL (nc) = controlb;
   11280                 :         176 :   OMP_CLAUSE__SCANTEMP__CONTROL (nc) = 1;
   11281                 :         176 :   *cp2 = nc;
   11282                 :         176 :   cp2 = &OMP_CLAUSE_CHAIN (nc);
   11283                 :         176 :   nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SCANTEMP_);
   11284                 :         176 :   OMP_CLAUSE_DECL (nc) = controlp;
   11285                 :         176 :   OMP_CLAUSE__SCANTEMP__CONTROL (nc) = 1;
   11286                 :         176 :   *cp2 = nc;
   11287                 :         176 :   cp2 = &OMP_CLAUSE_CHAIN (nc);
   11288                 :             : 
   11289                 :         176 :   *cp1 = gimple_omp_for_clauses (stmt);
   11290                 :         176 :   gimple_omp_for_set_clauses (stmt, new_clauses1);
   11291                 :         176 :   *cp2 = gimple_omp_for_clauses (new_stmt);
   11292                 :         176 :   gimple_omp_for_set_clauses (new_stmt, new_clauses2);
   11293                 :             : 
   11294                 :         176 :   if (is_for_simd)
   11295                 :             :     {
   11296                 :          84 :       gimple_seq_add_seq (gimple_omp_body_ptr (scan_stmt3), scan1_list);
   11297                 :          84 :       gimple_seq_add_seq (gimple_omp_body_ptr (input_stmt4), input2_list);
   11298                 :             : 
   11299                 :          84 :       gsi_insert_seq_after (&input3_gsi, gimple_omp_body (input_stmt3),
   11300                 :             :                             GSI_SAME_STMT);
   11301                 :          84 :       gsi_remove (&input3_gsi, true);
   11302                 :          84 :       gsi_insert_seq_after (&scan3_gsi, gimple_omp_body (scan_stmt3),
   11303                 :             :                             GSI_SAME_STMT);
   11304                 :          84 :       gsi_remove (&scan3_gsi, true);
   11305                 :          84 :       gsi_insert_seq_after (&input4_gsi, gimple_omp_body (input_stmt4),
   11306                 :             :                             GSI_SAME_STMT);
   11307                 :          84 :       gsi_remove (&input4_gsi, true);
   11308                 :          84 :       gsi_insert_seq_after (&scan4_gsi, gimple_omp_body (scan_stmt4),
   11309                 :             :                             GSI_SAME_STMT);
   11310                 :          84 :       gsi_remove (&scan4_gsi, true);
   11311                 :             :     }
   11312                 :             :   else
   11313                 :             :     {
   11314                 :          92 :       gimple_omp_set_body (scan_stmt1, scan1_list);
   11315                 :          92 :       gimple_omp_set_body (input_stmt2, input2_list);
   11316                 :             :     }
   11317                 :             : 
   11318                 :         176 :   gsi_insert_seq_after (&input1_gsi, gimple_omp_body (input_stmt1),
   11319                 :             :                         GSI_SAME_STMT);
   11320                 :         176 :   gsi_remove (&input1_gsi, true);
   11321                 :         176 :   gsi_insert_seq_after (&scan1_gsi, gimple_omp_body (scan_stmt1),
   11322                 :             :                         GSI_SAME_STMT);
   11323                 :         176 :   gsi_remove (&scan1_gsi, true);
   11324                 :         176 :   gsi_insert_seq_after (&input2_gsi, gimple_omp_body (input_stmt2),
   11325                 :             :                         GSI_SAME_STMT);
   11326                 :         176 :   gsi_remove (&input2_gsi, true);
   11327                 :         176 :   gsi_insert_seq_after (&scan2_gsi, gimple_omp_body (scan_stmt2),
   11328                 :             :                         GSI_SAME_STMT);
   11329                 :         176 :   gsi_remove (&scan2_gsi, true);
   11330                 :             : 
   11331                 :         176 :   gimple_seq_add_seq (body_p, clist);
   11332                 :             : 
   11333                 :         176 :   tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
   11334                 :         176 :   tree lab2 = create_artificial_label (UNKNOWN_LOCATION);
   11335                 :         176 :   tree lab3 = create_artificial_label (UNKNOWN_LOCATION);
   11336                 :         176 :   g = gimple_build_cond (EQ_EXPR, thread_num, integer_zero_node, lab1, lab2);
   11337                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11338                 :         176 :   g = gimple_build_label (lab1);
   11339                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11340                 :         176 :   gimple_seq_add_seq (body_p, thr01_list);
   11341                 :         176 :   g = gimple_build_goto (lab3);
   11342                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11343                 :         176 :   g = gimple_build_label (lab2);
   11344                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11345                 :         176 :   gimple_seq_add_seq (body_p, thrn1_list);
   11346                 :         176 :   g = gimple_build_label (lab3);
   11347                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11348                 :             : 
   11349                 :         176 :   g = gimple_build_assign (ivar, size_zero_node);
   11350                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11351                 :             : 
   11352                 :         176 :   gimple_seq_add_stmt (body_p, stmt);
   11353                 :         176 :   gimple_seq_add_seq (body_p, body);
   11354                 :         176 :   gimple_seq_add_stmt (body_p, gimple_build_omp_continue (fd->loop.v,
   11355                 :             :                                                           fd->loop.v));
   11356                 :             : 
   11357                 :         176 :   g = gimple_build_omp_return (true);
   11358                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11359                 :         176 :   gimple_seq_add_seq (body_p, mdlist);
   11360                 :             : 
   11361                 :         176 :   lab1 = create_artificial_label (UNKNOWN_LOCATION);
   11362                 :         176 :   lab2 = create_artificial_label (UNKNOWN_LOCATION);
   11363                 :         176 :   g = gimple_build_cond (GT_EXPR, num_threads, integer_one_node, lab1, lab2);
   11364                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11365                 :         176 :   g = gimple_build_label (lab1);
   11366                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11367                 :             : 
   11368                 :         176 :   g = omp_build_barrier (NULL);
   11369                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11370                 :             : 
   11371                 :         176 :   tree down = create_tmp_var (unsigned_type_node);
   11372                 :         176 :   g = gimple_build_assign (down, build_zero_cst (unsigned_type_node));
   11373                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11374                 :             : 
   11375                 :         176 :   g = gimple_build_assign (k, build_one_cst (unsigned_type_node));
   11376                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11377                 :             : 
   11378                 :         176 :   tree num_threadsu = create_tmp_var (unsigned_type_node);
   11379                 :         176 :   g = gimple_build_assign (num_threadsu, NOP_EXPR, num_threads);
   11380                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11381                 :             : 
   11382                 :         176 :   tree thread_numu = create_tmp_var (unsigned_type_node);
   11383                 :         176 :   g = gimple_build_assign (thread_numu, NOP_EXPR, thread_num);
   11384                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11385                 :             : 
   11386                 :         176 :   tree thread_nump1 = create_tmp_var (unsigned_type_node);
   11387                 :         176 :   g = gimple_build_assign (thread_nump1, PLUS_EXPR, thread_numu,
   11388                 :         176 :                            build_int_cst (unsigned_type_node, 1));
   11389                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11390                 :             : 
   11391                 :         176 :   lab3 = create_artificial_label (UNKNOWN_LOCATION);
   11392                 :         176 :   g = gimple_build_label (lab3);
   11393                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11394                 :             : 
   11395                 :         176 :   tree twok = create_tmp_var (unsigned_type_node);
   11396                 :         176 :   g = gimple_build_assign (twok, LSHIFT_EXPR, k, integer_one_node);
   11397                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11398                 :             : 
   11399                 :         176 :   tree lab4 = create_artificial_label (UNKNOWN_LOCATION);
   11400                 :         176 :   tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
   11401                 :         176 :   tree lab6 = create_artificial_label (UNKNOWN_LOCATION);
   11402                 :         176 :   g = gimple_build_cond (GT_EXPR, twok, num_threadsu, lab4, lab5);
   11403                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11404                 :         176 :   g = gimple_build_label (lab4);
   11405                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11406                 :         176 :   g = gimple_build_assign (down, build_all_ones_cst (unsigned_type_node));
   11407                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11408                 :         176 :   g = gimple_build_assign (k, RSHIFT_EXPR, k, integer_one_node);
   11409                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11410                 :             : 
   11411                 :         176 :   g = gimple_build_cond (EQ_EXPR, k, num_threadsu, lab6, lab5);
   11412                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11413                 :         176 :   g = gimple_build_label (lab6);
   11414                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11415                 :             : 
   11416                 :         176 :   g = gimple_build_assign (k, RSHIFT_EXPR, k, integer_one_node);
   11417                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11418                 :             : 
   11419                 :         176 :   g = gimple_build_label (lab5);
   11420                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11421                 :             : 
   11422                 :         176 :   g = gimple_build_assign (twok, LSHIFT_EXPR, k, integer_one_node);
   11423                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11424                 :             : 
   11425                 :         176 :   tree cplx = create_tmp_var (build_complex_type (unsigned_type_node, false));
   11426                 :         176 :   g = gimple_build_call_internal (IFN_MUL_OVERFLOW, 2, thread_nump1, twok);
   11427                 :         176 :   gimple_call_set_lhs (g, cplx);
   11428                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11429                 :         176 :   tree mul = create_tmp_var (unsigned_type_node);
   11430                 :         176 :   g = gimple_build_assign (mul, REALPART_EXPR,
   11431                 :             :                            build1 (REALPART_EXPR, unsigned_type_node, cplx));
   11432                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11433                 :         176 :   tree ovf = create_tmp_var (unsigned_type_node);
   11434                 :         176 :   g = gimple_build_assign (ovf, IMAGPART_EXPR,
   11435                 :             :                            build1 (IMAGPART_EXPR, unsigned_type_node, cplx));
   11436                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11437                 :             : 
   11438                 :         176 :   tree lab7 = create_artificial_label (UNKNOWN_LOCATION);
   11439                 :         176 :   tree lab8 = create_artificial_label (UNKNOWN_LOCATION);
   11440                 :         176 :   g = gimple_build_cond (EQ_EXPR, ovf, build_zero_cst (unsigned_type_node),
   11441                 :             :                          lab7, lab8);
   11442                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11443                 :         176 :   g = gimple_build_label (lab7);
   11444                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11445                 :             : 
   11446                 :         176 :   tree andv = create_tmp_var (unsigned_type_node);
   11447                 :         176 :   g = gimple_build_assign (andv, BIT_AND_EXPR, k, down);
   11448                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11449                 :         176 :   tree andvm1 = create_tmp_var (unsigned_type_node);
   11450                 :         176 :   g = gimple_build_assign (andvm1, PLUS_EXPR, andv,
   11451                 :             :                            build_minus_one_cst (unsigned_type_node));
   11452                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11453                 :             : 
   11454                 :         176 :   g = gimple_build_assign (l, PLUS_EXPR, mul, andvm1);
   11455                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11456                 :             : 
   11457                 :         176 :   tree lab9 = create_artificial_label (UNKNOWN_LOCATION);
   11458                 :         176 :   g = gimple_build_cond (LT_EXPR, l, num_threadsu, lab9, lab8);
   11459                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11460                 :         176 :   g = gimple_build_label (lab9);
   11461                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11462                 :         176 :   gimple_seq_add_seq (body_p, reduc_list);
   11463                 :         176 :   g = gimple_build_label (lab8);
   11464                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11465                 :             : 
   11466                 :         176 :   tree lab10 = create_artificial_label (UNKNOWN_LOCATION);
   11467                 :         176 :   tree lab11 = create_artificial_label (UNKNOWN_LOCATION);
   11468                 :         176 :   tree lab12 = create_artificial_label (UNKNOWN_LOCATION);
   11469                 :         176 :   g = gimple_build_cond (EQ_EXPR, down, build_zero_cst (unsigned_type_node),
   11470                 :             :                          lab10, lab11);
   11471                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11472                 :         176 :   g = gimple_build_label (lab10);
   11473                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11474                 :         176 :   g = gimple_build_assign (k, LSHIFT_EXPR, k, integer_one_node);
   11475                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11476                 :         176 :   g = gimple_build_goto (lab12);
   11477                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11478                 :         176 :   g = gimple_build_label (lab11);
   11479                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11480                 :         176 :   g = gimple_build_assign (k, RSHIFT_EXPR, k, integer_one_node);
   11481                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11482                 :         176 :   g = gimple_build_label (lab12);
   11483                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11484                 :             : 
   11485                 :         176 :   g = omp_build_barrier (NULL);
   11486                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11487                 :             : 
   11488                 :         176 :   g = gimple_build_cond (NE_EXPR, k, build_zero_cst (unsigned_type_node),
   11489                 :             :                          lab3, lab2);
   11490                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11491                 :             : 
   11492                 :         176 :   g = gimple_build_label (lab2);
   11493                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11494                 :             : 
   11495                 :         176 :   lab1 = create_artificial_label (UNKNOWN_LOCATION);
   11496                 :         176 :   lab2 = create_artificial_label (UNKNOWN_LOCATION);
   11497                 :         176 :   lab3 = create_artificial_label (UNKNOWN_LOCATION);
   11498                 :         176 :   g = gimple_build_cond (EQ_EXPR, thread_num, integer_zero_node, lab1, lab2);
   11499                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11500                 :         176 :   g = gimple_build_label (lab1);
   11501                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11502                 :         176 :   gimple_seq_add_seq (body_p, thr02_list);
   11503                 :         176 :   g = gimple_build_goto (lab3);
   11504                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11505                 :         176 :   g = gimple_build_label (lab2);
   11506                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11507                 :         176 :   gimple_seq_add_seq (body_p, thrn2_list);
   11508                 :         176 :   g = gimple_build_label (lab3);
   11509                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11510                 :             : 
   11511                 :         176 :   g = gimple_build_assign (ivar, size_zero_node);
   11512                 :         176 :   gimple_seq_add_stmt (body_p, g);
   11513                 :         176 :   gimple_seq_add_stmt (body_p, new_stmt);
   11514                 :         176 :   gimple_seq_add_seq (body_p, new_body);
   11515                 :             : 
   11516                 :         176 :   gimple_seq new_dlist = NULL;
   11517                 :         176 :   lab1 = create_artificial_label (UNKNOWN_LOCATION);
   11518                 :         176 :   lab2 = create_artificial_label (UNKNOWN_LOCATION);
   11519                 :         176 :   tree num_threadsm1 = create_tmp_var (integer_type_node);
   11520                 :         176 :   g = gimple_build_assign (num_threadsm1, PLUS_EXPR, num_threads,
   11521                 :             :                            integer_minus_one_node);
   11522                 :         176 :   gimple_seq_add_stmt (&new_dlist, g);
   11523                 :         176 :   g = gimple_build_cond (EQ_EXPR, thread_num, num_threadsm1, lab1, lab2);
   11524                 :         176 :   gimple_seq_add_stmt (&new_dlist, g);
   11525                 :         176 :   g = gimple_build_label (lab1);
   11526                 :         176 :   gimple_seq_add_stmt (&new_dlist, g);
   11527                 :         176 :   gimple_seq_add_seq (&new_dlist, last_list);
   11528                 :         176 :   g = gimple_build_label (lab2);
   11529                 :         176 :   gimple_seq_add_stmt (&new_dlist, g);
   11530                 :         176 :   gimple_seq_add_seq (&new_dlist, *dlist);
   11531                 :         176 :   *dlist = new_dlist;
   11532                 :         176 : }
   11533                 :             : 
   11534                 :             : /* Build an internal UNIQUE function with type IFN_UNIQUE_OACC_PRIVATE listing
   11535                 :             :    the addresses of variables to be made private at the surrounding
   11536                 :             :    parallelism level.  Such functions appear in the gimple code stream in two
   11537                 :             :    forms, e.g. for a partitioned loop:
   11538                 :             : 
   11539                 :             :       .data_dep.6 = .UNIQUE (OACC_HEAD_MARK, .data_dep.6, 1, 68);
   11540                 :             :       .data_dep.6 = .UNIQUE (OACC_PRIVATE, .data_dep.6, -1, &w);
   11541                 :             :       .data_dep.6 = .UNIQUE (OACC_FORK, .data_dep.6, -1);
   11542                 :             :       .data_dep.6 = .UNIQUE (OACC_HEAD_MARK, .data_dep.6);
   11543                 :             : 
   11544                 :             :    or alternatively, OACC_PRIVATE can appear at the top level of a parallel,
   11545                 :             :    not as part of a HEAD_MARK sequence:
   11546                 :             : 
   11547                 :             :       .UNIQUE (OACC_PRIVATE, 0, 0, &w);
   11548                 :             : 
   11549                 :             :    For such stand-alone appearances, the 3rd argument is always 0, denoting
   11550                 :             :    gang partitioning.  */
   11551                 :             : 
   11552                 :             : static gcall *
   11553                 :       18780 : lower_oacc_private_marker (omp_context *ctx)
   11554                 :             : {
   11555                 :       18780 :   if (ctx->oacc_privatization_candidates.length () == 0)
   11556                 :             :     return NULL;
   11557                 :             : 
   11558                 :         299 :   auto_vec<tree, 5> args;
   11559                 :             : 
   11560                 :         299 :   args.quick_push (build_int_cst (integer_type_node, IFN_UNIQUE_OACC_PRIVATE));
   11561                 :         299 :   args.quick_push (integer_zero_node);
   11562                 :         299 :   args.quick_push (integer_minus_one_node);
   11563                 :             : 
   11564                 :         299 :   int i;
   11565                 :         299 :   tree decl;
   11566                 :         690 :   FOR_EACH_VEC_ELT (ctx->oacc_privatization_candidates, i, decl)
   11567                 :             :     {
   11568                 :         391 :       gcc_checking_assert (TREE_ADDRESSABLE (decl));
   11569                 :         391 :       tree addr = build_fold_addr_expr (decl);
   11570                 :         391 :       args.safe_push (addr);
   11571                 :             :     }
   11572                 :             : 
   11573                 :         299 :   return gimple_build_call_internal_vec (IFN_UNIQUE, args);
   11574                 :         299 : }
   11575                 :             : 
   11576                 :             : /* Lower code for an OMP loop directive.  */
   11577                 :             : 
   11578                 :             : static void
   11579                 :       46675 : lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   11580                 :             : {
   11581                 :       46675 :   tree *rhs_p, block;
   11582                 :       46675 :   struct omp_for_data fd, *fdp = NULL;
   11583                 :       46675 :   gomp_for *stmt = as_a <gomp_for *> (gsi_stmt (*gsi_p));
   11584                 :       46675 :   gbind *new_stmt;
   11585                 :       46675 :   gimple_seq omp_for_body, body, dlist, tred_ilist = NULL, tred_dlist = NULL;
   11586                 :       46675 :   gimple_seq cnt_list = NULL, clist = NULL;
   11587                 :       46675 :   gimple_seq oacc_head = NULL, oacc_tail = NULL;
   11588                 :       46675 :   size_t i;
   11589                 :             : 
   11590                 :       46675 :   push_gimplify_context ();
   11591                 :             : 
   11592                 :       46675 :   if (is_gimple_omp_oacc (ctx->stmt))
   11593                 :       10589 :     oacc_privatization_scan_clause_chain (ctx, gimple_omp_for_clauses (stmt));
   11594                 :             : 
   11595                 :       46675 :   lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
   11596                 :             : 
   11597                 :       46675 :   block = make_node (BLOCK);
   11598                 :       46675 :   new_stmt = gimple_build_bind (NULL, NULL, block);
   11599                 :             :   /* Replace at gsi right away, so that 'stmt' is no member
   11600                 :             :      of a sequence anymore as we're going to add to a different
   11601                 :             :      one below.  */
   11602                 :       46675 :   gsi_replace (gsi_p, new_stmt, true);
   11603                 :             : 
   11604                 :             :   /* Move declaration of temporaries in the loop body before we make
   11605                 :             :      it go away.  */
   11606                 :       46675 :   omp_for_body = gimple_omp_body (stmt);
   11607                 :       46675 :   if (!gimple_seq_empty_p (omp_for_body)
   11608                 :       46675 :       && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
   11609                 :             :     {
   11610                 :       19483 :       gbind *inner_bind
   11611                 :       19483 :         = as_a <gbind *> (gimple_seq_first_stmt (omp_for_body));
   11612                 :       19483 :       tree vars = gimple_bind_vars (inner_bind);
   11613                 :       19483 :       if (is_gimple_omp_oacc (ctx->stmt))
   11614                 :        4985 :         oacc_privatization_scan_decl_chain (ctx, vars);
   11615                 :       19483 :       gimple_bind_append_vars (new_stmt, vars);
   11616                 :             :       /* bind_vars/BLOCK_VARS are being moved to new_stmt/block, don't
   11617                 :             :          keep them on the inner_bind and it's block.  */
   11618                 :       19483 :       gimple_bind_set_vars (inner_bind, NULL_TREE);
   11619                 :       19483 :       if (gimple_bind_block (inner_bind))
   11620                 :       16773 :         BLOCK_VARS (gimple_bind_block (inner_bind)) = NULL_TREE;
   11621                 :             :     }
   11622                 :             : 
   11623                 :       46675 :   if (gimple_omp_for_combined_into_p (stmt))
   11624                 :             :     {
   11625                 :       15088 :       omp_extract_for_data (stmt, &fd, NULL);
   11626                 :       15088 :       fdp = &fd;
   11627                 :             : 
   11628                 :             :       /* We need two temporaries with fd.loop.v type (istart/iend)
   11629                 :             :          and then (fd.collapse - 1) temporaries with the same
   11630                 :             :          type for count2 ... countN-1 vars if not constant.  */
   11631                 :       15088 :       size_t count = 2;
   11632                 :       15088 :       tree type = fd.iter_type;
   11633                 :       15088 :       if (fd.collapse > 1
   11634                 :        4853 :           && TREE_CODE (fd.loop.n2) != INTEGER_CST)
   11635                 :        2623 :         count += fd.collapse - 1;
   11636                 :       15088 :       size_t count2 = 0;
   11637                 :       15088 :       tree type2 = NULL_TREE;
   11638                 :       15088 :       bool taskreg_for
   11639                 :       15088 :         = (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR
   11640                 :       15088 :            || gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_TASKLOOP);
   11641                 :       15088 :       tree outerc = NULL, *pc = gimple_omp_for_clauses_ptr (stmt);
   11642                 :       15088 :       tree simtc = NULL;
   11643                 :       15088 :       tree clauses = *pc;
   11644                 :       15088 :       if (fd.collapse > 1
   11645                 :        4853 :           && fd.non_rect
   11646                 :         137 :           && fd.last_nonrect == fd.first_nonrect + 1
   11647                 :          89 :           && TREE_CODE (fd.loop.n2) != INTEGER_CST)
   11648                 :          64 :         if (tree v = gimple_omp_for_index (stmt, fd.last_nonrect))
   11649                 :          64 :           if (!TYPE_UNSIGNED (TREE_TYPE (v)))
   11650                 :             :             {
   11651                 :          60 :               v = gimple_omp_for_index (stmt, fd.first_nonrect);
   11652                 :          60 :               type2 = TREE_TYPE (v);
   11653                 :          60 :               count++;
   11654                 :          60 :               count2 = 3;
   11655                 :             :             }
   11656                 :       15088 :       if (taskreg_for)
   11657                 :        7776 :         outerc
   11658                 :        7776 :           = omp_find_clause (gimple_omp_taskreg_clauses (ctx->outer->stmt),
   11659                 :             :                              OMP_CLAUSE__LOOPTEMP_);
   11660                 :       15088 :       if (ctx->simt_stmt)
   11661                 :           0 :         simtc = omp_find_clause (gimple_omp_for_clauses (ctx->simt_stmt),
   11662                 :             :                                  OMP_CLAUSE__LOOPTEMP_);
   11663                 :       50594 :       for (i = 0; i < count + count2; i++)
   11664                 :             :         {
   11665                 :       35506 :           tree temp;
   11666                 :       35506 :           if (taskreg_for)
   11667                 :             :             {
   11668                 :       18367 :               gcc_assert (outerc);
   11669                 :       18367 :               temp = lookup_decl (OMP_CLAUSE_DECL (outerc), ctx->outer);
   11670                 :       18367 :               outerc = omp_find_clause (OMP_CLAUSE_CHAIN (outerc),
   11671                 :             :                                         OMP_CLAUSE__LOOPTEMP_);
   11672                 :             :             }
   11673                 :             :           else
   11674                 :             :             {
   11675                 :             :               /* If there are 2 adjacent SIMD stmts, one with _simt_
   11676                 :             :                  clause, another without, make sure they have the same
   11677                 :             :                  decls in _looptemp_ clauses, because the outer stmt
   11678                 :             :                  they are combined into will look up just one inner_stmt.  */
   11679                 :       17139 :               if (ctx->simt_stmt)
   11680                 :           0 :                 temp = OMP_CLAUSE_DECL (simtc);
   11681                 :             :               else
   11682                 :       34134 :                 temp = create_tmp_var (i >= count ? type2 : type);
   11683                 :       17139 :               insert_decl_map (&ctx->outer->cb, temp, temp);
   11684                 :             :             }
   11685                 :       35506 :           *pc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_);
   11686                 :       35506 :           OMP_CLAUSE_DECL (*pc) = temp;
   11687                 :       35506 :           pc = &OMP_CLAUSE_CHAIN (*pc);
   11688                 :       35506 :           if (ctx->simt_stmt)
   11689                 :           0 :             simtc = omp_find_clause (OMP_CLAUSE_CHAIN (simtc),
   11690                 :             :                                      OMP_CLAUSE__LOOPTEMP_);
   11691                 :             :         }
   11692                 :       15088 :       *pc = clauses;
   11693                 :             :     }
   11694                 :             : 
   11695                 :             :   /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR.  */
   11696                 :       46675 :   dlist = NULL;
   11697                 :       46675 :   body = NULL;
   11698                 :       46675 :   tree rclauses
   11699                 :       46675 :     = omp_task_reductions_find_first (gimple_omp_for_clauses (stmt), OMP_FOR,
   11700                 :             :                                       OMP_CLAUSE_REDUCTION);
   11701                 :       46675 :   tree rtmp = NULL_TREE;
   11702                 :       46675 :   if (rclauses)
   11703                 :             :     {
   11704                 :         229 :       tree type = build_pointer_type (pointer_sized_int_node);
   11705                 :         229 :       tree temp = create_tmp_var (type);
   11706                 :         229 :       tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
   11707                 :         229 :       OMP_CLAUSE_DECL (c) = temp;
   11708                 :         229 :       OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (stmt);
   11709                 :         229 :       gimple_omp_for_set_clauses (stmt, c);
   11710                 :         229 :       lower_omp_task_reductions (ctx, OMP_FOR,
   11711                 :             :                                  gimple_omp_for_clauses (stmt),
   11712                 :             :                                  &tred_ilist, &tred_dlist);
   11713                 :         229 :       rclauses = c;
   11714                 :         229 :       rtmp = make_ssa_name (type);
   11715                 :         229 :       gimple_seq_add_stmt (&body, gimple_build_assign (rtmp, temp));
   11716                 :             :     }
   11717                 :             : 
   11718                 :       46675 :   lower_lastprivate_conditional_clauses (gimple_omp_for_clauses_ptr (stmt),
   11719                 :             :                                          ctx);
   11720                 :             : 
   11721                 :       46675 :   lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx,
   11722                 :             :                            fdp);
   11723                 :       93121 :   gimple_seq_add_seq (rclauses ? &tred_ilist : &body,
   11724                 :             :                       gimple_omp_for_pre_body (stmt));
   11725                 :             : 
   11726                 :       46675 :   lower_omp (gimple_omp_body_ptr (stmt), ctx);
   11727                 :             : 
   11728                 :       46675 :   gcall *private_marker = NULL;
   11729                 :       46675 :   if (is_gimple_omp_oacc (ctx->stmt)
   11730                 :       46675 :       && !gimple_seq_empty_p (omp_for_body))
   11731                 :        9654 :     private_marker = lower_oacc_private_marker (ctx);
   11732                 :             : 
   11733                 :             :   /* Lower the header expressions.  At this point, we can assume that
   11734                 :             :      the header is of the form:
   11735                 :             : 
   11736                 :             :         #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
   11737                 :             : 
   11738                 :             :      We just need to make sure that VAL1, VAL2 and VAL3 are lowered
   11739                 :             :      using the .omp_data_s mapping, if needed.  */
   11740                 :      114448 :   for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
   11741                 :             :     {
   11742                 :       67773 :       rhs_p = gimple_omp_for_initial_ptr (stmt, i);
   11743                 :       67773 :       if (TREE_CODE (*rhs_p) == TREE_VEC)
   11744                 :             :         {
   11745                 :         644 :           if (!is_gimple_min_invariant (TREE_VEC_ELT (*rhs_p, 1)))
   11746                 :         149 :             TREE_VEC_ELT (*rhs_p, 1)
   11747                 :         298 :               = get_formal_tmp_var (TREE_VEC_ELT (*rhs_p, 1), &cnt_list);
   11748                 :         644 :           if (!is_gimple_min_invariant (TREE_VEC_ELT (*rhs_p, 2)))
   11749                 :         161 :             TREE_VEC_ELT (*rhs_p, 2)
   11750                 :         322 :               = get_formal_tmp_var (TREE_VEC_ELT (*rhs_p, 2), &cnt_list);
   11751                 :             :         }
   11752                 :       67129 :       else if (!is_gimple_min_invariant (*rhs_p))
   11753                 :       11531 :         *rhs_p = get_formal_tmp_var (*rhs_p, &cnt_list);
   11754                 :       55598 :       else if (TREE_CODE (*rhs_p) == ADDR_EXPR)
   11755                 :        4643 :         recompute_tree_invariant_for_addr_expr (*rhs_p);
   11756                 :             : 
   11757                 :       67773 :       rhs_p = gimple_omp_for_final_ptr (stmt, i);
   11758                 :       67773 :       if (TREE_CODE (*rhs_p) == TREE_VEC)
   11759                 :             :         {
   11760                 :         527 :           if (!is_gimple_min_invariant (TREE_VEC_ELT (*rhs_p, 1)))
   11761                 :         142 :             TREE_VEC_ELT (*rhs_p, 1)
   11762                 :         284 :               = get_formal_tmp_var (TREE_VEC_ELT (*rhs_p, 1), &cnt_list);
   11763                 :         527 :           if (!is_gimple_min_invariant (TREE_VEC_ELT (*rhs_p, 2)))
   11764                 :         157 :             TREE_VEC_ELT (*rhs_p, 2)
   11765                 :         314 :               = get_formal_tmp_var (TREE_VEC_ELT (*rhs_p, 2), &cnt_list);
   11766                 :             :         }
   11767                 :       67246 :       else if (!is_gimple_min_invariant (*rhs_p))
   11768                 :       16069 :         *rhs_p = get_formal_tmp_var (*rhs_p, &cnt_list);
   11769                 :       51177 :       else if (TREE_CODE (*rhs_p) == ADDR_EXPR)
   11770                 :        4638 :         recompute_tree_invariant_for_addr_expr (*rhs_p);
   11771                 :             : 
   11772                 :       67773 :       rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
   11773                 :       67773 :       if (!is_gimple_min_invariant (*rhs_p))
   11774                 :        6332 :         *rhs_p = get_formal_tmp_var (*rhs_p, &cnt_list);
   11775                 :             :     }
   11776                 :       46675 :   if (rclauses)
   11777                 :         229 :     gimple_seq_add_seq (&tred_ilist, cnt_list);
   11778                 :             :   else
   11779                 :       46446 :     gimple_seq_add_seq (&body, cnt_list);
   11780                 :             : 
   11781                 :             :   /* Once lowered, extract the bounds and clauses.  */
   11782                 :       46675 :   omp_extract_for_data (stmt, &fd, NULL);
   11783                 :             : 
   11784                 :       46675 :   if (is_gimple_omp_oacc (ctx->stmt)
   11785                 :       46675 :       && !ctx_in_oacc_kernels_region (ctx))
   11786                 :        8725 :     lower_oacc_head_tail (gimple_location (stmt),
   11787                 :             :                           gimple_omp_for_clauses (stmt), private_marker,
   11788                 :             :                           &oacc_head, &oacc_tail, ctx);
   11789                 :             : 
   11790                 :             :   /* Add OpenACC partitioning and reduction markers just before the loop.  */
   11791                 :       46675 :   if (oacc_head)
   11792                 :        8725 :     gimple_seq_add_seq (&body, oacc_head);
   11793                 :             : 
   11794                 :       46675 :   lower_omp_for_lastprivate (&fd, &body, &dlist, &clist, ctx);
   11795                 :             : 
   11796                 :       46675 :   if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR)
   11797                 :       85775 :     for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
   11798                 :       70523 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   11799                 :       70523 :           && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   11800                 :             :         {
   11801                 :         242 :           OMP_CLAUSE_DECL (c) = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
   11802                 :         242 :           if (DECL_P (OMP_CLAUSE_LINEAR_STEP (c)))
   11803                 :          44 :             OMP_CLAUSE_LINEAR_STEP (c)
   11804                 :          88 :               = maybe_lookup_decl_in_outer_ctx (OMP_CLAUSE_LINEAR_STEP (c),
   11805                 :             :                                                 ctx);
   11806                 :             :         }
   11807                 :             : 
   11808                 :       46285 :   if ((ctx->scan_inclusive || ctx->scan_exclusive)
   11809                 :       46963 :       && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR)
   11810                 :         176 :     lower_omp_for_scan (&body, &dlist, stmt, &fd, ctx);
   11811                 :             :   else
   11812                 :             :     {
   11813                 :       46499 :       gimple_seq_add_stmt (&body, stmt);
   11814                 :       46499 :       gimple_seq_add_seq (&body, gimple_omp_body (stmt));
   11815                 :             :     }
   11816                 :             : 
   11817                 :       46675 :   gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
   11818                 :             :                                                          fd.loop.v));
   11819                 :             : 
   11820                 :             :   /* After the loop, add exit clauses.  */
   11821                 :       46675 :   lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, &clist, ctx);
   11822                 :             : 
   11823                 :       46675 :   if (clist)
   11824                 :             :     {
   11825                 :         187 :       tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
   11826                 :         187 :       gcall *g = gimple_build_call (fndecl, 0);
   11827                 :         187 :       gimple_seq_add_stmt (&body, g);
   11828                 :         187 :       gimple_seq_add_seq (&body, clist);
   11829                 :         187 :       fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
   11830                 :         187 :       g = gimple_build_call (fndecl, 0);
   11831                 :         187 :       gimple_seq_add_stmt (&body, g);
   11832                 :             :     }
   11833                 :             : 
   11834                 :       46675 :   if (ctx->cancellable)
   11835                 :          86 :     gimple_seq_add_stmt (&body, gimple_build_label (ctx->cancel_label));
   11836                 :             : 
   11837                 :       46675 :   gimple_seq_add_seq (&body, dlist);
   11838                 :             : 
   11839                 :       46675 :   if (rclauses)
   11840                 :             :     {
   11841                 :         229 :       gimple_seq_add_seq (&tred_ilist, body);
   11842                 :         229 :       body = tred_ilist;
   11843                 :             :     }
   11844                 :             : 
   11845                 :       46675 :   body = maybe_catch_exception (body);
   11846                 :             : 
   11847                 :             :   /* Region exit marker goes at the end of the loop body.  */
   11848                 :       46675 :   gimple *g = gimple_build_omp_return (fd.have_nowait);
   11849                 :       46675 :   gimple_seq_add_stmt (&body, g);
   11850                 :             : 
   11851                 :       46675 :   gimple_seq_add_seq (&body, tred_dlist);
   11852                 :             : 
   11853                 :       46675 :   maybe_add_implicit_barrier_cancel (ctx, g, &body);
   11854                 :             : 
   11855                 :       46675 :   if (rclauses)
   11856                 :         229 :     OMP_CLAUSE_DECL (rclauses) = rtmp;
   11857                 :             : 
   11858                 :             :   /* Add OpenACC joining and reduction markers just after the loop.  */
   11859                 :       46675 :   if (oacc_tail)
   11860                 :        8725 :     gimple_seq_add_seq (&body, oacc_tail);
   11861                 :             : 
   11862                 :       46675 :   pop_gimplify_context (new_stmt);
   11863                 :             : 
   11864                 :       46675 :   gimple_bind_append_vars (new_stmt, ctx->block_vars);
   11865                 :       46675 :   maybe_remove_omp_member_access_dummy_vars (new_stmt);
   11866                 :       46675 :   BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
   11867                 :       46675 :   if (BLOCK_VARS (block))
   11868                 :       46242 :     TREE_USED (block) = 1;
   11869                 :             : 
   11870                 :       46675 :   gimple_bind_set_body (new_stmt, body);
   11871                 :       46675 :   gimple_omp_set_body (stmt, NULL);
   11872                 :       46675 :   gimple_omp_for_set_pre_body (stmt, NULL);
   11873                 :       46675 : }
   11874                 :             : 
   11875                 :             : /* Callback for walk_stmts.  Check if the current statement only contains
   11876                 :             :    GIMPLE_OMP_FOR or GIMPLE_OMP_SECTIONS.  */
   11877                 :             : 
   11878                 :             : static tree
   11879                 :      211096 : check_combined_parallel (gimple_stmt_iterator *gsi_p,
   11880                 :             :                          bool *handled_ops_p,
   11881                 :             :                          struct walk_stmt_info *wi)
   11882                 :             : {
   11883                 :      211096 :   int *info = (int *) wi->info;
   11884                 :      211096 :   gimple *stmt = gsi_stmt (*gsi_p);
   11885                 :             : 
   11886                 :      211096 :   *handled_ops_p = true;
   11887                 :      211096 :   switch (gimple_code (stmt))
   11888                 :             :     {
   11889                 :       11081 :     WALK_SUBSTMTS;
   11890                 :             : 
   11891                 :             :     case GIMPLE_DEBUG:
   11892                 :             :       break;
   11893                 :        1822 :     case GIMPLE_OMP_FOR:
   11894                 :        1822 :     case GIMPLE_OMP_SECTIONS:
   11895                 :        1822 :       *info = *info == 0 ? 1 : -1;
   11896                 :        1822 :       break;
   11897                 :      198154 :     default:
   11898                 :      198154 :       *info = -1;
   11899                 :      198154 :       break;
   11900                 :             :     }
   11901                 :      211096 :   return NULL;
   11902                 :             : }
   11903                 :             : 
   11904                 :             : struct omp_taskcopy_context
   11905                 :             : {
   11906                 :             :   /* This field must be at the beginning, as we do "inheritance": Some
   11907                 :             :      callback functions for tree-inline.cc (e.g., omp_copy_decl)
   11908                 :             :      receive a copy_body_data pointer that is up-casted to an
   11909                 :             :      omp_context pointer.  */
   11910                 :             :   copy_body_data cb;
   11911                 :             :   omp_context *ctx;
   11912                 :             : };
   11913                 :             : 
   11914                 :             : static tree
   11915                 :         366 : task_copyfn_copy_decl (tree var, copy_body_data *cb)
   11916                 :             : {
   11917                 :         366 :   struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
   11918                 :             : 
   11919                 :         366 :   if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
   11920                 :         158 :     return create_tmp_var (TREE_TYPE (var));
   11921                 :             : 
   11922                 :             :   return var;
   11923                 :             : }
   11924                 :             : 
   11925                 :             : static tree
   11926                 :          50 : task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
   11927                 :             : {
   11928                 :          50 :   tree name, new_fields = NULL, type, f;
   11929                 :             : 
   11930                 :          50 :   type = lang_hooks.types.make_type (RECORD_TYPE);
   11931                 :          50 :   name = DECL_NAME (TYPE_NAME (orig_type));
   11932                 :          50 :   name = build_decl (gimple_location (tcctx->ctx->stmt),
   11933                 :             :                      TYPE_DECL, name, type);
   11934                 :          50 :   TYPE_NAME (type) = name;
   11935                 :             : 
   11936                 :        1140 :   for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
   11937                 :             :     {
   11938                 :        1090 :       tree new_f = copy_node (f);
   11939                 :        1090 :       DECL_CONTEXT (new_f) = type;
   11940                 :        1090 :       TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
   11941                 :        1090 :       TREE_CHAIN (new_f) = new_fields;
   11942                 :        1090 :       walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
   11943                 :        1090 :       walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
   11944                 :        1090 :       walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
   11945                 :             :                  &tcctx->cb, NULL);
   11946                 :        1090 :       new_fields = new_f;
   11947                 :        1090 :       tcctx->cb.decl_map->put (f, new_f);
   11948                 :             :     }
   11949                 :          50 :   TYPE_FIELDS (type) = nreverse (new_fields);
   11950                 :          50 :   layout_type (type);
   11951                 :          50 :   return type;
   11952                 :             : }
   11953                 :             : 
   11954                 :             : /* Create task copyfn.  */
   11955                 :             : 
   11956                 :             : static void
   11957                 :         549 : create_task_copyfn (gomp_task *task_stmt, omp_context *ctx)
   11958                 :             : {
   11959                 :         549 :   struct function *child_cfun;
   11960                 :         549 :   tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
   11961                 :         549 :   tree record_type, srecord_type, bind, list;
   11962                 :         549 :   bool record_needs_remap = false, srecord_needs_remap = false;
   11963                 :         549 :   splay_tree_node n;
   11964                 :         549 :   struct omp_taskcopy_context tcctx;
   11965                 :         549 :   location_t loc = gimple_location (task_stmt);
   11966                 :         549 :   size_t looptempno = 0;
   11967                 :             : 
   11968                 :         549 :   child_fn = gimple_omp_task_copy_fn (task_stmt);
   11969                 :         549 :   task_cpyfns.safe_push (task_stmt);
   11970                 :         549 :   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
   11971                 :         549 :   gcc_assert (child_cfun->cfg == NULL);
   11972                 :         549 :   DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
   11973                 :             : 
   11974                 :             :   /* Reset DECL_CONTEXT on function arguments.  */
   11975                 :        1647 :   for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
   11976                 :        1098 :     DECL_CONTEXT (t) = child_fn;
   11977                 :             : 
   11978                 :             :   /* Populate the function.  */
   11979                 :         549 :   push_gimplify_context ();
   11980                 :         549 :   push_cfun (child_cfun);
   11981                 :             : 
   11982                 :         549 :   bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
   11983                 :         549 :   TREE_SIDE_EFFECTS (bind) = 1;
   11984                 :         549 :   list = NULL;
   11985                 :         549 :   DECL_SAVED_TREE (child_fn) = bind;
   11986                 :         549 :   DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
   11987                 :             : 
   11988                 :             :   /* Remap src and dst argument types if needed.  */
   11989                 :         549 :   record_type = ctx->record_type;
   11990                 :         549 :   srecord_type = ctx->srecord_type;
   11991                 :        3568 :   for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
   11992                 :        3044 :     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
   11993                 :             :       {
   11994                 :             :         record_needs_remap = true;
   11995                 :             :         break;
   11996                 :             :       }
   11997                 :        3277 :   for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
   11998                 :        2753 :     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
   11999                 :             :       {
   12000                 :             :         srecord_needs_remap = true;
   12001                 :             :         break;
   12002                 :             :       }
   12003                 :             : 
   12004                 :         549 :   if (record_needs_remap || srecord_needs_remap)
   12005                 :             :     {
   12006                 :          25 :       memset (&tcctx, '\0', sizeof (tcctx));
   12007                 :          25 :       tcctx.cb.src_fn = ctx->cb.src_fn;
   12008                 :          25 :       tcctx.cb.dst_fn = child_fn;
   12009                 :          25 :       tcctx.cb.src_node = cgraph_node::get (tcctx.cb.src_fn);
   12010                 :          25 :       gcc_checking_assert (tcctx.cb.src_node);
   12011                 :          25 :       tcctx.cb.dst_node = tcctx.cb.src_node;
   12012                 :          25 :       tcctx.cb.src_cfun = ctx->cb.src_cfun;
   12013                 :          25 :       tcctx.cb.copy_decl = task_copyfn_copy_decl;
   12014                 :          25 :       tcctx.cb.eh_lp_nr = 0;
   12015                 :          25 :       tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
   12016                 :          25 :       tcctx.cb.decl_map = new hash_map<tree, tree>;
   12017                 :          25 :       tcctx.ctx = ctx;
   12018                 :             : 
   12019                 :          25 :       if (record_needs_remap)
   12020                 :          25 :         record_type = task_copyfn_remap_type (&tcctx, record_type);
   12021                 :          25 :       if (srecord_needs_remap)
   12022                 :          25 :         srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
   12023                 :             :     }
   12024                 :             :   else
   12025                 :         524 :     tcctx.cb.decl_map = NULL;
   12026                 :             : 
   12027                 :         549 :   arg = DECL_ARGUMENTS (child_fn);
   12028                 :         549 :   TREE_TYPE (arg) = build_pointer_type (record_type);
   12029                 :         549 :   sarg = DECL_CHAIN (arg);
   12030                 :         549 :   TREE_TYPE (sarg) = build_pointer_type (srecord_type);
   12031                 :             : 
   12032                 :             :   /* First pass: initialize temporaries used in record_type and srecord_type
   12033                 :             :      sizes and field offsets.  */
   12034                 :         549 :   if (tcctx.cb.decl_map)
   12035                 :         631 :     for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   12036                 :         606 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   12037                 :             :         {
   12038                 :         497 :           tree *p;
   12039                 :             : 
   12040                 :         497 :           decl = OMP_CLAUSE_DECL (c);
   12041                 :         497 :           p = tcctx.cb.decl_map->get (decl);
   12042                 :         497 :           if (p == NULL)
   12043                 :         339 :             continue;
   12044                 :         158 :           n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
   12045                 :         158 :           sf = (tree) n->value;
   12046                 :         158 :           sf = *tcctx.cb.decl_map->get (sf);
   12047                 :         158 :           src = build_simple_mem_ref_loc (loc, sarg);
   12048                 :         158 :           src = omp_build_component_ref (src, sf);
   12049                 :         158 :           t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
   12050                 :         158 :           append_to_statement_list (t, &list);
   12051                 :             :         }
   12052                 :             : 
   12053                 :             :   /* Second pass: copy shared var pointers and copy construct non-VLA
   12054                 :             :      firstprivate vars.  */
   12055                 :        6571 :   for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   12056                 :        6022 :     switch (OMP_CLAUSE_CODE (c))
   12057                 :             :       {
   12058                 :         643 :         splay_tree_key key;
   12059                 :         643 :       case OMP_CLAUSE_SHARED:
   12060                 :         643 :         decl = OMP_CLAUSE_DECL (c);
   12061                 :         643 :         key = (splay_tree_key) decl;
   12062                 :         643 :         if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
   12063                 :         300 :           key = (splay_tree_key) &DECL_UID (decl);
   12064                 :         643 :         n = splay_tree_lookup (ctx->field_map, key);
   12065                 :         643 :         if (n == NULL)
   12066                 :             :           break;
   12067                 :         160 :         f = (tree) n->value;
   12068                 :         160 :         if (tcctx.cb.decl_map)
   12069                 :          12 :           f = *tcctx.cb.decl_map->get (f);
   12070                 :         160 :         n = splay_tree_lookup (ctx->sfield_map, key);
   12071                 :         160 :         sf = (tree) n->value;
   12072                 :         160 :         if (tcctx.cb.decl_map)
   12073                 :          12 :           sf = *tcctx.cb.decl_map->get (sf);
   12074                 :         160 :         src = build_simple_mem_ref_loc (loc, sarg);
   12075                 :         160 :         src = omp_build_component_ref (src, sf);
   12076                 :         160 :         dst = build_simple_mem_ref_loc (loc, arg);
   12077                 :         160 :         dst = omp_build_component_ref (dst, f);
   12078                 :         160 :         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
   12079                 :         160 :         append_to_statement_list (t, &list);
   12080                 :         160 :         break;
   12081                 :         684 :       case OMP_CLAUSE_REDUCTION:
   12082                 :         684 :       case OMP_CLAUSE_IN_REDUCTION:
   12083                 :         684 :         decl = OMP_CLAUSE_DECL (c);
   12084                 :         684 :         if (TREE_CODE (decl) == MEM_REF)
   12085                 :             :           {
   12086                 :         352 :             decl = TREE_OPERAND (decl, 0);
   12087                 :         352 :             if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
   12088                 :          98 :               decl = TREE_OPERAND (decl, 0);
   12089                 :         352 :             if (TREE_CODE (decl) == INDIRECT_REF
   12090                 :         278 :                 || TREE_CODE (decl) == ADDR_EXPR)
   12091                 :          74 :               decl = TREE_OPERAND (decl, 0);
   12092                 :             :           }
   12093                 :         684 :         key = (splay_tree_key) decl;
   12094                 :         684 :         n = splay_tree_lookup (ctx->field_map, key);
   12095                 :         684 :         if (n == NULL)
   12096                 :             :           break;
   12097                 :         279 :         f = (tree) n->value;
   12098                 :         279 :         if (tcctx.cb.decl_map)
   12099                 :          20 :           f = *tcctx.cb.decl_map->get (f);
   12100                 :         279 :         n = splay_tree_lookup (ctx->sfield_map, key);
   12101                 :         279 :         sf = (tree) n->value;
   12102                 :         279 :         if (tcctx.cb.decl_map)
   12103                 :          20 :           sf = *tcctx.cb.decl_map->get (sf);
   12104                 :         279 :         src = build_simple_mem_ref_loc (loc, sarg);
   12105                 :         279 :         src = omp_build_component_ref (src, sf);
   12106                 :         279 :         if (decl != OMP_CLAUSE_DECL (c)
   12107                 :         273 :             && TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   12108                 :         552 :             && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
   12109                 :          72 :           src = build_simple_mem_ref_loc (loc, src);
   12110                 :         279 :         dst = build_simple_mem_ref_loc (loc, arg);
   12111                 :         279 :         dst = omp_build_component_ref (dst, f);
   12112                 :         279 :         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
   12113                 :         279 :         append_to_statement_list (t, &list);
   12114                 :         279 :         break;
   12115                 :         808 :       case OMP_CLAUSE__LOOPTEMP_:
   12116                 :             :         /* Fields for first two _looptemp_ clauses are initialized by
   12117                 :             :            GOMP_taskloop*, the rest are handled like firstprivate.  */
   12118                 :         808 :         if (looptempno < 2)
   12119                 :             :           {
   12120                 :         802 :             looptempno++;
   12121                 :         802 :             break;
   12122                 :             :           }
   12123                 :             :         /* FALLTHRU */
   12124                 :        1909 :       case OMP_CLAUSE__REDUCTEMP_:
   12125                 :        1909 :       case OMP_CLAUSE_FIRSTPRIVATE:
   12126                 :        1909 :         decl = OMP_CLAUSE_DECL (c);
   12127                 :        1909 :         if (is_variable_sized (decl))
   12128                 :             :           break;
   12129                 :        1895 :         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
   12130                 :        1895 :         if (n == NULL)
   12131                 :             :           break;
   12132                 :        1895 :         f = (tree) n->value;
   12133                 :        1895 :         if (tcctx.cb.decl_map)
   12134                 :         490 :           f = *tcctx.cb.decl_map->get (f);
   12135                 :        1895 :         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
   12136                 :        1895 :         if (n != NULL)
   12137                 :             :           {
   12138                 :        1615 :             sf = (tree) n->value;
   12139                 :        1615 :             if (tcctx.cb.decl_map)
   12140                 :         490 :               sf = *tcctx.cb.decl_map->get (sf);
   12141                 :        1615 :             src = build_simple_mem_ref_loc (loc, sarg);
   12142                 :        1615 :             src = omp_build_component_ref (src, sf);
   12143                 :        1615 :             if (use_pointer_for_field (decl, NULL)
   12144                 :        1615 :                 || omp_privatize_by_reference (decl))
   12145                 :         320 :               src = build_simple_mem_ref_loc (loc, src);
   12146                 :             :           }
   12147                 :             :         else
   12148                 :             :           src = decl;
   12149                 :        1895 :         dst = build_simple_mem_ref_loc (loc, arg);
   12150                 :        1895 :         dst = omp_build_component_ref (dst, f);
   12151                 :        1895 :         if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
   12152                 :         212 :           t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
   12153                 :             :         else
   12154                 :             :           {
   12155                 :        1683 :             if (ctx->allocate_map)
   12156                 :          78 :               if (tree *allocatorp = ctx->allocate_map->get (decl))
   12157                 :             :                 {
   12158                 :          44 :                   tree allocator = *allocatorp;
   12159                 :          44 :                   HOST_WIDE_INT ialign = 0;
   12160                 :          44 :                   if (TREE_CODE (allocator) == TREE_LIST)
   12161                 :             :                     {
   12162                 :           4 :                       ialign = tree_to_uhwi (TREE_VALUE (allocator));
   12163                 :           4 :                       allocator = TREE_PURPOSE (allocator);
   12164                 :             :                     }
   12165                 :          44 :                   if (TREE_CODE (allocator) != INTEGER_CST)
   12166                 :             :                     {
   12167                 :          22 :                       n = splay_tree_lookup (ctx->sfield_map,
   12168                 :             :                                              (splay_tree_key) allocator);
   12169                 :          22 :                       allocator = (tree) n->value;
   12170                 :          22 :                       if (tcctx.cb.decl_map)
   12171                 :           0 :                         allocator = *tcctx.cb.decl_map->get (allocator);
   12172                 :          22 :                       tree a = build_simple_mem_ref_loc (loc, sarg);
   12173                 :          22 :                       allocator = omp_build_component_ref (a, allocator);
   12174                 :             :                     }
   12175                 :          44 :                   allocator = fold_convert (pointer_sized_int_node, allocator);
   12176                 :          44 :                   tree a = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
   12177                 :          44 :                   tree align = build_int_cst (size_type_node,
   12178                 :          44 :                                               MAX (ialign,
   12179                 :             :                                                    DECL_ALIGN_UNIT (decl)));
   12180                 :          44 :                   tree sz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (dst)));
   12181                 :          44 :                   tree ptr = build_call_expr_loc (loc, a, 3, align, sz,
   12182                 :             :                                                   allocator);
   12183                 :          44 :                   ptr = fold_convert (TREE_TYPE (dst), ptr);
   12184                 :          44 :                   t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, ptr);
   12185                 :          44 :                   append_to_statement_list (t, &list);
   12186                 :          44 :                   dst = build_simple_mem_ref_loc (loc, dst);
   12187                 :             :                 }
   12188                 :        1683 :             t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
   12189                 :             :           }
   12190                 :        1895 :         append_to_statement_list (t, &list);
   12191                 :        1895 :         break;
   12192                 :         516 :       case OMP_CLAUSE_PRIVATE:
   12193                 :         516 :         if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
   12194                 :             :           break;
   12195                 :          12 :         decl = OMP_CLAUSE_DECL (c);
   12196                 :          12 :         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
   12197                 :          12 :         f = (tree) n->value;
   12198                 :          12 :         if (tcctx.cb.decl_map)
   12199                 :           0 :           f = *tcctx.cb.decl_map->get (f);
   12200                 :          12 :         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
   12201                 :          12 :         if (n != NULL)
   12202                 :             :           {
   12203                 :          12 :             sf = (tree) n->value;
   12204                 :          12 :             if (tcctx.cb.decl_map)
   12205                 :           0 :               sf = *tcctx.cb.decl_map->get (sf);
   12206                 :          12 :             src = build_simple_mem_ref_loc (loc, sarg);
   12207                 :          12 :             src = omp_build_component_ref (src, sf);
   12208                 :          12 :             if (use_pointer_for_field (decl, NULL))
   12209                 :          12 :               src = build_simple_mem_ref_loc (loc, src);
   12210                 :             :           }
   12211                 :             :         else
   12212                 :             :           src = decl;
   12213                 :          12 :         dst = build_simple_mem_ref_loc (loc, arg);
   12214                 :          12 :         dst = omp_build_component_ref (dst, f);
   12215                 :          12 :         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
   12216                 :          12 :         append_to_statement_list (t, &list);
   12217                 :          12 :         break;
   12218                 :             :       default:
   12219                 :             :         break;
   12220                 :             :       }
   12221                 :             : 
   12222                 :             :   /* Last pass: handle VLA firstprivates.  */
   12223                 :         549 :   if (tcctx.cb.decl_map)
   12224                 :         631 :     for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   12225                 :         606 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   12226                 :             :         {
   12227                 :         497 :           tree ind, ptr, df;
   12228                 :             : 
   12229                 :         497 :           decl = OMP_CLAUSE_DECL (c);
   12230                 :         497 :           if (!is_variable_sized (decl))
   12231                 :         483 :             continue;
   12232                 :          14 :           n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
   12233                 :          14 :           if (n == NULL)
   12234                 :           0 :             continue;
   12235                 :          14 :           f = (tree) n->value;
   12236                 :          14 :           f = *tcctx.cb.decl_map->get (f);
   12237                 :          14 :           gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
   12238                 :          14 :           ind = DECL_VALUE_EXPR (decl);
   12239                 :          14 :           gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
   12240                 :          14 :           gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
   12241                 :          42 :           n = splay_tree_lookup (ctx->sfield_map,
   12242                 :          14 :                                  (splay_tree_key) TREE_OPERAND (ind, 0));
   12243                 :          14 :           sf = (tree) n->value;
   12244                 :          14 :           sf = *tcctx.cb.decl_map->get (sf);
   12245                 :          14 :           src = build_simple_mem_ref_loc (loc, sarg);
   12246                 :          14 :           src = omp_build_component_ref (src, sf);
   12247                 :          14 :           src = build_simple_mem_ref_loc (loc, src);
   12248                 :          14 :           dst = build_simple_mem_ref_loc (loc, arg);
   12249                 :          14 :           dst = omp_build_component_ref (dst, f);
   12250                 :          14 :           t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
   12251                 :          14 :           append_to_statement_list (t, &list);
   12252                 :          42 :           n = splay_tree_lookup (ctx->field_map,
   12253                 :          14 :                                  (splay_tree_key) TREE_OPERAND (ind, 0));
   12254                 :          14 :           df = (tree) n->value;
   12255                 :          14 :           df = *tcctx.cb.decl_map->get (df);
   12256                 :          14 :           ptr = build_simple_mem_ref_loc (loc, arg);
   12257                 :          14 :           ptr = omp_build_component_ref (ptr, df);
   12258                 :          14 :           t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
   12259                 :             :                       build_fold_addr_expr_loc (loc, dst));
   12260                 :          14 :           append_to_statement_list (t, &list);
   12261                 :             :         }
   12262                 :             : 
   12263                 :         549 :   t = build1 (RETURN_EXPR, void_type_node, NULL);
   12264                 :         549 :   append_to_statement_list (t, &list);
   12265                 :             : 
   12266                 :         549 :   if (tcctx.cb.decl_map)
   12267                 :          25 :     delete tcctx.cb.decl_map;
   12268                 :         549 :   pop_gimplify_context (NULL);
   12269                 :         549 :   BIND_EXPR_BODY (bind) = list;
   12270                 :         549 :   pop_cfun ();
   12271                 :         549 : }
   12272                 :             : 
   12273                 :             : static void
   12274                 :        1549 : lower_depend_clauses (tree *pclauses, gimple_seq *iseq, gimple_seq *oseq)
   12275                 :             : {
   12276                 :        1549 :   tree c, clauses;
   12277                 :        1549 :   gimple *g;
   12278                 :        1549 :   size_t cnt[5] = { 0, 0, 0, 0, 0 }, idx = 2, i;
   12279                 :             : 
   12280                 :        1549 :   clauses = omp_find_clause (*pclauses, OMP_CLAUSE_DEPEND);
   12281                 :        1549 :   gcc_assert (clauses);
   12282                 :        6332 :   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   12283                 :        4914 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   12284                 :        1711 :       switch (OMP_CLAUSE_DEPEND_KIND (c))
   12285                 :             :         {
   12286                 :         131 :         case OMP_CLAUSE_DEPEND_LAST:
   12287                 :             :           /* Lowering already done at gimplification.  */
   12288                 :         131 :           return;
   12289                 :         476 :         case OMP_CLAUSE_DEPEND_IN:
   12290                 :         476 :           cnt[2]++;
   12291                 :         476 :           break;
   12292                 :         979 :         case OMP_CLAUSE_DEPEND_OUT:
   12293                 :         979 :         case OMP_CLAUSE_DEPEND_INOUT:
   12294                 :         979 :           cnt[0]++;
   12295                 :         979 :           break;
   12296                 :          30 :         case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
   12297                 :          30 :           cnt[1]++;
   12298                 :          30 :           break;
   12299                 :          67 :         case OMP_CLAUSE_DEPEND_DEPOBJ:
   12300                 :          67 :           cnt[3]++;
   12301                 :          67 :           break;
   12302                 :          28 :         case OMP_CLAUSE_DEPEND_INOUTSET:
   12303                 :          28 :           cnt[4]++;
   12304                 :          28 :           break;
   12305                 :           0 :         default:
   12306                 :           0 :           gcc_unreachable ();
   12307                 :             :         }
   12308                 :        1418 :   if (cnt[1] || cnt[3] || cnt[4])
   12309                 :         122 :     idx = 5;
   12310                 :        1418 :   size_t total = cnt[0] + cnt[1] + cnt[2] + cnt[3] + cnt[4];
   12311                 :        1418 :   size_t inoutidx = total + idx;
   12312                 :        1418 :   tree type = build_array_type_nelts (ptr_type_node, total + idx + 2 * cnt[4]);
   12313                 :        1418 :   tree array = create_tmp_var (type);
   12314                 :        1418 :   TREE_ADDRESSABLE (array) = 1;
   12315                 :        1418 :   tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
   12316                 :             :                    NULL_TREE);
   12317                 :        1418 :   if (idx == 5)
   12318                 :             :     {
   12319                 :         122 :       g = gimple_build_assign (r, build_int_cst (ptr_type_node, 0));
   12320                 :         122 :       gimple_seq_add_stmt (iseq, g);
   12321                 :         122 :       r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
   12322                 :             :                   NULL_TREE);
   12323                 :             :     }
   12324                 :        1418 :   g = gimple_build_assign (r, build_int_cst (ptr_type_node, total));
   12325                 :        1418 :   gimple_seq_add_stmt (iseq, g);
   12326                 :        7090 :   for (i = 0; i < (idx == 5 ? 3 : 1); i++)
   12327                 :             :     {
   12328                 :        1662 :       r = build4 (ARRAY_REF, ptr_type_node, array,
   12329                 :        1662 :                   size_int (i + 1 + (idx == 5)), NULL_TREE, NULL_TREE);
   12330                 :        1662 :       g = gimple_build_assign (r, build_int_cst (ptr_type_node, cnt[i]));
   12331                 :        1662 :       gimple_seq_add_stmt (iseq, g);
   12332                 :             :     }
   12333                 :        8508 :   for (i = 0; i < 5; i++)
   12334                 :             :     {
   12335                 :        7090 :       if (cnt[i] == 0)
   12336                 :        5617 :         continue;
   12337                 :        6569 :       for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   12338                 :        5096 :         if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
   12339                 :        3382 :           continue;
   12340                 :             :         else
   12341                 :             :           {
   12342                 :        1714 :             switch (OMP_CLAUSE_DEPEND_KIND (c))
   12343                 :             :               {
   12344                 :         539 :               case OMP_CLAUSE_DEPEND_IN:
   12345                 :         539 :                 if (i != 2)
   12346                 :         134 :                   continue;
   12347                 :             :                 break;
   12348                 :        1033 :               case OMP_CLAUSE_DEPEND_OUT:
   12349                 :        1033 :               case OMP_CLAUSE_DEPEND_INOUT:
   12350                 :        1033 :                 if (i != 0)
   12351                 :          54 :                   continue;
   12352                 :             :                 break;
   12353                 :          44 :               case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
   12354                 :          44 :                 if (i != 1)
   12355                 :          14 :                   continue;
   12356                 :             :                 break;
   12357                 :          70 :               case OMP_CLAUSE_DEPEND_DEPOBJ:
   12358                 :          70 :                 if (i != 3)
   12359                 :           3 :                   continue;
   12360                 :             :                 break;
   12361                 :          28 :               case OMP_CLAUSE_DEPEND_INOUTSET:
   12362                 :          28 :                 if (i != 4)
   12363                 :           0 :                    continue;
   12364                 :             :                 break;
   12365                 :           0 :               default:
   12366                 :           0 :                 gcc_unreachable ();
   12367                 :             :               }
   12368                 :        1580 :             tree t = OMP_CLAUSE_DECL (c);
   12369                 :        1580 :             if (i == 4)
   12370                 :             :               {
   12371                 :          28 :                 t = build4 (ARRAY_REF, ptr_type_node, array,
   12372                 :             :                             size_int (inoutidx), NULL_TREE, NULL_TREE);
   12373                 :          28 :                 t = build_fold_addr_expr (t);
   12374                 :          28 :                 inoutidx += 2;
   12375                 :             :               }
   12376                 :        1580 :             t = fold_convert (ptr_type_node, t);
   12377                 :        1580 :             gimplify_expr (&t, iseq, NULL, is_gimple_val, fb_rvalue);
   12378                 :        1580 :             r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
   12379                 :             :                         NULL_TREE, NULL_TREE);
   12380                 :        1580 :             g = gimple_build_assign (r, t);
   12381                 :        1580 :             gimple_seq_add_stmt (iseq, g);
   12382                 :             :           }
   12383                 :             :     }
   12384                 :        1418 :   if (cnt[4])
   12385                 :          73 :     for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   12386                 :          45 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
   12387                 :          45 :           && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_INOUTSET)
   12388                 :             :         {
   12389                 :          28 :           tree t = OMP_CLAUSE_DECL (c);
   12390                 :          28 :           t = fold_convert (ptr_type_node, t);
   12391                 :          28 :           gimplify_expr (&t, iseq, NULL, is_gimple_val, fb_rvalue);
   12392                 :          28 :           r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
   12393                 :             :                       NULL_TREE, NULL_TREE);
   12394                 :          28 :           g = gimple_build_assign (r, t);
   12395                 :          28 :           gimple_seq_add_stmt (iseq, g);
   12396                 :          28 :           t = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
   12397                 :          28 :           r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
   12398                 :             :                       NULL_TREE, NULL_TREE);
   12399                 :          28 :           g = gimple_build_assign (r, t);
   12400                 :          28 :           gimple_seq_add_stmt (iseq, g);
   12401                 :             :         }
   12402                 :             : 
   12403                 :        1418 :   c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
   12404                 :        1418 :   OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
   12405                 :        1418 :   OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
   12406                 :        1418 :   OMP_CLAUSE_CHAIN (c) = *pclauses;
   12407                 :        1418 :   *pclauses = c;
   12408                 :        1418 :   tree clobber = build_clobber (type);
   12409                 :        1418 :   g = gimple_build_assign (array, clobber);
   12410                 :        1418 :   gimple_seq_add_stmt (oseq, g);
   12411                 :             : }
   12412                 :             : 
   12413                 :             : /* Lower the OpenMP parallel or task directive in the current statement
   12414                 :             :    in GSI_P.  CTX holds context information for the directive.  */
   12415                 :             : 
   12416                 :             : static void
   12417                 :       22562 : lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   12418                 :             : {
   12419                 :       22562 :   tree clauses;
   12420                 :       22562 :   tree child_fn, t;
   12421                 :       22562 :   gimple *stmt = gsi_stmt (*gsi_p);
   12422                 :       22562 :   gbind *par_bind, *bind, *dep_bind = NULL;
   12423                 :       22562 :   gimple_seq par_body;
   12424                 :       22562 :   location_t loc = gimple_location (stmt);
   12425                 :             : 
   12426                 :       22562 :   clauses = gimple_omp_taskreg_clauses (stmt);
   12427                 :       22562 :   if (gimple_code (stmt) == GIMPLE_OMP_TASK
   12428                 :       22562 :       && gimple_omp_task_taskwait_p (stmt))
   12429                 :             :     {
   12430                 :          57 :       par_bind = NULL;
   12431                 :          57 :       par_body = NULL;
   12432                 :             :     }
   12433                 :             :   else
   12434                 :             :     {
   12435                 :       22505 :       par_bind
   12436                 :       22505 :         = as_a <gbind *> (gimple_seq_first_stmt (gimple_omp_body (stmt)));
   12437                 :       22505 :       par_body = gimple_bind_body (par_bind);
   12438                 :             :     }
   12439                 :       22562 :   child_fn = ctx->cb.dst_fn;
   12440                 :       22562 :   if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
   12441                 :       22562 :       && !gimple_omp_parallel_combined_p (stmt))
   12442                 :             :     {
   12443                 :        4288 :       struct walk_stmt_info wi;
   12444                 :        4288 :       int ws_num = 0;
   12445                 :             : 
   12446                 :        4288 :       memset (&wi, 0, sizeof (wi));
   12447                 :        4288 :       wi.info = &ws_num;
   12448                 :        4288 :       wi.val_only = true;
   12449                 :        4288 :       walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
   12450                 :        4288 :       if (ws_num == 1)
   12451                 :         408 :         gimple_omp_parallel_set_combined_p (stmt, true);
   12452                 :             :     }
   12453                 :       22562 :   gimple_seq dep_ilist = NULL;
   12454                 :       22562 :   gimple_seq dep_olist = NULL;
   12455                 :       22562 :   if (gimple_code (stmt) == GIMPLE_OMP_TASK
   12456                 :       22562 :       && omp_find_clause (clauses, OMP_CLAUSE_DEPEND))
   12457                 :             :     {
   12458                 :        1200 :       push_gimplify_context ();
   12459                 :        1200 :       dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
   12460                 :        1200 :       lower_depend_clauses (gimple_omp_task_clauses_ptr (stmt),
   12461                 :             :                             &dep_ilist, &dep_olist);
   12462                 :             :     }
   12463                 :             : 
   12464                 :       22562 :   if (gimple_code (stmt) == GIMPLE_OMP_TASK
   12465                 :       22562 :       && gimple_omp_task_taskwait_p (stmt))
   12466                 :             :     {
   12467                 :          57 :       if (dep_bind)
   12468                 :             :         {
   12469                 :          57 :           gsi_replace (gsi_p, dep_bind, true);
   12470                 :          57 :           gimple_bind_add_seq (dep_bind, dep_ilist);
   12471                 :          57 :           gimple_bind_add_stmt (dep_bind, stmt);
   12472                 :          57 :           gimple_bind_add_seq (dep_bind, dep_olist);
   12473                 :          57 :           pop_gimplify_context (dep_bind);
   12474                 :             :         }
   12475                 :          57 :       return;
   12476                 :             :     }
   12477                 :             : 
   12478                 :       22505 :   if (ctx->srecord_type)
   12479                 :         549 :     create_task_copyfn (as_a <gomp_task *> (stmt), ctx);
   12480                 :             : 
   12481                 :       22505 :   gimple_seq tskred_ilist = NULL;
   12482                 :       22505 :   gimple_seq tskred_olist = NULL;
   12483                 :       22505 :   if ((is_task_ctx (ctx)
   12484                 :        3935 :        && gimple_omp_task_taskloop_p (ctx->stmt)
   12485                 :        1394 :        && omp_find_clause (gimple_omp_task_clauses (ctx->stmt),
   12486                 :             :                            OMP_CLAUSE_REDUCTION))
   12487                 :       25881 :       || (is_parallel_ctx (ctx)
   12488                 :       15945 :           && omp_find_clause (gimple_omp_parallel_clauses (stmt),
   12489                 :             :                               OMP_CLAUSE__REDUCTEMP_)))
   12490                 :             :     {
   12491                 :         624 :       if (dep_bind == NULL)
   12492                 :             :         {
   12493                 :         624 :           push_gimplify_context ();
   12494                 :         624 :           dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
   12495                 :             :         }
   12496                 :         689 :       lower_omp_task_reductions (ctx, is_task_ctx (ctx) ? OMP_TASKLOOP
   12497                 :             :                                                         : OMP_PARALLEL,
   12498                 :         624 :                                  gimple_omp_taskreg_clauses (ctx->stmt),
   12499                 :             :                                  &tskred_ilist, &tskred_olist);
   12500                 :             :     }
   12501                 :             : 
   12502                 :       22505 :   push_gimplify_context ();
   12503                 :             : 
   12504                 :       22505 :   gimple_seq par_olist = NULL;
   12505                 :       22505 :   gimple_seq par_ilist = NULL;
   12506                 :       22505 :   gimple_seq par_rlist = NULL;
   12507                 :       22505 :   lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx, NULL);
   12508                 :       22501 :   lower_omp (&par_body, ctx);
   12509                 :       22501 :   if (gimple_code (stmt) != GIMPLE_OMP_TASK)
   12510                 :       18566 :     lower_reduction_clauses (clauses, &par_rlist, NULL, ctx);
   12511                 :             : 
   12512                 :             :   /* Declare all the variables created by mapping and the variables
   12513                 :             :      declared in the scope of the parallel body.  */
   12514                 :       22501 :   record_vars_into (ctx->block_vars, child_fn);
   12515                 :       22501 :   maybe_remove_omp_member_access_dummy_vars (par_bind);
   12516                 :       22501 :   record_vars_into (gimple_bind_vars (par_bind), child_fn);
   12517                 :             : 
   12518                 :       22501 :   if (ctx->record_type)
   12519                 :             :     {
   12520                 :       17960 :       ctx->sender_decl
   12521                 :       35371 :         = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
   12522                 :             :                           : ctx->record_type, ".omp_data_o");
   12523                 :       17960 :       DECL_NAMELESS (ctx->sender_decl) = 1;
   12524                 :       17960 :       TREE_ADDRESSABLE (ctx->sender_decl) = 1;
   12525                 :       17960 :       gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
   12526                 :             :     }
   12527                 :             : 
   12528                 :       22501 :   gimple_seq olist = NULL;
   12529                 :       22501 :   gimple_seq ilist = NULL;
   12530                 :       22501 :   lower_send_clauses (clauses, &ilist, &olist, ctx);
   12531                 :       22501 :   lower_send_shared_vars (&ilist, &olist, ctx);
   12532                 :             : 
   12533                 :       22501 :   if (ctx->record_type)
   12534                 :             :     {
   12535                 :       17960 :       tree clobber = build_clobber (TREE_TYPE (ctx->sender_decl));
   12536                 :       17960 :       gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
   12537                 :             :                                                         clobber));
   12538                 :             :     }
   12539                 :             : 
   12540                 :             :   /* Once all the expansions are done, sequence all the different
   12541                 :             :      fragments inside gimple_omp_body.  */
   12542                 :             : 
   12543                 :       22501 :   gimple_seq new_body = NULL;
   12544                 :             : 
   12545                 :       22501 :   if (ctx->record_type)
   12546                 :             :     {
   12547                 :       17960 :       t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
   12548                 :             :       /* fixup_child_record_type might have changed receiver_decl's type.  */
   12549                 :       17960 :       t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
   12550                 :       17960 :       gimple_seq_add_stmt (&new_body,
   12551                 :       17960 :                            gimple_build_assign (ctx->receiver_decl, t));
   12552                 :             :     }
   12553                 :             : 
   12554                 :       22501 :   gimple_seq_add_seq (&new_body, par_ilist);
   12555                 :       22501 :   gimple_seq_add_seq (&new_body, par_body);
   12556                 :       22501 :   gimple_seq_add_seq (&new_body, par_rlist);
   12557                 :       22501 :   if (ctx->cancellable)
   12558                 :         149 :     gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
   12559                 :       22501 :   gimple_seq_add_seq (&new_body, par_olist);
   12560                 :       22501 :   new_body = maybe_catch_exception (new_body);
   12561                 :       22501 :   if (gimple_code (stmt) == GIMPLE_OMP_TASK)
   12562                 :        3935 :     gimple_seq_add_stmt (&new_body,
   12563                 :        3935 :                          gimple_build_omp_continue (integer_zero_node,
   12564                 :             :                                                     integer_zero_node));
   12565                 :       22501 :   gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
   12566                 :       22501 :   gimple_omp_set_body (stmt, new_body);
   12567                 :             : 
   12568                 :       22501 :   if (dep_bind && gimple_bind_block (par_bind) == NULL_TREE)
   12569                 :         559 :     bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
   12570                 :             :   else
   12571                 :       21942 :     bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
   12572                 :       43235 :   gsi_replace (gsi_p, dep_bind ? dep_bind : bind, true);
   12573                 :       22501 :   gimple_bind_add_seq (bind, ilist);
   12574                 :       22501 :   gimple_bind_add_stmt (bind, stmt);
   12575                 :       22501 :   gimple_bind_add_seq (bind, olist);
   12576                 :             : 
   12577                 :       22501 :   pop_gimplify_context (NULL);
   12578                 :             : 
   12579                 :       22501 :   if (dep_bind)
   12580                 :             :     {
   12581                 :        1767 :       gimple_bind_add_seq (dep_bind, dep_ilist);
   12582                 :        1767 :       gimple_bind_add_seq (dep_bind, tskred_ilist);
   12583                 :        1767 :       gimple_bind_add_stmt (dep_bind, bind);
   12584                 :        1767 :       gimple_bind_add_seq (dep_bind, tskred_olist);
   12585                 :        1767 :       gimple_bind_add_seq (dep_bind, dep_olist);
   12586                 :        1767 :       pop_gimplify_context (dep_bind);
   12587                 :             :     }
   12588                 :             : }
   12589                 :             : 
   12590                 :             : /* Lower the GIMPLE_OMP_TARGET in the current statement
   12591                 :             :    in GSI_P.  CTX holds context information for the directive.  */
   12592                 :             : 
   12593                 :             : static void
   12594                 :       35389 : lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   12595                 :             : {
   12596                 :       35389 :   tree clauses;
   12597                 :       35389 :   tree child_fn, t, c;
   12598                 :       35389 :   gomp_target *stmt = as_a <gomp_target *> (gsi_stmt (*gsi_p));
   12599                 :       35389 :   gbind *tgt_bind, *bind, *dep_bind = NULL;
   12600                 :       35389 :   gimple_seq tgt_body, olist, ilist, fplist, new_body;
   12601                 :       35389 :   location_t loc = gimple_location (stmt);
   12602                 :       35389 :   bool offloaded, data_region;
   12603                 :       35389 :   unsigned int map_cnt = 0;
   12604                 :       35389 :   tree in_reduction_clauses = NULL_TREE;
   12605                 :             : 
   12606                 :       35389 :   offloaded = is_gimple_omp_offloaded (stmt);
   12607                 :       35389 :   switch (gimple_omp_target_kind (stmt))
   12608                 :             :     {
   12609                 :       10616 :     case GF_OMP_TARGET_KIND_REGION:
   12610                 :       10616 :       tree *p, *q;
   12611                 :       10616 :       q = &in_reduction_clauses;
   12612                 :       72724 :       for (p = gimple_omp_target_clauses_ptr (stmt); *p; )
   12613                 :       62108 :         if (OMP_CLAUSE_CODE (*p) == OMP_CLAUSE_IN_REDUCTION)
   12614                 :             :           {
   12615                 :         452 :             *q = *p;
   12616                 :         452 :             q = &OMP_CLAUSE_CHAIN (*q);
   12617                 :         452 :             *p = OMP_CLAUSE_CHAIN (*p);
   12618                 :             :           }
   12619                 :             :         else
   12620                 :       61656 :           p = &OMP_CLAUSE_CHAIN (*p);
   12621                 :       10616 :       *q = NULL_TREE;
   12622                 :       10616 :       *p = in_reduction_clauses;
   12623                 :             :       /* FALLTHRU */
   12624                 :             :     case GF_OMP_TARGET_KIND_UPDATE:
   12625                 :             :     case GF_OMP_TARGET_KIND_ENTER_DATA:
   12626                 :             :     case GF_OMP_TARGET_KIND_EXIT_DATA:
   12627                 :             :     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
   12628                 :             :     case GF_OMP_TARGET_KIND_OACC_KERNELS:
   12629                 :             :     case GF_OMP_TARGET_KIND_OACC_SERIAL:
   12630                 :             :     case GF_OMP_TARGET_KIND_OACC_UPDATE:
   12631                 :             :     case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
   12632                 :             :     case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
   12633                 :             :     case GF_OMP_TARGET_KIND_OACC_DECLARE:
   12634                 :             :     case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
   12635                 :             :     case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
   12636                 :             :       data_region = false;
   12637                 :             :       break;
   12638                 :             :     case GF_OMP_TARGET_KIND_DATA:
   12639                 :             :     case GF_OMP_TARGET_KIND_OACC_DATA:
   12640                 :             :     case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
   12641                 :             :     case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
   12642                 :             :       data_region = true;
   12643                 :             :       break;
   12644                 :           0 :     default:
   12645                 :           0 :       gcc_unreachable ();
   12646                 :             :     }
   12647                 :             : 
   12648                 :             :   /* Ensure that requires map is written via output_offload_tables, even if only
   12649                 :             :      'target (enter/exit) data' is used in the translation unit.  */
   12650                 :       35389 :   if (ENABLE_OFFLOADING && (omp_requires_mask & OMP_REQUIRES_TARGET_USED))
   12651                 :             :     g->have_offload = true;
   12652                 :             : 
   12653                 :       35389 :   clauses = gimple_omp_target_clauses (stmt);
   12654                 :             : 
   12655                 :       35389 :   gimple_seq dep_ilist = NULL;
   12656                 :       35389 :   gimple_seq dep_olist = NULL;
   12657                 :       35389 :   bool has_depend = omp_find_clause (clauses, OMP_CLAUSE_DEPEND) != NULL_TREE;
   12658                 :       35389 :   if (has_depend || in_reduction_clauses)
   12659                 :             :     {
   12660                 :         412 :       push_gimplify_context ();
   12661                 :         412 :       dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
   12662                 :         412 :       if (has_depend)
   12663                 :         349 :         lower_depend_clauses (gimple_omp_target_clauses_ptr (stmt),
   12664                 :             :                               &dep_ilist, &dep_olist);
   12665                 :         412 :       if (in_reduction_clauses)
   12666                 :         344 :         lower_rec_input_clauses (in_reduction_clauses, &dep_ilist, &dep_olist,
   12667                 :             :                                  ctx, NULL);
   12668                 :             :     }
   12669                 :             : 
   12670                 :       35389 :   tgt_bind = NULL;
   12671                 :       35389 :   tgt_body = NULL;
   12672                 :       35389 :   if (offloaded)
   12673                 :             :     {
   12674                 :       19742 :       tgt_bind = gimple_seq_first_stmt_as_a_bind (gimple_omp_body (stmt));
   12675                 :       19742 :       tgt_body = gimple_bind_body (tgt_bind);
   12676                 :             :     }
   12677                 :       15647 :   else if (data_region)
   12678                 :        4134 :     tgt_body = gimple_omp_body (stmt);
   12679                 :       35389 :   child_fn = ctx->cb.dst_fn;
   12680                 :             : 
   12681                 :       35389 :   push_gimplify_context ();
   12682                 :       35389 :   fplist = NULL;
   12683                 :             : 
   12684                 :      166696 :   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
   12685                 :      131307 :     switch (OMP_CLAUSE_CODE (c))
   12686                 :             :       {
   12687                 :             :         tree var, x;
   12688                 :             : 
   12689                 :             :       default:
   12690                 :             :         break;
   12691                 :       73165 :       case OMP_CLAUSE_MAP:
   12692                 :             : #if CHECKING_P
   12693                 :             :         /* First check what we're prepared to handle in the following.  */
   12694                 :       73165 :         switch (OMP_CLAUSE_MAP_KIND (c))
   12695                 :             :           {
   12696                 :             :           case GOMP_MAP_ALLOC:
   12697                 :             :           case GOMP_MAP_TO:
   12698                 :             :           case GOMP_MAP_FROM:
   12699                 :             :           case GOMP_MAP_TOFROM:
   12700                 :             :           case GOMP_MAP_POINTER:
   12701                 :             :           case GOMP_MAP_TO_PSET:
   12702                 :             :           case GOMP_MAP_DELETE:
   12703                 :             :           case GOMP_MAP_RELEASE:
   12704                 :             :           case GOMP_MAP_ALWAYS_TO:
   12705                 :             :           case GOMP_MAP_ALWAYS_FROM:
   12706                 :             :           case GOMP_MAP_ALWAYS_TOFROM:
   12707                 :             :           case GOMP_MAP_FORCE_PRESENT:
   12708                 :             :           case GOMP_MAP_ALWAYS_PRESENT_FROM:
   12709                 :             :           case GOMP_MAP_ALWAYS_PRESENT_TO:
   12710                 :             :           case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   12711                 :             : 
   12712                 :             :           case GOMP_MAP_FIRSTPRIVATE_POINTER:
   12713                 :             :           case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   12714                 :             :           case GOMP_MAP_STRUCT:
   12715                 :             :           case GOMP_MAP_STRUCT_UNORD:
   12716                 :             :           case GOMP_MAP_ALWAYS_POINTER:
   12717                 :             :           case GOMP_MAP_ATTACH:
   12718                 :             :           case GOMP_MAP_DETACH:
   12719                 :             :           case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   12720                 :             :           case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   12721                 :             :             break;
   12722                 :        2684 :           case GOMP_MAP_IF_PRESENT:
   12723                 :        2684 :           case GOMP_MAP_FORCE_ALLOC:
   12724                 :        2684 :           case GOMP_MAP_FORCE_TO:
   12725                 :        2684 :           case GOMP_MAP_FORCE_FROM:
   12726                 :        2684 :           case GOMP_MAP_FORCE_TOFROM:
   12727                 :        2684 :           case GOMP_MAP_FORCE_DEVICEPTR:
   12728                 :        2684 :           case GOMP_MAP_DEVICE_RESIDENT:
   12729                 :        2684 :           case GOMP_MAP_LINK:
   12730                 :        2684 :           case GOMP_MAP_FORCE_DETACH:
   12731                 :        2684 :             gcc_assert (is_gimple_omp_oacc (stmt));
   12732                 :             :             break;
   12733                 :           0 :           default:
   12734                 :           0 :             gcc_unreachable ();
   12735                 :             :           }
   12736                 :             : #endif
   12737                 :             :           /* FALLTHRU */
   12738                 :       84442 :       case OMP_CLAUSE_TO:
   12739                 :       84442 :       case OMP_CLAUSE_FROM:
   12740                 :       84442 :       oacc_firstprivate:
   12741                 :       84442 :         var = OMP_CLAUSE_DECL (c);
   12742                 :       84442 :         if (!DECL_P (var))
   12743                 :             :           {
   12744                 :       33868 :             if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
   12745                 :       33868 :                 || (!OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
   12746                 :       32408 :                     && (OMP_CLAUSE_MAP_KIND (c)
   12747                 :             :                         != GOMP_MAP_FIRSTPRIVATE_POINTER)))
   12748                 :       33868 :               map_cnt++;
   12749                 :       33868 :             continue;
   12750                 :             :           }
   12751                 :             : 
   12752                 :       50574 :         if (DECL_SIZE (var)
   12753                 :       50574 :             && TREE_CODE (DECL_SIZE (var)) != INTEGER_CST)
   12754                 :             :           {
   12755                 :         746 :             tree var2 = DECL_VALUE_EXPR (var);
   12756                 :         746 :             gcc_assert (TREE_CODE (var2) == INDIRECT_REF);
   12757                 :         746 :             var2 = TREE_OPERAND (var2, 0);
   12758                 :         746 :             gcc_assert (DECL_P (var2));
   12759                 :             :             var = var2;
   12760                 :             :           }
   12761                 :             : 
   12762                 :       50574 :         if (offloaded
   12763                 :       34969 :             && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   12764                 :       81799 :             && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   12765                 :       28015 :                 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   12766                 :             :           {
   12767                 :        3609 :             if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
   12768                 :             :               {
   12769                 :         363 :                 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx))
   12770                 :         363 :                     && varpool_node::get_create (var)->offloadable)
   12771                 :           2 :                   continue;
   12772                 :             : 
   12773                 :         361 :                 tree type = build_pointer_type (TREE_TYPE (var));
   12774                 :         361 :                 tree new_var = lookup_decl (var, ctx);
   12775                 :         361 :                 x = create_tmp_var_raw (type, get_name (new_var));
   12776                 :         361 :                 gimple_add_tmp_var (x);
   12777                 :         361 :                 x = build_simple_mem_ref (x);
   12778                 :         361 :                 SET_DECL_VALUE_EXPR (new_var, x);
   12779                 :         361 :                 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   12780                 :             :               }
   12781                 :        3607 :             continue;
   12782                 :        3607 :           }
   12783                 :             : 
   12784                 :       46965 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   12785                 :       37148 :             && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   12786                 :       36960 :                 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
   12787                 :       47199 :             && is_omp_target (stmt))
   12788                 :             :           {
   12789                 :         210 :             gcc_assert (maybe_lookup_field (c, ctx));
   12790                 :         210 :             map_cnt++;
   12791                 :         210 :             continue;
   12792                 :             :           }
   12793                 :             : 
   12794                 :       46755 :         if (!maybe_lookup_field (var, ctx))
   12795                 :        5738 :           continue;
   12796                 :             : 
   12797                 :             :         /* Don't remap compute constructs' reduction variables, because the
   12798                 :             :            intermediate result must be local to each gang.  */
   12799                 :       67101 :         if (offloaded && !(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   12800                 :       22340 :                            && is_gimple_omp_oacc (ctx->stmt)
   12801                 :       13383 :                            && OMP_CLAUSE_MAP_IN_REDUCTION (c)))
   12802                 :             :           {
   12803                 :       25553 :             x = build_receiver_ref (var, true, ctx);
   12804                 :       25553 :             tree new_var = lookup_decl (var, ctx);
   12805                 :             : 
   12806                 :       25553 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   12807                 :       21809 :                 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
   12808                 :        2855 :                 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
   12809                 :       28408 :                 && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
   12810                 :         425 :               x = build_simple_mem_ref (x);
   12811                 :       25553 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   12812                 :             :               {
   12813                 :        3744 :                 gcc_assert (is_gimple_omp_oacc (ctx->stmt));
   12814                 :        3744 :                 if (omp_privatize_by_reference (new_var)
   12815                 :        3744 :                     && (TREE_CODE (TREE_TYPE (new_var)) != POINTER_TYPE
   12816                 :          44 :                         || DECL_BY_REFERENCE (var)))
   12817                 :             :                   {
   12818                 :             :                     /* Create a local object to hold the instance
   12819                 :             :                        value.  */
   12820                 :         494 :                     tree type = TREE_TYPE (TREE_TYPE (new_var));
   12821                 :         494 :                     const char *id = IDENTIFIER_POINTER (DECL_NAME (new_var));
   12822                 :         494 :                     tree inst = create_tmp_var (type, id);
   12823                 :         494 :                     gimplify_assign (inst, fold_indirect_ref (x), &fplist);
   12824                 :         494 :                     x = build_fold_addr_expr (inst);
   12825                 :             :                   }
   12826                 :        3744 :                 gimplify_assign (new_var, x, &fplist);
   12827                 :             :               }
   12828                 :       21809 :             else if (DECL_P (new_var))
   12829                 :             :               {
   12830                 :       21809 :                 SET_DECL_VALUE_EXPR (new_var, x);
   12831                 :       21809 :                 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   12832                 :             :               }
   12833                 :             :             else
   12834                 :           0 :               gcc_unreachable ();
   12835                 :             :           }
   12836                 :       41017 :         map_cnt++;
   12837                 :       41017 :         break;
   12838                 :             : 
   12839                 :       14697 :       case OMP_CLAUSE_FIRSTPRIVATE:
   12840                 :       14697 :       omp_firstprivate_recv:
   12841                 :       14697 :         gcc_checking_assert (offloaded);
   12842                 :       14697 :         if (is_gimple_omp_oacc (ctx->stmt))
   12843                 :             :           {
   12844                 :             :             /* No 'firstprivate' clauses on OpenACC 'kernels'.  */
   12845                 :        3744 :             gcc_checking_assert (!is_oacc_kernels (ctx));
   12846                 :             :             /* Likewise, on OpenACC 'kernels' decomposed parts.  */
   12847                 :        3744 :             gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));
   12848                 :             : 
   12849                 :        3744 :             goto oacc_firstprivate;
   12850                 :             :           }
   12851                 :       10953 :         map_cnt++;
   12852                 :       10953 :         var = OMP_CLAUSE_DECL (c);
   12853                 :       10953 :         if (!omp_privatize_by_reference (var)
   12854                 :       10953 :             && !is_gimple_reg_type (TREE_TYPE (var)))
   12855                 :             :           {
   12856                 :         109 :             tree new_var = lookup_decl (var, ctx);
   12857                 :         109 :             if (is_variable_sized (var))
   12858                 :             :               {
   12859                 :           4 :                 tree pvar = DECL_VALUE_EXPR (var);
   12860                 :           4 :                 gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
   12861                 :           4 :                 pvar = TREE_OPERAND (pvar, 0);
   12862                 :           4 :                 gcc_assert (DECL_P (pvar));
   12863                 :           4 :                 tree new_pvar = lookup_decl (pvar, ctx);
   12864                 :           4 :                 x = build_fold_indirect_ref (new_pvar);
   12865                 :           4 :                 TREE_THIS_NOTRAP (x) = 1;
   12866                 :             :               }
   12867                 :             :             else
   12868                 :         105 :               x = build_receiver_ref (var, true, ctx);
   12869                 :         109 :             SET_DECL_VALUE_EXPR (new_var, x);
   12870                 :         109 :             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   12871                 :             :           }
   12872                 :             :           /* Fortran array descriptors: firstprivate of data + attach.  */
   12873                 :       10953 :           if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR
   12874                 :       10953 :               && lang_hooks.decls.omp_array_data (var, true))
   12875                 :          18 :             map_cnt += 2;
   12876                 :             :         break;
   12877                 :             : 
   12878                 :         179 :       case OMP_CLAUSE_PRIVATE:
   12879                 :         179 :         gcc_checking_assert (offloaded);
   12880                 :         179 :         if (is_gimple_omp_oacc (ctx->stmt))
   12881                 :             :           {
   12882                 :             :             /* No 'private' clauses on OpenACC 'kernels'.  */
   12883                 :          83 :             gcc_checking_assert (!is_oacc_kernels (ctx));
   12884                 :             :             /* Likewise, on OpenACC 'kernels' decomposed parts.  */
   12885                 :          83 :             gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));
   12886                 :             : 
   12887                 :             :             break;
   12888                 :             :           }
   12889                 :          96 :         var = OMP_CLAUSE_DECL (c);
   12890                 :          96 :         if (is_variable_sized (var))
   12891                 :             :           {
   12892                 :           1 :             tree new_var = lookup_decl (var, ctx);
   12893                 :           1 :             tree pvar = DECL_VALUE_EXPR (var);
   12894                 :           1 :             gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
   12895                 :           1 :             pvar = TREE_OPERAND (pvar, 0);
   12896                 :           1 :             gcc_assert (DECL_P (pvar));
   12897                 :           1 :             tree new_pvar = lookup_decl (pvar, ctx);
   12898                 :           1 :             x = build_fold_indirect_ref (new_pvar);
   12899                 :           1 :             TREE_THIS_NOTRAP (x) = 1;
   12900                 :           1 :             SET_DECL_VALUE_EXPR (new_var, x);
   12901                 :           1 :             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   12902                 :             :           }
   12903                 :             :         break;
   12904                 :             : 
   12905                 :        2367 :       case OMP_CLAUSE_USE_DEVICE_PTR:
   12906                 :        2367 :       case OMP_CLAUSE_USE_DEVICE_ADDR:
   12907                 :        2367 :       case OMP_CLAUSE_HAS_DEVICE_ADDR:
   12908                 :        2367 :       case OMP_CLAUSE_IS_DEVICE_PTR:
   12909                 :        2367 :         var = OMP_CLAUSE_DECL (c);
   12910                 :        2367 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
   12911                 :             :           {
   12912                 :         239 :             while (TREE_CODE (var) == INDIRECT_REF
   12913                 :         239 :                    || TREE_CODE (var) == ARRAY_REF)
   12914                 :          17 :               var = TREE_OPERAND (var, 0);
   12915                 :         222 :             if (lang_hooks.decls.omp_array_data (var, true))
   12916                 :          13 :               goto omp_firstprivate_recv;
   12917                 :             :           }
   12918                 :        2354 :         map_cnt++;
   12919                 :        2354 :         if (is_variable_sized (var))
   12920                 :             :           {
   12921                 :          12 :             tree new_var = lookup_decl (var, ctx);
   12922                 :          12 :             tree pvar = DECL_VALUE_EXPR (var);
   12923                 :          12 :             gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
   12924                 :          12 :             pvar = TREE_OPERAND (pvar, 0);
   12925                 :          12 :             gcc_assert (DECL_P (pvar));
   12926                 :          12 :             tree new_pvar = lookup_decl (pvar, ctx);
   12927                 :          12 :             x = build_fold_indirect_ref (new_pvar);
   12928                 :          12 :             TREE_THIS_NOTRAP (x) = 1;
   12929                 :          12 :             SET_DECL_VALUE_EXPR (new_var, x);
   12930                 :          12 :             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   12931                 :             :           }
   12932                 :        2342 :         else if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
   12933                 :         484 :                    || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
   12934                 :        2065 :                   && !omp_privatize_by_reference (var)
   12935                 :         697 :                   && !omp_is_allocatable_or_ptr (var)
   12936                 :         558 :                   && !lang_hooks.decls.omp_array_data (var, true))
   12937                 :        4324 :                  || TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
   12938                 :             :           {
   12939                 :         389 :             tree new_var = lookup_decl (var, ctx);
   12940                 :         389 :             tree type = build_pointer_type (TREE_TYPE (var));
   12941                 :         389 :             x = create_tmp_var_raw (type, get_name (new_var));
   12942                 :         389 :             gimple_add_tmp_var (x);
   12943                 :         389 :             x = build_simple_mem_ref (x);
   12944                 :         389 :             SET_DECL_VALUE_EXPR (new_var, x);
   12945                 :         389 :             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   12946                 :             :           }
   12947                 :             :         else
   12948                 :             :           {
   12949                 :        1953 :             tree new_var = lookup_decl (var, ctx);
   12950                 :        1953 :             x = create_tmp_var_raw (TREE_TYPE (new_var), get_name (new_var));
   12951                 :        1953 :             gimple_add_tmp_var (x);
   12952                 :        1953 :             SET_DECL_VALUE_EXPR (new_var, x);
   12953                 :        1953 :             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
   12954                 :             :           }
   12955                 :             :         break;
   12956                 :             :       }
   12957                 :             : 
   12958                 :       35389 :   if (offloaded)
   12959                 :             :     {
   12960                 :       19742 :       target_nesting_level++;
   12961                 :       19742 :       lower_omp (&tgt_body, ctx);
   12962                 :       19742 :       target_nesting_level--;
   12963                 :             :     }
   12964                 :       15647 :   else if (data_region)
   12965                 :        4134 :     lower_omp (&tgt_body, ctx);
   12966                 :             : 
   12967                 :       35389 :   if (offloaded)
   12968                 :             :     {
   12969                 :             :       /* Declare all the variables created by mapping and the variables
   12970                 :             :          declared in the scope of the target body.  */
   12971                 :       19742 :       record_vars_into (ctx->block_vars, child_fn);
   12972                 :       19742 :       maybe_remove_omp_member_access_dummy_vars (tgt_bind);
   12973                 :       19742 :       record_vars_into (gimple_bind_vars (tgt_bind), child_fn);
   12974                 :             :     }
   12975                 :             : 
   12976                 :       35389 :   olist = NULL;
   12977                 :       35389 :   ilist = NULL;
   12978                 :       35389 :   if (ctx->record_type)
   12979                 :             :     {
   12980                 :       30649 :       ctx->sender_decl
   12981                 :       30649 :         = create_tmp_var (ctx->record_type, ".omp_data_arr");
   12982                 :       30649 :       DECL_NAMELESS (ctx->sender_decl) = 1;
   12983                 :       30649 :       TREE_ADDRESSABLE (ctx->sender_decl) = 1;
   12984                 :       30649 :       t = make_tree_vec (3);
   12985                 :       30649 :       TREE_VEC_ELT (t, 0) = ctx->sender_decl;
   12986                 :       61298 :       TREE_VEC_ELT (t, 1)
   12987                 :       30649 :         = create_tmp_var (build_array_type_nelts (size_type_node, map_cnt),
   12988                 :             :                           ".omp_data_sizes");
   12989                 :       30649 :       DECL_NAMELESS (TREE_VEC_ELT (t, 1)) = 1;
   12990                 :       30649 :       TREE_ADDRESSABLE (TREE_VEC_ELT (t, 1)) = 1;
   12991                 :       30649 :       TREE_STATIC (TREE_VEC_ELT (t, 1)) = 1;
   12992                 :       30649 :       tree tkind_type = short_unsigned_type_node;
   12993                 :       30649 :       int talign_shift = 8;
   12994                 :       61298 :       TREE_VEC_ELT (t, 2)
   12995                 :       30649 :         = create_tmp_var (build_array_type_nelts (tkind_type, map_cnt),
   12996                 :             :                           ".omp_data_kinds");
   12997                 :       30649 :       DECL_NAMELESS (TREE_VEC_ELT (t, 2)) = 1;
   12998                 :       30649 :       TREE_ADDRESSABLE (TREE_VEC_ELT (t, 2)) = 1;
   12999                 :       30649 :       TREE_STATIC (TREE_VEC_ELT (t, 2)) = 1;
   13000                 :       30649 :       gimple_omp_target_set_data_arg (stmt, t);
   13001                 :             : 
   13002                 :       30649 :       vec<constructor_elt, va_gc> *vsize;
   13003                 :       30649 :       vec<constructor_elt, va_gc> *vkind;
   13004                 :       30649 :       vec_alloc (vsize, map_cnt);
   13005                 :       30649 :       vec_alloc (vkind, map_cnt);
   13006                 :       30649 :       unsigned int map_idx = 0;
   13007                 :             : 
   13008                 :      152615 :       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
   13009                 :      121966 :         switch (OMP_CLAUSE_CODE (c))
   13010                 :             :           {
   13011                 :             :             tree ovar, nc, s, purpose, var, x, type;
   13012                 :             :             unsigned int talign;
   13013                 :             : 
   13014                 :             :           default:
   13015                 :      117921 :             break;
   13016                 :             : 
   13017                 :       82918 :           case OMP_CLAUSE_MAP:
   13018                 :       82918 :           case OMP_CLAUSE_TO:
   13019                 :       82918 :           case OMP_CLAUSE_FROM:
   13020                 :       82918 :           oacc_firstprivate_map:
   13021                 :       82918 :             nc = c;
   13022                 :       82918 :             ovar = OMP_CLAUSE_DECL (c);
   13023                 :       82918 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13024                 :       82918 :                 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   13025                 :       68262 :                     || (OMP_CLAUSE_MAP_KIND (c)
   13026                 :             :                         == GOMP_MAP_FIRSTPRIVATE_REFERENCE)))
   13027                 :             :               break;
   13028                 :       79140 :             if (!DECL_P (ovar))
   13029                 :             :               {
   13030                 :       33868 :                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13031                 :       33868 :                     && OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
   13032                 :             :                   {
   13033                 :           0 :                     nc = OMP_CLAUSE_CHAIN (c);
   13034                 :           0 :                     gcc_checking_assert (OMP_CLAUSE_DECL (nc)
   13035                 :             :                                          == get_base_address (ovar));
   13036                 :           0 :                     ovar = OMP_CLAUSE_DECL (nc);
   13037                 :             :                   }
   13038                 :             :                 else
   13039                 :             :                   {
   13040                 :       33868 :                     tree x = build_sender_ref (ovar, ctx);
   13041                 :       33868 :                     tree v = ovar;
   13042                 :       33868 :                     if (in_reduction_clauses
   13043                 :         163 :                         && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13044                 :       34031 :                         && OMP_CLAUSE_MAP_IN_REDUCTION (c))
   13045                 :             :                       {
   13046                 :         104 :                         v = unshare_expr (v);
   13047                 :         104 :                         tree *p = &v;
   13048                 :         104 :                         while (handled_component_p (*p)
   13049                 :             :                                || TREE_CODE (*p) == INDIRECT_REF
   13050                 :             :                                || TREE_CODE (*p) == ADDR_EXPR
   13051                 :             :                                || TREE_CODE (*p) == MEM_REF
   13052                 :         256 :                                || TREE_CODE (*p) == NON_LVALUE_EXPR)
   13053                 :         152 :                           p = &TREE_OPERAND (*p, 0);
   13054                 :         104 :                         tree d = *p;
   13055                 :         104 :                         if (is_variable_sized (d))
   13056                 :             :                           {
   13057                 :          16 :                             gcc_assert (DECL_HAS_VALUE_EXPR_P (d));
   13058                 :          16 :                             d = DECL_VALUE_EXPR (d);
   13059                 :          16 :                             gcc_assert (TREE_CODE (d) == INDIRECT_REF);
   13060                 :          16 :                             d = TREE_OPERAND (d, 0);
   13061                 :          16 :                             gcc_assert (DECL_P (d));
   13062                 :             :                           }
   13063                 :         104 :                         splay_tree_key key
   13064                 :         104 :                           = (splay_tree_key) &DECL_CONTEXT (d);
   13065                 :         104 :                         tree nd = (tree) splay_tree_lookup (ctx->field_map,
   13066                 :         104 :                                                             key)->value;
   13067                 :         104 :                         if (d == *p)
   13068                 :          88 :                           *p = nd;
   13069                 :             :                         else
   13070                 :          16 :                           *p = build_fold_indirect_ref (nd);
   13071                 :             :                       }
   13072                 :       33868 :                     v = build_fold_addr_expr_with_type (v, ptr_type_node);
   13073                 :       33868 :                     gimplify_assign (x, v, &ilist);
   13074                 :       33868 :                     nc = NULL_TREE;
   13075                 :             :                   }
   13076                 :             :               }
   13077                 :             :             else
   13078                 :             :               {
   13079                 :       45272 :                 if (DECL_SIZE (ovar)
   13080                 :       45272 :                     && TREE_CODE (DECL_SIZE (ovar)) != INTEGER_CST)
   13081                 :             :                   {
   13082                 :           7 :                     tree ovar2 = DECL_VALUE_EXPR (ovar);
   13083                 :           7 :                     gcc_assert (TREE_CODE (ovar2) == INDIRECT_REF);
   13084                 :           7 :                     ovar2 = TREE_OPERAND (ovar2, 0);
   13085                 :           7 :                     gcc_assert (DECL_P (ovar2));
   13086                 :             :                     ovar = ovar2;
   13087                 :             :                   }
   13088                 :       45272 :                 if (!maybe_lookup_field (ovar, ctx)
   13089                 :       49433 :                     && !(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13090                 :        4161 :                          && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   13091                 :        4082 :                              || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)))
   13092                 :        4045 :                   continue;
   13093                 :             :               }
   13094                 :             : 
   13095                 :       75095 :             talign = TYPE_ALIGN_UNIT (TREE_TYPE (ovar));
   13096                 :       75095 :             if (DECL_P (ovar) && DECL_ALIGN_UNIT (ovar) > talign)
   13097                 :        6277 :               talign = DECL_ALIGN_UNIT (ovar);
   13098                 :             : 
   13099                 :       75095 :             var = NULL_TREE;
   13100                 :       75095 :             if (nc)
   13101                 :             :               {
   13102                 :       41227 :                 if (in_reduction_clauses
   13103                 :         993 :                     && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13104                 :       42220 :                     && OMP_CLAUSE_MAP_IN_REDUCTION (c))
   13105                 :             :                   {
   13106                 :         298 :                     tree d = ovar;
   13107                 :         298 :                     if (is_variable_sized (d))
   13108                 :             :                       {
   13109                 :           0 :                         gcc_assert (DECL_HAS_VALUE_EXPR_P (d));
   13110                 :           0 :                         d = DECL_VALUE_EXPR (d);
   13111                 :           0 :                         gcc_assert (TREE_CODE (d) == INDIRECT_REF);
   13112                 :           0 :                         d = TREE_OPERAND (d, 0);
   13113                 :           0 :                         gcc_assert (DECL_P (d));
   13114                 :             :                       }
   13115                 :         298 :                     splay_tree_key key
   13116                 :         298 :                       = (splay_tree_key) &DECL_CONTEXT (d);
   13117                 :         298 :                     tree nd = (tree) splay_tree_lookup (ctx->field_map,
   13118                 :         298 :                                                         key)->value;
   13119                 :         298 :                     if (d == ovar)
   13120                 :             :                       var = nd;
   13121                 :             :                     else
   13122                 :           0 :                       var = build_fold_indirect_ref (nd);
   13123                 :             :                   }
   13124                 :             :                 else
   13125                 :       40929 :                   var = lookup_decl_in_outer_ctx (ovar, ctx);
   13126                 :             :               }
   13127                 :       41227 :             if (nc
   13128                 :       41227 :                 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13129                 :       31410 :                 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   13130                 :       31222 :                     || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
   13131                 :         234 :                 && is_omp_target (stmt))
   13132                 :             :               {
   13133                 :         210 :                 x = build_sender_ref (c, ctx);
   13134                 :         210 :                 gimplify_assign (x, build_fold_addr_expr (var), &ilist);
   13135                 :             :               }
   13136                 :       74885 :             else if (nc)
   13137                 :             :               {
   13138                 :       41017 :                 x = build_sender_ref (ovar, ctx);
   13139                 :             : 
   13140                 :       41017 :                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13141                 :       31200 :                     && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
   13142                 :        4984 :                     && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
   13143                 :       46001 :                     && TREE_CODE (TREE_TYPE (ovar)) == ARRAY_TYPE)
   13144                 :             :                   {
   13145                 :         425 :                     gcc_assert (offloaded);
   13146                 :         425 :                     tree avar
   13147                 :         425 :                       = create_tmp_var (TREE_TYPE (TREE_TYPE (x)));
   13148                 :         425 :                     mark_addressable (avar);
   13149                 :         425 :                     gimplify_assign (avar, build_fold_addr_expr (var), &ilist);
   13150                 :         425 :                     talign = DECL_ALIGN_UNIT (avar);
   13151                 :         425 :                     avar = build_fold_addr_expr (avar);
   13152                 :         425 :                     gimplify_assign (x, avar, &ilist);
   13153                 :             :                   }
   13154                 :       40592 :                 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   13155                 :             :                   {
   13156                 :        3744 :                     gcc_assert (is_gimple_omp_oacc (ctx->stmt));
   13157                 :        3744 :                     if (!omp_privatize_by_reference (var))
   13158                 :             :                       {
   13159                 :        3250 :                         if (is_gimple_reg (var)
   13160                 :        3250 :                             && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   13161                 :        2376 :                           suppress_warning (var);
   13162                 :        3250 :                         var = build_fold_addr_expr (var);
   13163                 :             :                       }
   13164                 :             :                     else
   13165                 :         494 :                       talign = TYPE_ALIGN_UNIT (TREE_TYPE (TREE_TYPE (ovar)));
   13166                 :        3744 :                     gimplify_assign (x, var, &ilist);
   13167                 :             :                   }
   13168                 :       36848 :                 else if (is_gimple_reg (var))
   13169                 :             :                   {
   13170                 :        5054 :                     gcc_assert (offloaded);
   13171                 :        5054 :                     tree avar = create_tmp_var (TREE_TYPE (var));
   13172                 :        5054 :                     mark_addressable (avar);
   13173                 :        5054 :                     enum gomp_map_kind map_kind = OMP_CLAUSE_MAP_KIND (c);
   13174                 :        5054 :                     if (GOMP_MAP_COPY_TO_P (map_kind)
   13175                 :             :                         || map_kind == GOMP_MAP_POINTER
   13176                 :         458 :                         || map_kind == GOMP_MAP_TO_PSET
   13177                 :           2 :                         || map_kind == GOMP_MAP_FORCE_DEVICEPTR)
   13178                 :             :                       {
   13179                 :             :                         /* If we need to initialize a temporary
   13180                 :             :                            with VAR because it is not addressable, and
   13181                 :             :                            the variable hasn't been initialized yet, then
   13182                 :             :                            we'll get a warning for the store to avar.
   13183                 :             :                            Don't warn in that case, the mapping might
   13184                 :             :                            be implicit.  */
   13185                 :        5052 :                         suppress_warning (var, OPT_Wuninitialized);
   13186                 :        5052 :                         gimplify_assign (avar, var, &ilist);
   13187                 :             :                       }
   13188                 :        5054 :                     avar = build_fold_addr_expr (avar);
   13189                 :        5054 :                     gimplify_assign (x, avar, &ilist);
   13190                 :        5054 :                     if ((GOMP_MAP_COPY_FROM_P (map_kind)
   13191                 :        1246 :                          || map_kind == GOMP_MAP_FORCE_DEVICEPTR)
   13192                 :        8862 :                         && !TYPE_READONLY (TREE_TYPE (var)))
   13193                 :             :                       {
   13194                 :        3808 :                         x = unshare_expr (x);
   13195                 :        3808 :                         x = build_simple_mem_ref (x);
   13196                 :        3808 :                         gimplify_assign (var, x, &olist);
   13197                 :             :                       }
   13198                 :             :                   }
   13199                 :             :                 else
   13200                 :             :                   {
   13201                 :             :                     /* While MAP is handled explicitly by the FE,
   13202                 :             :                        for 'target update', only the identified is passed.  */
   13203                 :       31794 :                     if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM
   13204                 :       26671 :                          || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO)
   13205                 :       32744 :                         && (omp_is_allocatable_or_ptr (var)
   13206                 :         120 :                             && omp_check_optional_argument (var, false)))
   13207                 :           0 :                       var = build_fold_indirect_ref (var);
   13208                 :       31794 :                     else if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FROM
   13209                 :       26671 :                               && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TO)
   13210                 :       32744 :                              || (!omp_is_allocatable_or_ptr (var)
   13211                 :        5953 :                                  && !omp_check_optional_argument (var, false)))
   13212                 :       31674 :                       var = build_fold_addr_expr (var);
   13213                 :       31794 :                     gimplify_assign (x, var, &ilist);
   13214                 :             :                   }
   13215                 :             :               }
   13216                 :       75095 :             s = NULL_TREE;
   13217                 :       75095 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   13218                 :             :               {
   13219                 :        3744 :                 gcc_checking_assert (is_gimple_omp_oacc (ctx->stmt));
   13220                 :        3744 :                 s = TREE_TYPE (ovar);
   13221                 :        3744 :                 if (TREE_CODE (s) == REFERENCE_TYPE
   13222                 :        3744 :                     || omp_check_optional_argument (ovar, false))
   13223                 :         488 :                   s = TREE_TYPE (s);
   13224                 :        3744 :                 s = TYPE_SIZE_UNIT (s);
   13225                 :             :               }
   13226                 :             :             else
   13227                 :       71351 :               s = OMP_CLAUSE_SIZE (c);
   13228                 :       75095 :             if (s == NULL_TREE)
   13229                 :         145 :               s = TYPE_SIZE_UNIT (TREE_TYPE (ovar));
   13230                 :       75095 :             s = fold_convert (size_type_node, s);
   13231                 :       75095 :             purpose = size_int (map_idx++);
   13232                 :       75095 :             CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
   13233                 :       75095 :             if (TREE_CODE (s) != INTEGER_CST)
   13234                 :       15074 :               TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;
   13235                 :             : 
   13236                 :       75095 :             unsigned HOST_WIDE_INT tkind, tkind_zero;
   13237                 :       75095 :             switch (OMP_CLAUSE_CODE (c))
   13238                 :             :               {
   13239                 :       63818 :               case OMP_CLAUSE_MAP:
   13240                 :       63818 :                 tkind = OMP_CLAUSE_MAP_KIND (c);
   13241                 :       63818 :                 tkind_zero = tkind;
   13242                 :       63818 :                 if (OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c))
   13243                 :        5206 :                   switch (tkind)
   13244                 :             :                     {
   13245                 :             :                     case GOMP_MAP_ALLOC:
   13246                 :             :                     case GOMP_MAP_IF_PRESENT:
   13247                 :             :                     case GOMP_MAP_TO:
   13248                 :             :                     case GOMP_MAP_FROM:
   13249                 :             :                     case GOMP_MAP_TOFROM:
   13250                 :             :                     case GOMP_MAP_ALWAYS_TO:
   13251                 :             :                     case GOMP_MAP_ALWAYS_FROM:
   13252                 :             :                     case GOMP_MAP_ALWAYS_TOFROM:
   13253                 :             :                     case GOMP_MAP_ALWAYS_PRESENT_TO:
   13254                 :             :                     case GOMP_MAP_ALWAYS_PRESENT_FROM:
   13255                 :             :                     case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   13256                 :             :                     case GOMP_MAP_RELEASE:
   13257                 :             :                     case GOMP_MAP_FORCE_TO:
   13258                 :             :                     case GOMP_MAP_FORCE_FROM:
   13259                 :             :                     case GOMP_MAP_FORCE_TOFROM:
   13260                 :             :                     case GOMP_MAP_FORCE_PRESENT:
   13261                 :       63818 :                       tkind_zero = GOMP_MAP_ZERO_LEN_ARRAY_SECTION;
   13262                 :             :                       break;
   13263                 :          21 :                     case GOMP_MAP_DELETE:
   13264                 :          21 :                       tkind_zero = GOMP_MAP_DELETE_ZERO_LEN_ARRAY_SECTION;
   13265                 :             :                     default:
   13266                 :             :                       break;
   13267                 :             :                     }
   13268                 :       63818 :                 if (tkind_zero != tkind)
   13269                 :             :                   {
   13270                 :        5206 :                     if (integer_zerop (s))
   13271                 :             :                       tkind = tkind_zero;
   13272                 :        4514 :                     else if (integer_nonzerop (s))
   13273                 :       63818 :                       tkind_zero = tkind;
   13274                 :             :                   }
   13275                 :       63818 :                 if (tkind_zero == tkind
   13276                 :       62416 :                     && OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (c)
   13277                 :       63818 :                     && (((tkind & GOMP_MAP_FLAG_SPECIAL_BITS)
   13278                 :        4906 :                          & ~GOMP_MAP_IMPLICIT)
   13279                 :             :                         == 0))
   13280                 :             :                   {
   13281                 :             :                     /* If this is an implicit map, and the GOMP_MAP_IMPLICIT
   13282                 :             :                        bits are not interfered by other special bit encodings,
   13283                 :             :                        then turn the GOMP_IMPLICIT_BIT flag on for the runtime
   13284                 :             :                        to see.  */
   13285                 :        4862 :                     tkind |= GOMP_MAP_IMPLICIT;
   13286                 :        4862 :                     tkind_zero = tkind;
   13287                 :             :                   }
   13288                 :             :                 break;
   13289                 :        3744 :               case OMP_CLAUSE_FIRSTPRIVATE:
   13290                 :        3744 :                 gcc_checking_assert (is_gimple_omp_oacc (ctx->stmt));
   13291                 :             :                 tkind = GOMP_MAP_TO;
   13292                 :             :                 tkind_zero = tkind;
   13293                 :             :                 break;
   13294                 :        1574 :               case OMP_CLAUSE_TO:
   13295                 :        1574 :                 tkind
   13296                 :        1574 :                   = (OMP_CLAUSE_MOTION_PRESENT (c)
   13297                 :        1574 :                      ? GOMP_MAP_ALWAYS_PRESENT_TO : GOMP_MAP_TO);
   13298                 :             :                 tkind_zero = tkind;
   13299                 :             :                 break;
   13300                 :        5959 :               case OMP_CLAUSE_FROM:
   13301                 :        5959 :                 tkind
   13302                 :        5959 :                   = (OMP_CLAUSE_MOTION_PRESENT (c)
   13303                 :        5959 :                      ? GOMP_MAP_ALWAYS_PRESENT_FROM : GOMP_MAP_FROM);
   13304                 :             :                 tkind_zero = tkind;
   13305                 :             :                 break;
   13306                 :           0 :               default:
   13307                 :           0 :                 gcc_unreachable ();
   13308                 :             :               }
   13309                 :       63818 :             gcc_checking_assert (tkind
   13310                 :             :                                  < (HOST_WIDE_INT_C (1U) << talign_shift));
   13311                 :       75095 :             gcc_checking_assert (tkind_zero
   13312                 :             :                                  < (HOST_WIDE_INT_C (1U) << talign_shift));
   13313                 :       75095 :             talign = ceil_log2 (talign);
   13314                 :       75095 :             tkind |= talign << talign_shift;
   13315                 :       75095 :             tkind_zero |= talign << talign_shift;
   13316                 :       75095 :             gcc_checking_assert (tkind
   13317                 :             :                                  <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
   13318                 :       75095 :             gcc_checking_assert (tkind_zero
   13319                 :             :                                  <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
   13320                 :       75095 :             if (tkind == tkind_zero)
   13321                 :       73693 :               x = build_int_cstu (tkind_type, tkind);
   13322                 :             :             else
   13323                 :             :               {
   13324                 :        1402 :                 TREE_STATIC (TREE_VEC_ELT (t, 2)) = 0;
   13325                 :        1402 :                 x = build3 (COND_EXPR, tkind_type,
   13326                 :             :                             fold_build2 (EQ_EXPR, boolean_type_node,
   13327                 :             :                                          unshare_expr (s), size_zero_node),
   13328                 :             :                             build_int_cstu (tkind_type, tkind_zero),
   13329                 :             :                             build_int_cstu (tkind_type, tkind));
   13330                 :             :               }
   13331                 :       75095 :             CONSTRUCTOR_APPEND_ELT (vkind, purpose, x);
   13332                 :       75095 :             if (nc && nc != c)
   13333                 :           0 :               c = nc;
   13334                 :             :             break;
   13335                 :             : 
   13336                 :       14697 :           case OMP_CLAUSE_FIRSTPRIVATE:
   13337                 :       14697 :           omp_has_device_addr_descr:
   13338                 :       14697 :             if (is_gimple_omp_oacc (ctx->stmt))
   13339                 :        3744 :               goto oacc_firstprivate_map;
   13340                 :       10953 :             ovar = OMP_CLAUSE_DECL (c);
   13341                 :       10953 :             if (omp_privatize_by_reference (ovar))
   13342                 :         757 :               talign = TYPE_ALIGN_UNIT (TREE_TYPE (TREE_TYPE (ovar)));
   13343                 :             :             else
   13344                 :       10196 :               talign = DECL_ALIGN_UNIT (ovar);
   13345                 :       10953 :             var = lookup_decl_in_outer_ctx (ovar, ctx);
   13346                 :       10953 :             x = build_sender_ref (ovar, ctx);
   13347                 :       10953 :             tkind = GOMP_MAP_FIRSTPRIVATE;
   13348                 :       10953 :             type = TREE_TYPE (ovar);
   13349                 :       10953 :             if (omp_privatize_by_reference (ovar))
   13350                 :         757 :               type = TREE_TYPE (type);
   13351                 :       10953 :             if ((INTEGRAL_TYPE_P (type)
   13352                 :       10668 :                  && TYPE_PRECISION (type) <= POINTER_SIZE)
   13353                 :       10965 :                 || TREE_CODE (type) == POINTER_TYPE)
   13354                 :             :               {
   13355                 :       10801 :                 tkind = GOMP_MAP_FIRSTPRIVATE_INT;
   13356                 :       10801 :                 tree t = var;
   13357                 :       10801 :                 if (omp_privatize_by_reference (var))
   13358                 :         739 :                   t = build_simple_mem_ref (var);
   13359                 :       10062 :                 else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   13360                 :        8925 :                   suppress_warning (var);
   13361                 :       10801 :                 if (TREE_CODE (type) != POINTER_TYPE)
   13362                 :       10656 :                   t = fold_convert (pointer_sized_int_node, t);
   13363                 :       10801 :                 t = fold_convert (TREE_TYPE (x), t);
   13364                 :       10801 :                 gimplify_assign (x, t, &ilist);
   13365                 :             :               }
   13366                 :         152 :             else if (omp_privatize_by_reference (var))
   13367                 :          18 :               gimplify_assign (x, var, &ilist);
   13368                 :         134 :             else if (is_gimple_reg (var))
   13369                 :             :               {
   13370                 :          13 :                 tree avar = create_tmp_var (TREE_TYPE (var));
   13371                 :          13 :                 mark_addressable (avar);
   13372                 :          13 :                 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   13373                 :           5 :                   suppress_warning (var);
   13374                 :          13 :                 gimplify_assign (avar, var, &ilist);
   13375                 :          13 :                 avar = build_fold_addr_expr (avar);
   13376                 :          13 :                 gimplify_assign (x, avar, &ilist);
   13377                 :             :               }
   13378                 :             :             else
   13379                 :             :               {
   13380                 :         121 :                 var = build_fold_addr_expr (var);
   13381                 :         121 :                 gimplify_assign (x, var, &ilist);
   13382                 :             :               }
   13383                 :         152 :             if (tkind == GOMP_MAP_FIRSTPRIVATE_INT)
   13384                 :       10801 :               s = size_int (0);
   13385                 :         152 :             else if (omp_privatize_by_reference (ovar))
   13386                 :          18 :               s = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ovar)));
   13387                 :             :             else
   13388                 :         134 :               s = TYPE_SIZE_UNIT (TREE_TYPE (ovar));
   13389                 :       10953 :             s = fold_convert (size_type_node, s);
   13390                 :       10953 :             purpose = size_int (map_idx++);
   13391                 :       10953 :             CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
   13392                 :       10953 :             if (TREE_CODE (s) != INTEGER_CST)
   13393                 :           8 :               TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;
   13394                 :             : 
   13395                 :       10953 :             gcc_checking_assert (tkind
   13396                 :             :                                  < (HOST_WIDE_INT_C (1U) << talign_shift));
   13397                 :       10953 :             talign = ceil_log2 (talign);
   13398                 :       10953 :             tkind |= talign << talign_shift;
   13399                 :       10953 :             gcc_checking_assert (tkind
   13400                 :             :                                  <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
   13401                 :       10953 :             CONSTRUCTOR_APPEND_ELT (vkind, purpose,
   13402                 :             :                                     build_int_cstu (tkind_type, tkind));
   13403                 :             :             /* Fortran array descriptors: firstprivate of data + attach.  */
   13404                 :       10953 :             if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR
   13405                 :       10953 :                 && lang_hooks.decls.omp_array_data (ovar, true))
   13406                 :             :               {
   13407                 :          18 :                 tree not_null_lb, null_lb, after_lb;
   13408                 :          18 :                 tree var1, var2, size1, size2;
   13409                 :          18 :                 tree present = omp_check_optional_argument (ovar, true);
   13410                 :          18 :                 if (present)
   13411                 :             :                   {
   13412                 :           1 :                     location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   13413                 :           1 :                     not_null_lb = create_artificial_label (clause_loc);
   13414                 :           1 :                     null_lb = create_artificial_label (clause_loc);
   13415                 :           1 :                     after_lb = create_artificial_label (clause_loc);
   13416                 :           1 :                     gimple_seq seq = NULL;
   13417                 :           1 :                     present = force_gimple_operand (present, &seq, true,
   13418                 :             :                                                     NULL_TREE);
   13419                 :           1 :                     gimple_seq_add_seq (&ilist, seq);
   13420                 :           1 :                     gimple_seq_add_stmt (&ilist,
   13421                 :           1 :                       gimple_build_cond_from_tree (present,
   13422                 :             :                                                    not_null_lb, null_lb));
   13423                 :           1 :                     gimple_seq_add_stmt (&ilist,
   13424                 :           1 :                                          gimple_build_label (not_null_lb));
   13425                 :             :                   }
   13426                 :          18 :                 var1 = lang_hooks.decls.omp_array_data (var, false);
   13427                 :          18 :                 size1 = lang_hooks.decls.omp_array_size (var, &ilist);
   13428                 :          18 :                 var2 = build_fold_addr_expr (x);
   13429                 :          18 :                 if (!POINTER_TYPE_P (TREE_TYPE (var)))
   13430                 :           0 :                   var = build_fold_addr_expr (var);
   13431                 :          18 :                 size2 = fold_build2 (POINTER_DIFF_EXPR, ssizetype,
   13432                 :             :                                    build_fold_addr_expr (var1), var);
   13433                 :          18 :                 size2 = fold_convert (sizetype, size2);
   13434                 :          18 :                 if (present)
   13435                 :             :                   {
   13436                 :           1 :                     tree tmp = create_tmp_var (TREE_TYPE (var1));
   13437                 :           1 :                     gimplify_assign (tmp, var1, &ilist);
   13438                 :           1 :                     var1 = tmp;
   13439                 :           1 :                     tmp = create_tmp_var (TREE_TYPE (var2));
   13440                 :           1 :                     gimplify_assign (tmp, var2, &ilist);
   13441                 :           1 :                     var2 = tmp;
   13442                 :           1 :                     tmp = create_tmp_var (TREE_TYPE (size1));
   13443                 :           1 :                     gimplify_assign (tmp, size1, &ilist);
   13444                 :           1 :                     size1 = tmp;
   13445                 :           1 :                     tmp = create_tmp_var (TREE_TYPE (size2));
   13446                 :           1 :                     gimplify_assign (tmp, size2, &ilist);
   13447                 :           1 :                     size2 = tmp;
   13448                 :           1 :                     gimple_seq_add_stmt (&ilist, gimple_build_goto (after_lb));
   13449                 :           1 :                     gimple_seq_add_stmt (&ilist, gimple_build_label (null_lb));
   13450                 :           1 :                     gimplify_assign (var1, null_pointer_node, &ilist);
   13451                 :           1 :                     gimplify_assign (var2, null_pointer_node, &ilist);
   13452                 :           1 :                     gimplify_assign (size1, size_zero_node, &ilist);
   13453                 :           1 :                     gimplify_assign (size2, size_zero_node, &ilist);
   13454                 :           1 :                     gimple_seq_add_stmt (&ilist, gimple_build_label (after_lb));
   13455                 :             :                   }
   13456                 :          18 :                 x = build_sender_ref ((splay_tree_key) &DECL_NAME (ovar), ctx);
   13457                 :          18 :                 gimplify_assign (x, var1, &ilist);
   13458                 :          18 :                 tkind = GOMP_MAP_FIRSTPRIVATE;
   13459                 :          18 :                 talign = DECL_ALIGN_UNIT (ovar);
   13460                 :          18 :                 talign = ceil_log2 (talign);
   13461                 :          18 :                 tkind |= talign << talign_shift;
   13462                 :          18 :                 gcc_checking_assert (tkind
   13463                 :             :                                      <= tree_to_uhwi (
   13464                 :             :                                           TYPE_MAX_VALUE (tkind_type)));
   13465                 :          18 :                 purpose = size_int (map_idx++);
   13466                 :          18 :                 CONSTRUCTOR_APPEND_ELT (vsize, purpose, size1);
   13467                 :          18 :                 if (TREE_CODE (size1) != INTEGER_CST)
   13468                 :          18 :                   TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;
   13469                 :          18 :                 CONSTRUCTOR_APPEND_ELT (vkind, purpose,
   13470                 :             :                                         build_int_cstu (tkind_type, tkind));
   13471                 :          18 :                 x = build_sender_ref ((splay_tree_key) &DECL_UID (ovar), ctx);
   13472                 :          18 :                 gimplify_assign (x, var2, &ilist);
   13473                 :          18 :                 tkind = GOMP_MAP_ATTACH;
   13474                 :          18 :                 purpose = size_int (map_idx++);
   13475                 :          18 :                 CONSTRUCTOR_APPEND_ELT (vsize, purpose, size2);
   13476                 :          18 :                 CONSTRUCTOR_APPEND_ELT (vkind, purpose,
   13477                 :             :                                         build_int_cstu (tkind_type, tkind));
   13478                 :             :               }
   13479                 :             :             break;
   13480                 :             : 
   13481                 :        2367 :           case OMP_CLAUSE_USE_DEVICE_PTR:
   13482                 :        2367 :           case OMP_CLAUSE_USE_DEVICE_ADDR:
   13483                 :        2367 :           case OMP_CLAUSE_HAS_DEVICE_ADDR:
   13484                 :        2367 :           case OMP_CLAUSE_IS_DEVICE_PTR:
   13485                 :        2367 :             ovar = OMP_CLAUSE_DECL (c);
   13486                 :        2367 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
   13487                 :             :               {
   13488                 :         222 :                 if (lang_hooks.decls.omp_array_data (ovar, true))
   13489                 :          13 :                   goto omp_has_device_addr_descr;
   13490                 :         226 :                 while (TREE_CODE (ovar) == INDIRECT_REF
   13491                 :         226 :                        || TREE_CODE (ovar) == ARRAY_REF)
   13492                 :          17 :                   ovar = TREE_OPERAND (ovar, 0);
   13493                 :             :               }
   13494                 :        2354 :             var = lookup_decl_in_outer_ctx (ovar, ctx);
   13495                 :             : 
   13496                 :        2354 :             if (lang_hooks.decls.omp_array_data (ovar, true))
   13497                 :             :               {
   13498                 :         600 :                 tkind = ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IS_DEVICE_PTR
   13499                 :         600 :                           && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR)
   13500                 :         600 :                          ? GOMP_MAP_USE_DEVICE_PTR : GOMP_MAP_FIRSTPRIVATE_INT);
   13501                 :         600 :                 x = build_sender_ref ((splay_tree_key) &DECL_NAME (ovar), ctx);
   13502                 :             :               }
   13503                 :        1754 :             else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IS_DEVICE_PTR
   13504                 :        1754 :                      && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR)
   13505                 :             :               {
   13506                 :        1466 :                 tkind = GOMP_MAP_USE_DEVICE_PTR;
   13507                 :        1466 :                 x = build_sender_ref ((splay_tree_key) &DECL_UID (ovar), ctx);
   13508                 :             :               }
   13509                 :             :             else
   13510                 :             :               {
   13511                 :         288 :                 tkind = GOMP_MAP_FIRSTPRIVATE_INT;
   13512                 :         288 :                 x = build_sender_ref (ovar, ctx);
   13513                 :             :               }
   13514                 :             : 
   13515                 :        2354 :             if (is_gimple_omp_oacc (ctx->stmt))
   13516                 :             :               {
   13517                 :         164 :                 gcc_assert (tkind == GOMP_MAP_USE_DEVICE_PTR);
   13518                 :             : 
   13519                 :         164 :                 if (OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c))
   13520                 :          64 :                   tkind = GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT;
   13521                 :             :               }
   13522                 :             : 
   13523                 :        2354 :             type = TREE_TYPE (ovar);
   13524                 :        2354 :             if (lang_hooks.decls.omp_array_data (ovar, true))
   13525                 :         600 :               var = lang_hooks.decls.omp_array_data (var, false);
   13526                 :        1754 :             else if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
   13527                 :         484 :                       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
   13528                 :        1479 :                       && !omp_privatize_by_reference (ovar)
   13529                 :         507 :                       && !omp_is_allocatable_or_ptr (ovar))
   13530                 :        3140 :                      || TREE_CODE (type) == ARRAY_TYPE)
   13531                 :         401 :               var = build_fold_addr_expr (var);
   13532                 :             :             else
   13533                 :             :               {
   13534                 :        1353 :                 if (omp_privatize_by_reference (ovar)
   13535                 :         328 :                     || omp_check_optional_argument (ovar, false)
   13536                 :        1681 :                     || omp_is_allocatable_or_ptr (ovar))
   13537                 :             :                   {
   13538                 :        1198 :                     type = TREE_TYPE (type);
   13539                 :        1198 :                     if (POINTER_TYPE_P (type)
   13540                 :        1198 :                         && TREE_CODE (type) != ARRAY_TYPE
   13541                 :        1543 :                         && ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_USE_DEVICE_ADDR
   13542                 :          22 :                             && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR
   13543                 :          14 :                             && !omp_is_allocatable_or_ptr (ovar))
   13544                 :         337 :                            || (omp_privatize_by_reference (ovar)
   13545                 :         337 :                                && omp_is_allocatable_or_ptr (ovar))))
   13546                 :         343 :                       var = build_simple_mem_ref (var);
   13547                 :        1198 :                     var = fold_convert (TREE_TYPE (x), var);
   13548                 :             :                   }
   13549                 :             :               }
   13550                 :        2354 :             tree present;
   13551                 :        2354 :             present = omp_check_optional_argument (ovar, true);
   13552                 :        2354 :             if (present)
   13553                 :             :               {
   13554                 :         878 :                 tree null_label = create_artificial_label (UNKNOWN_LOCATION);
   13555                 :         878 :                 tree notnull_label = create_artificial_label (UNKNOWN_LOCATION);
   13556                 :         878 :                 tree opt_arg_label = create_artificial_label (UNKNOWN_LOCATION);
   13557                 :         878 :                 tree new_x = unshare_expr (x);
   13558                 :         878 :                 gimplify_expr (&present, &ilist, NULL, is_gimple_val,
   13559                 :             :                                fb_rvalue);
   13560                 :         878 :                 gcond *cond = gimple_build_cond_from_tree (present,
   13561                 :             :                                                            notnull_label,
   13562                 :             :                                                            null_label);
   13563                 :         878 :                 gimple_seq_add_stmt (&ilist, cond);
   13564                 :         878 :                 gimple_seq_add_stmt (&ilist, gimple_build_label (null_label));
   13565                 :         878 :                 gimplify_assign (new_x, null_pointer_node, &ilist);
   13566                 :         878 :                 gimple_seq_add_stmt (&ilist, gimple_build_goto (opt_arg_label));
   13567                 :         878 :                 gimple_seq_add_stmt (&ilist,
   13568                 :         878 :                                      gimple_build_label (notnull_label));
   13569                 :         878 :                 gimplify_assign (x, var, &ilist);
   13570                 :         878 :                 gimple_seq_add_stmt (&ilist,
   13571                 :         878 :                                      gimple_build_label (opt_arg_label));
   13572                 :             :               }
   13573                 :             :             else
   13574                 :        1476 :               gimplify_assign (x, var, &ilist);
   13575                 :        2354 :             s = size_int (0);
   13576                 :        2354 :             purpose = size_int (map_idx++);
   13577                 :        2354 :             CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
   13578                 :        2354 :             gcc_checking_assert (tkind
   13579                 :             :                                  < (HOST_WIDE_INT_C (1U) << talign_shift));
   13580                 :        2354 :             gcc_checking_assert (tkind
   13581                 :             :                                  <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
   13582                 :        2354 :             CONSTRUCTOR_APPEND_ELT (vkind, purpose,
   13583                 :             :                                     build_int_cstu (tkind_type, tkind));
   13584                 :        2354 :             break;
   13585                 :             :           }
   13586                 :             : 
   13587                 :       30649 :       gcc_assert (map_idx == map_cnt);
   13588                 :             : 
   13589                 :       30649 :       DECL_INITIAL (TREE_VEC_ELT (t, 1))
   13590                 :       30649 :         = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 1)), vsize);
   13591                 :       30649 :       DECL_INITIAL (TREE_VEC_ELT (t, 2))
   13592                 :       30649 :         = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 2)), vkind);
   13593                 :       91947 :       for (int i = 1; i <= 2; i++)
   13594                 :       61298 :         if (!TREE_STATIC (TREE_VEC_ELT (t, i)))
   13595                 :             :           {
   13596                 :        8823 :             gimple_seq initlist = NULL;
   13597                 :        8823 :             force_gimple_operand (build1 (DECL_EXPR, void_type_node,
   13598                 :        8823 :                                           TREE_VEC_ELT (t, i)),
   13599                 :             :                                   &initlist, true, NULL_TREE);
   13600                 :        8823 :             gimple_seq_add_seq (&ilist, initlist);
   13601                 :             : 
   13602                 :        8823 :             tree clobber = build_clobber (TREE_TYPE (TREE_VEC_ELT (t, i)));
   13603                 :        8823 :             gimple_seq_add_stmt (&olist,
   13604                 :        8823 :                                  gimple_build_assign (TREE_VEC_ELT (t, i),
   13605                 :             :                                                       clobber));
   13606                 :             :           }
   13607                 :       52475 :         else if (omp_maybe_offloaded_ctx (ctx->outer))
   13608                 :             :           {
   13609                 :        3304 :             tree id = get_identifier ("omp declare target");
   13610                 :        3304 :             tree decl = TREE_VEC_ELT (t, i);
   13611                 :        3304 :             DECL_ATTRIBUTES (decl)
   13612                 :        3304 :               = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
   13613                 :        3304 :             varpool_node *node = varpool_node::get (decl);
   13614                 :        3304 :             if (node)
   13615                 :             :               {
   13616                 :           0 :                 node->offloadable = 1;
   13617                 :           0 :                 if (ENABLE_OFFLOADING)
   13618                 :             :                   {
   13619                 :             :                     g->have_offload = true;
   13620                 :             :                     vec_safe_push (offload_vars, t);
   13621                 :             :                   }
   13622                 :             :               }
   13623                 :             :           }
   13624                 :             : 
   13625                 :       30649 :       tree clobber = build_clobber (ctx->record_type);
   13626                 :       30649 :       gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
   13627                 :             :                                                         clobber));
   13628                 :             :     }
   13629                 :             : 
   13630                 :             :   /* Once all the expansions are done, sequence all the different
   13631                 :             :      fragments inside gimple_omp_body.  */
   13632                 :             : 
   13633                 :       35389 :   new_body = NULL;
   13634                 :             : 
   13635                 :       35389 :   if (offloaded
   13636                 :       19742 :       && ctx->record_type)
   13637                 :             :     {
   13638                 :       15251 :       t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
   13639                 :             :       /* fixup_child_record_type might have changed receiver_decl's type.  */
   13640                 :       15251 :       t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
   13641                 :       15251 :       gimple_seq_add_stmt (&new_body,
   13642                 :       15251 :                            gimple_build_assign (ctx->receiver_decl, t));
   13643                 :             :     }
   13644                 :       35389 :   gimple_seq_add_seq (&new_body, fplist);
   13645                 :             : 
   13646                 :       35389 :   if (offloaded || data_region)
   13647                 :             :     {
   13648                 :      134196 :       tree prev = NULL_TREE;
   13649                 :      134196 :       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
   13650                 :      110320 :         switch (OMP_CLAUSE_CODE (c))
   13651                 :             :           {
   13652                 :             :             tree var, x;
   13653                 :             :           default:
   13654                 :             :             break;
   13655                 :       14697 :           case OMP_CLAUSE_FIRSTPRIVATE:
   13656                 :       14697 :           omp_firstprivatize_data_region:
   13657                 :       14697 :             if (is_gimple_omp_oacc (ctx->stmt))
   13658                 :             :               break;
   13659                 :       10953 :             var = OMP_CLAUSE_DECL (c);
   13660                 :       10953 :             if (omp_privatize_by_reference (var)
   13661                 :       10953 :                 || is_gimple_reg_type (TREE_TYPE (var)))
   13662                 :             :               {
   13663                 :       10844 :                 tree new_var = lookup_decl (var, ctx);
   13664                 :       10844 :                 tree type;
   13665                 :       10844 :                 type = TREE_TYPE (var);
   13666                 :       10844 :                 if (omp_privatize_by_reference (var))
   13667                 :         757 :                   type = TREE_TYPE (type);
   13668                 :       10844 :                 if ((INTEGRAL_TYPE_P (type)
   13669                 :       10668 :                      && TYPE_PRECISION (type) <= POINTER_SIZE)
   13670                 :       10856 :                     || TREE_CODE (type) == POINTER_TYPE)
   13671                 :             :                   {
   13672                 :       10801 :                     x = build_receiver_ref (var, false, ctx);
   13673                 :       10801 :                     if (TREE_CODE (type) != POINTER_TYPE)
   13674                 :       10656 :                       x = fold_convert (pointer_sized_int_node, x);
   13675                 :       10801 :                     x = fold_convert (type, x);
   13676                 :       10801 :                     gimplify_expr (&x, &new_body, NULL, is_gimple_val,
   13677                 :             :                                    fb_rvalue);
   13678                 :       10801 :                     if (omp_privatize_by_reference (var))
   13679                 :             :                       {
   13680                 :         739 :                         tree v = create_tmp_var_raw (type, get_name (var));
   13681                 :         739 :                         gimple_add_tmp_var (v);
   13682                 :         739 :                         TREE_ADDRESSABLE (v) = 1;
   13683                 :         739 :                         gimple_seq_add_stmt (&new_body,
   13684                 :         739 :                                              gimple_build_assign (v, x));
   13685                 :         739 :                         x = build_fold_addr_expr (v);
   13686                 :             :                       }
   13687                 :       10801 :                     gimple_seq_add_stmt (&new_body,
   13688                 :       10801 :                                          gimple_build_assign (new_var, x));
   13689                 :             :                   }
   13690                 :             :                 else
   13691                 :             :                   {
   13692                 :          43 :                     bool by_ref = !omp_privatize_by_reference (var);
   13693                 :          43 :                     x = build_receiver_ref (var, by_ref, ctx);
   13694                 :          43 :                     gimplify_expr (&x, &new_body, NULL, is_gimple_val,
   13695                 :             :                                    fb_rvalue);
   13696                 :          43 :                     gimple_seq_add_stmt (&new_body,
   13697                 :          43 :                                          gimple_build_assign (new_var, x));
   13698                 :             :                   }
   13699                 :             :               }
   13700                 :         109 :             else if (is_variable_sized (var))
   13701                 :             :               {
   13702                 :           4 :                 tree pvar = DECL_VALUE_EXPR (var);
   13703                 :           4 :                 gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
   13704                 :           4 :                 pvar = TREE_OPERAND (pvar, 0);
   13705                 :           4 :                 gcc_assert (DECL_P (pvar));
   13706                 :           4 :                 tree new_var = lookup_decl (pvar, ctx);
   13707                 :           4 :                 x = build_receiver_ref (var, false, ctx);
   13708                 :           4 :                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
   13709                 :           4 :                 gimple_seq_add_stmt (&new_body,
   13710                 :           4 :                                      gimple_build_assign (new_var, x));
   13711                 :             :               }
   13712                 :             :             break;
   13713                 :         179 :           case OMP_CLAUSE_PRIVATE:
   13714                 :         179 :             if (is_gimple_omp_oacc (ctx->stmt))
   13715                 :             :               break;
   13716                 :          96 :             var = OMP_CLAUSE_DECL (c);
   13717                 :          96 :             if (omp_privatize_by_reference (var))
   13718                 :             :               {
   13719                 :           5 :                 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   13720                 :           5 :                 tree new_var = lookup_decl (var, ctx);
   13721                 :           5 :                 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
   13722                 :           5 :                 if (TREE_CONSTANT (x))
   13723                 :             :                   {
   13724                 :           3 :                     x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
   13725                 :             :                                             get_name (var));
   13726                 :           3 :                     gimple_add_tmp_var (x);
   13727                 :           3 :                     TREE_ADDRESSABLE (x) = 1;
   13728                 :           3 :                     x = build_fold_addr_expr_loc (clause_loc, x);
   13729                 :             :                   }
   13730                 :             :                 else
   13731                 :             :                   break;
   13732                 :             : 
   13733                 :           3 :                 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
   13734                 :           3 :                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
   13735                 :           3 :                 gimple_seq_add_stmt (&new_body,
   13736                 :           3 :                                      gimple_build_assign (new_var, x));
   13737                 :             :               }
   13738                 :             :             break;
   13739                 :        2367 :           case OMP_CLAUSE_USE_DEVICE_PTR:
   13740                 :        2367 :           case OMP_CLAUSE_USE_DEVICE_ADDR:
   13741                 :        2367 :           case OMP_CLAUSE_HAS_DEVICE_ADDR:
   13742                 :        2367 :           case OMP_CLAUSE_IS_DEVICE_PTR:
   13743                 :        2367 :             tree new_var;
   13744                 :        2367 :             gimple_seq assign_body;
   13745                 :        2367 :             bool is_array_data;
   13746                 :        2367 :             bool do_optional_check;
   13747                 :        2367 :             assign_body = NULL;
   13748                 :        2367 :             do_optional_check = false;
   13749                 :        2367 :             var = OMP_CLAUSE_DECL (c);
   13750                 :        2367 :             is_array_data = lang_hooks.decls.omp_array_data (var, true) != NULL;
   13751                 :        2367 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR && is_array_data)
   13752                 :          13 :               goto omp_firstprivatize_data_region;
   13753                 :             : 
   13754                 :        2354 :             if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IS_DEVICE_PTR
   13755                 :        2354 :                 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR)
   13756                 :        4132 :               x = build_sender_ref (is_array_data
   13757                 :         600 :                                     ? (splay_tree_key) &DECL_NAME (var)
   13758                 :        1466 :                                     : (splay_tree_key) &DECL_UID (var), ctx);
   13759                 :             :             else
   13760                 :             :               {
   13761                 :         288 :                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
   13762                 :             :                   {
   13763                 :         226 :                     while (TREE_CODE (var) == INDIRECT_REF
   13764                 :         226 :                            || TREE_CODE (var) == ARRAY_REF)
   13765                 :          17 :                       var = TREE_OPERAND (var, 0);
   13766                 :             :                   }
   13767                 :         288 :                 x = build_receiver_ref (var, false, ctx);
   13768                 :             :               }
   13769                 :             : 
   13770                 :        2354 :             if (is_array_data)
   13771                 :             :               {
   13772                 :         600 :                 bool is_ref = omp_privatize_by_reference (var);
   13773                 :         600 :                 do_optional_check = true;
   13774                 :             :                 /* First, we copy the descriptor data from the host; then
   13775                 :             :                    we update its data to point to the target address.  */
   13776                 :         600 :                 new_var = lookup_decl (var, ctx);
   13777                 :         600 :                 new_var = DECL_VALUE_EXPR (new_var);
   13778                 :         600 :                 tree v = new_var;
   13779                 :         600 :                 tree v2 = var;
   13780                 :         600 :                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
   13781                 :         600 :                     || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR)
   13782                 :         600 :                   v2 = maybe_lookup_decl_in_outer_ctx (var, ctx);
   13783                 :             : 
   13784                 :         600 :                 if (is_ref)
   13785                 :             :                   {
   13786                 :         396 :                     v2 = build_fold_indirect_ref (v2);
   13787                 :         396 :                     v = create_tmp_var_raw (TREE_TYPE (v2), get_name (var));
   13788                 :         396 :                     gimple_add_tmp_var (v);
   13789                 :         396 :                     TREE_ADDRESSABLE (v) = 1;
   13790                 :         396 :                     gimplify_assign (v, v2, &assign_body);
   13791                 :         396 :                     tree rhs = build_fold_addr_expr (v);
   13792                 :         396 :                     gimple_seq_add_stmt (&assign_body,
   13793                 :         396 :                                          gimple_build_assign (new_var, rhs));
   13794                 :             :                   }
   13795                 :             :                 else
   13796                 :         204 :                   gimplify_assign (new_var, v2, &assign_body);
   13797                 :             : 
   13798                 :         600 :                 v2 = lang_hooks.decls.omp_array_data (unshare_expr (v), false);
   13799                 :         600 :                 gcc_assert (v2);
   13800                 :         600 :                 gimplify_expr (&x, &assign_body, NULL, is_gimple_val, fb_rvalue);
   13801                 :        1200 :                 gimple_seq_add_stmt (&assign_body,
   13802                 :         600 :                                      gimple_build_assign (v2, x));
   13803                 :             :               }
   13804                 :        1754 :             else if (is_variable_sized (var))
   13805                 :             :               {
   13806                 :          12 :                 tree pvar = DECL_VALUE_EXPR (var);
   13807                 :          12 :                 gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
   13808                 :          12 :                 pvar = TREE_OPERAND (pvar, 0);
   13809                 :          12 :                 gcc_assert (DECL_P (pvar));
   13810                 :          12 :                 new_var = lookup_decl (pvar, ctx);
   13811                 :          12 :                 gimplify_expr (&x, &assign_body, NULL, is_gimple_val, fb_rvalue);
   13812                 :          24 :                 gimple_seq_add_stmt (&assign_body,
   13813                 :          12 :                                      gimple_build_assign (new_var, x));
   13814                 :             :               }
   13815                 :        1742 :             else if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
   13816                 :         478 :                       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
   13817                 :        1471 :                       && !omp_privatize_by_reference (var)
   13818                 :         499 :                       && !omp_is_allocatable_or_ptr (var))
   13819                 :        3124 :                      || TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
   13820                 :             :               {
   13821                 :         389 :                 new_var = lookup_decl (var, ctx);
   13822                 :         389 :                 new_var = DECL_VALUE_EXPR (new_var);
   13823                 :         389 :                 gcc_assert (TREE_CODE (new_var) == MEM_REF);
   13824                 :         389 :                 new_var = TREE_OPERAND (new_var, 0);
   13825                 :         389 :                 gcc_assert (DECL_P (new_var));
   13826                 :         389 :                 gimplify_expr (&x, &assign_body, NULL, is_gimple_val, fb_rvalue);
   13827                 :         778 :                 gimple_seq_add_stmt (&assign_body,
   13828                 :         389 :                                      gimple_build_assign (new_var, x));
   13829                 :             :               }
   13830                 :             :             else
   13831                 :             :               {
   13832                 :        1353 :                 tree type = TREE_TYPE (var);
   13833                 :        1353 :                 new_var = lookup_decl (var, ctx);
   13834                 :        1353 :                 if (omp_privatize_by_reference (var))
   13835                 :             :                   {
   13836                 :        1025 :                     type = TREE_TYPE (type);
   13837                 :        1025 :                     if (POINTER_TYPE_P (type)
   13838                 :        1025 :                         && TREE_CODE (type) != ARRAY_TYPE
   13839                 :        1370 :                         && ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_USE_DEVICE_ADDR
   13840                 :          22 :                             && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR)
   13841                 :         331 :                             || (omp_privatize_by_reference (var)
   13842                 :         331 :                                 && omp_is_allocatable_or_ptr (var))))
   13843                 :             :                       {
   13844                 :         343 :                         tree v = create_tmp_var_raw (type, get_name (var));
   13845                 :         343 :                         gimple_add_tmp_var (v);
   13846                 :         343 :                         TREE_ADDRESSABLE (v) = 1;
   13847                 :         343 :                         x = fold_convert (type, x);
   13848                 :         343 :                         gimplify_expr (&x, &assign_body, NULL, is_gimple_val,
   13849                 :             :                                        fb_rvalue);
   13850                 :         343 :                         gimple_seq_add_stmt (&assign_body,
   13851                 :         343 :                                              gimple_build_assign (v, x));
   13852                 :         343 :                         x = build_fold_addr_expr (v);
   13853                 :         343 :                         do_optional_check = true;
   13854                 :             :                       }
   13855                 :             :                   }
   13856                 :        1353 :                 new_var = DECL_VALUE_EXPR (new_var);
   13857                 :        1353 :                 x = fold_convert (TREE_TYPE (new_var), x);
   13858                 :        1353 :                 gimplify_expr (&x, &assign_body, NULL, is_gimple_val, fb_rvalue);
   13859                 :        1353 :                 gimple_seq_add_stmt (&assign_body,
   13860                 :        1353 :                                      gimple_build_assign (new_var, x));
   13861                 :             :               }
   13862                 :        2354 :             tree present;
   13863                 :        1001 :             present = ((do_optional_check
   13864                 :         943 :                         && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR
   13865                 :         937 :                         && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IS_DEVICE_PTR)
   13866                 :        2285 :                        ? omp_check_optional_argument (OMP_CLAUSE_DECL (c), true)
   13867                 :             :                        : NULL_TREE);
   13868                 :        2354 :             if (present)
   13869                 :             :               {
   13870                 :         480 :                 tree null_label = create_artificial_label (UNKNOWN_LOCATION);
   13871                 :         480 :                 tree notnull_label = create_artificial_label (UNKNOWN_LOCATION);
   13872                 :         480 :                 tree opt_arg_label = create_artificial_label (UNKNOWN_LOCATION);
   13873                 :         480 :                 glabel *null_glabel = gimple_build_label (null_label);
   13874                 :         480 :                 glabel *notnull_glabel = gimple_build_label (notnull_label);
   13875                 :         480 :                 ggoto *opt_arg_ggoto = gimple_build_goto (opt_arg_label);
   13876                 :         480 :                 gimplify_expr (&x, &new_body, NULL, is_gimple_val,
   13877                 :             :                                            fb_rvalue);
   13878                 :         480 :                 gimplify_expr (&present, &new_body, NULL, is_gimple_val,
   13879                 :             :                                fb_rvalue);
   13880                 :         480 :                 gcond *cond = gimple_build_cond_from_tree (present,
   13881                 :             :                                                            notnull_label,
   13882                 :             :                                                            null_label);
   13883                 :         480 :                 gimple_seq_add_stmt (&new_body, cond);
   13884                 :         480 :                 gimple_seq_add_stmt (&new_body, null_glabel);
   13885                 :         480 :                 gimplify_assign (new_var, null_pointer_node, &new_body);
   13886                 :         480 :                 gimple_seq_add_stmt (&new_body, opt_arg_ggoto);
   13887                 :         480 :                 gimple_seq_add_stmt (&new_body, notnull_glabel);
   13888                 :         480 :                 gimple_seq_add_seq (&new_body, assign_body);
   13889                 :         480 :                 gimple_seq_add_stmt (&new_body,
   13890                 :         480 :                                      gimple_build_label (opt_arg_label));
   13891                 :             :               }
   13892                 :             :             else
   13893                 :        1874 :               gimple_seq_add_seq (&new_body, assign_body);
   13894                 :             :             break;
   13895                 :             :           }
   13896                 :             :       /* Handle GOMP_MAP_FIRSTPRIVATE_{POINTER,REFERENCE} in second pass,
   13897                 :             :          so that firstprivate vars holding OMP_CLAUSE_SIZE if needed
   13898                 :             :          are already handled.  Similarly OMP_CLAUSE_PRIVATE for VLAs
   13899                 :             :          or references to VLAs.  */
   13900                 :      134196 :       for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   13901                 :      110320 :         switch (OMP_CLAUSE_CODE (c))
   13902                 :             :           {
   13903                 :             :             tree var;
   13904                 :             :           default:
   13905                 :             :             break;
   13906                 :       61050 :           case OMP_CLAUSE_MAP:
   13907                 :       61050 :             if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   13908                 :       61050 :                 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   13909                 :             :               {
   13910                 :        3609 :                 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   13911                 :        3609 :                 poly_int64 offset = 0;
   13912                 :        3609 :                 gcc_assert (prev);
   13913                 :        3609 :                 var = OMP_CLAUSE_DECL (c);
   13914                 :        3609 :                 if (DECL_P (var)
   13915                 :        3609 :                     && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
   13916                 :        1102 :                     && is_global_var (maybe_lookup_decl_in_outer_ctx (var,
   13917                 :             :                                                                       ctx))
   13918                 :        3725 :                     && varpool_node::get_create (var)->offloadable)
   13919                 :             :                   break;
   13920                 :        3607 :                 if (TREE_CODE (var) == INDIRECT_REF
   13921                 :        3607 :                     && TREE_CODE (TREE_OPERAND (var, 0)) == COMPONENT_REF)
   13922                 :           0 :                   var = TREE_OPERAND (var, 0);
   13923                 :        3607 :                 if (TREE_CODE (var) == COMPONENT_REF)
   13924                 :             :                   {
   13925                 :           0 :                     var = get_addr_base_and_unit_offset (var, &offset);
   13926                 :           0 :                     gcc_assert (var != NULL_TREE && DECL_P (var));
   13927                 :             :                   }
   13928                 :        3607 :                 else if (DECL_SIZE (var)
   13929                 :        3607 :                          && TREE_CODE (DECL_SIZE (var)) != INTEGER_CST)
   13930                 :             :                   {
   13931                 :         739 :                     tree var2 = DECL_VALUE_EXPR (var);
   13932                 :         739 :                     gcc_assert (TREE_CODE (var2) == INDIRECT_REF);
   13933                 :         739 :                     var2 = TREE_OPERAND (var2, 0);
   13934                 :         739 :                     gcc_assert (DECL_P (var2));
   13935                 :             :                     var = var2;
   13936                 :             :                   }
   13937                 :        3607 :                 tree new_var = lookup_decl (var, ctx), x;
   13938                 :        3607 :                 tree type = TREE_TYPE (new_var);
   13939                 :        3607 :                 bool is_ref;
   13940                 :        3607 :                 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == INDIRECT_REF
   13941                 :        3607 :                     && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
   13942                 :             :                         == COMPONENT_REF))
   13943                 :             :                   {
   13944                 :           0 :                     type = TREE_TYPE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0));
   13945                 :           0 :                     is_ref = true;
   13946                 :           0 :                     new_var = build2 (MEM_REF, type,
   13947                 :             :                                       build_fold_addr_expr (new_var),
   13948                 :             :                                       build_int_cst (build_pointer_type (type),
   13949                 :             :                                                      offset));
   13950                 :             :                   }
   13951                 :        3607 :                 else if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPONENT_REF)
   13952                 :             :                   {
   13953                 :           0 :                     type = TREE_TYPE (OMP_CLAUSE_DECL (c));
   13954                 :           0 :                     is_ref = TREE_CODE (type) == REFERENCE_TYPE;
   13955                 :           0 :                     new_var = build2 (MEM_REF, type,
   13956                 :             :                                       build_fold_addr_expr (new_var),
   13957                 :             :                                       build_int_cst (build_pointer_type (type),
   13958                 :             :                                                      offset));
   13959                 :             :                   }
   13960                 :             :                 else
   13961                 :        3607 :                   is_ref = omp_privatize_by_reference (var);
   13962                 :        3607 :                 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   13963                 :             :                   is_ref = false;
   13964                 :        6654 :                 bool ref_to_array = false;
   13965                 :        6654 :                 bool ref_to_ptr = false;
   13966                 :        3208 :                 if (is_ref)
   13967                 :             :                   {
   13968                 :         161 :                     type = TREE_TYPE (type);
   13969                 :         161 :                     if (TREE_CODE (type) == ARRAY_TYPE)
   13970                 :             :                       {
   13971                 :         155 :                         type = build_pointer_type (type);
   13972                 :         155 :                         ref_to_array = true;
   13973                 :             :                       }
   13974                 :             :                   }
   13975                 :        3446 :                 else if (TREE_CODE (type) == ARRAY_TYPE)
   13976                 :             :                   {
   13977                 :         361 :                     tree decl2 = DECL_VALUE_EXPR (new_var);
   13978                 :         361 :                     gcc_assert (TREE_CODE (decl2) == MEM_REF);
   13979                 :         361 :                     decl2 = TREE_OPERAND (decl2, 0);
   13980                 :         361 :                     gcc_assert (DECL_P (decl2));
   13981                 :         361 :                     new_var = decl2;
   13982                 :         361 :                     type = TREE_TYPE (new_var);
   13983                 :             :                   }
   13984                 :        3085 :                 else if (TREE_CODE (type) == REFERENCE_TYPE
   13985                 :        3085 :                          && TREE_CODE (TREE_TYPE (type)) == POINTER_TYPE)
   13986                 :             :                   {
   13987                 :         157 :                     type = TREE_TYPE (type);
   13988                 :         157 :                     ref_to_ptr = true;
   13989                 :             :                   }
   13990                 :        3607 :                 x = build_receiver_ref (OMP_CLAUSE_DECL (prev), false, ctx);
   13991                 :        3607 :                 x = fold_convert_loc (clause_loc, type, x);
   13992                 :        3607 :                 if (!integer_zerop (OMP_CLAUSE_SIZE (c)))
   13993                 :             :                   {
   13994                 :         735 :                     tree bias = OMP_CLAUSE_SIZE (c);
   13995                 :         735 :                     if (DECL_P (bias))
   13996                 :         295 :                       bias = lookup_decl (bias, ctx);
   13997                 :         735 :                     bias = fold_convert_loc (clause_loc, sizetype, bias);
   13998                 :         735 :                     bias = fold_build1_loc (clause_loc, NEGATE_EXPR, sizetype,
   13999                 :             :                                             bias);
   14000                 :         735 :                     x = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
   14001                 :         735 :                                          TREE_TYPE (x), x, bias);
   14002                 :             :                   }
   14003                 :        3607 :                 if (ref_to_array)
   14004                 :         155 :                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
   14005                 :        3607 :                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
   14006                 :        3607 :                 if ((is_ref && !ref_to_array)
   14007                 :        3601 :                     || ref_to_ptr)
   14008                 :             :                   {
   14009                 :         163 :                     tree t = create_tmp_var_raw (type, get_name (var));
   14010                 :         163 :                     gimple_add_tmp_var (t);
   14011                 :         163 :                     TREE_ADDRESSABLE (t) = 1;
   14012                 :         163 :                     gimple_seq_add_stmt (&new_body,
   14013                 :         163 :                                          gimple_build_assign (t, x));
   14014                 :         163 :                     x = build_fold_addr_expr_loc (clause_loc, t);
   14015                 :             :                   }
   14016                 :        3607 :                 gimple_seq_add_stmt (&new_body,
   14017                 :        3607 :                                      gimple_build_assign (new_var, x));
   14018                 :        3607 :                 prev = NULL_TREE;
   14019                 :             :               }
   14020                 :       57441 :             else if (OMP_CLAUSE_CHAIN (c)
   14021                 :       41666 :                      && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c))
   14022                 :             :                         == OMP_CLAUSE_MAP
   14023                 :       93906 :                      && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
   14024                 :             :                          == GOMP_MAP_FIRSTPRIVATE_POINTER
   14025                 :       33255 :                          || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
   14026                 :             :                              == GOMP_MAP_FIRSTPRIVATE_REFERENCE)))
   14027                 :             :               prev = c;
   14028                 :             :             break;
   14029                 :         179 :           case OMP_CLAUSE_PRIVATE:
   14030                 :         179 :             var = OMP_CLAUSE_DECL (c);
   14031                 :         179 :             if (is_variable_sized (var))
   14032                 :             :               {
   14033                 :           1 :                 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   14034                 :           1 :                 tree new_var = lookup_decl (var, ctx);
   14035                 :           1 :                 tree pvar = DECL_VALUE_EXPR (var);
   14036                 :           1 :                 gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
   14037                 :           1 :                 pvar = TREE_OPERAND (pvar, 0);
   14038                 :           1 :                 gcc_assert (DECL_P (pvar));
   14039                 :           1 :                 tree new_pvar = lookup_decl (pvar, ctx);
   14040                 :           1 :                 tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
   14041                 :           1 :                 tree al = size_int (DECL_ALIGN (var));
   14042                 :           1 :                 tree x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
   14043                 :           1 :                 x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
   14044                 :           1 :                 x = fold_convert_loc (clause_loc, TREE_TYPE (new_pvar), x);
   14045                 :           1 :                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
   14046                 :           1 :                 gimple_seq_add_stmt (&new_body,
   14047                 :           1 :                                      gimple_build_assign (new_pvar, x));
   14048                 :             :               }
   14049                 :         178 :             else if (omp_privatize_by_reference (var)
   14050                 :         178 :                      && !is_gimple_omp_oacc (ctx->stmt))
   14051                 :             :               {
   14052                 :           5 :                 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
   14053                 :           5 :                 tree new_var = lookup_decl (var, ctx);
   14054                 :           5 :                 tree x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
   14055                 :           5 :                 if (TREE_CONSTANT (x))
   14056                 :             :                   break;
   14057                 :             :                 else
   14058                 :             :                   {
   14059                 :           2 :                     tree atmp
   14060                 :           2 :                       = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
   14061                 :           2 :                     tree rtype = TREE_TYPE (TREE_TYPE (new_var));
   14062                 :           2 :                     tree al = size_int (TYPE_ALIGN (rtype));
   14063                 :           2 :                     x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
   14064                 :             :                   }
   14065                 :             : 
   14066                 :           2 :                 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
   14067                 :           2 :                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
   14068                 :           2 :                 gimple_seq_add_stmt (&new_body,
   14069                 :           2 :                                      gimple_build_assign (new_var, x));
   14070                 :             :               }
   14071                 :             :             break;
   14072                 :             :           }
   14073                 :             : 
   14074                 :       23876 :       gimple_seq fork_seq = NULL;
   14075                 :       23876 :       gimple_seq join_seq = NULL;
   14076                 :             : 
   14077                 :       23876 :       if (offloaded && is_gimple_omp_oacc (ctx->stmt))
   14078                 :             :         {
   14079                 :             :           /* If there are reductions on the offloaded region itself, treat
   14080                 :             :              them as a dummy GANG loop.  */
   14081                 :        9126 :           tree level = build_int_cst (integer_type_node, GOMP_DIM_GANG);
   14082                 :             : 
   14083                 :        9126 :           gcall *private_marker = lower_oacc_private_marker (ctx);
   14084                 :             : 
   14085                 :        9126 :           if (private_marker)
   14086                 :          20 :             gimple_call_set_arg (private_marker, 2, level);
   14087                 :             : 
   14088                 :        9126 :           lower_oacc_reductions (gimple_location (ctx->stmt), clauses, level,
   14089                 :             :                                  false, NULL, private_marker, NULL, &fork_seq,
   14090                 :             :                                  &join_seq, ctx);
   14091                 :             :         }
   14092                 :             : 
   14093                 :       23876 :       gimple_seq_add_seq (&new_body, fork_seq);
   14094                 :       23876 :       gimple_seq_add_seq (&new_body, tgt_body);
   14095                 :       23876 :       gimple_seq_add_seq (&new_body, join_seq);
   14096                 :             : 
   14097                 :       23876 :       if (offloaded)
   14098                 :             :         {
   14099                 :       19742 :           new_body = maybe_catch_exception (new_body);
   14100                 :       19742 :           gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
   14101                 :             :         }
   14102                 :       23876 :       gimple_omp_set_body (stmt, new_body);
   14103                 :             :     }
   14104                 :             : 
   14105                 :       55131 :   bind = gimple_build_bind (NULL, NULL,
   14106                 :       19742 :                             tgt_bind ? gimple_bind_block (tgt_bind)
   14107                 :             :                                      : NULL_TREE);
   14108                 :       70366 :   gsi_replace (gsi_p, dep_bind ? dep_bind : bind, true);
   14109                 :       35389 :   gimple_bind_add_seq (bind, ilist);
   14110                 :       35389 :   gimple_bind_add_stmt (bind, stmt);
   14111                 :       35389 :   gimple_bind_add_seq (bind, olist);
   14112                 :             : 
   14113                 :       35389 :   pop_gimplify_context (NULL);
   14114                 :             : 
   14115                 :       35389 :   if (dep_bind)
   14116                 :             :     {
   14117                 :         412 :       gimple_bind_add_seq (dep_bind, dep_ilist);
   14118                 :         412 :       gimple_bind_add_stmt (dep_bind, bind);
   14119                 :         412 :       gimple_bind_add_seq (dep_bind, dep_olist);
   14120                 :         412 :       pop_gimplify_context (dep_bind);
   14121                 :             :     }
   14122                 :       35389 : }
   14123                 :             : 
   14124                 :             : /* Expand code for an OpenMP teams directive.  */
   14125                 :             : 
   14126                 :             : static void
   14127                 :        5997 : lower_omp_teams (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   14128                 :             : {
   14129                 :        5997 :   gomp_teams *teams_stmt = as_a <gomp_teams *> (gsi_stmt (*gsi_p));
   14130                 :        5997 :   push_gimplify_context ();
   14131                 :             : 
   14132                 :        5997 :   tree block = make_node (BLOCK);
   14133                 :        5997 :   gbind *bind = gimple_build_bind (NULL, NULL, block);
   14134                 :        5997 :   gsi_replace (gsi_p, bind, true);
   14135                 :        5997 :   gimple_seq bind_body = NULL;
   14136                 :        5997 :   gimple_seq dlist = NULL;
   14137                 :        5997 :   gimple_seq olist = NULL;
   14138                 :             : 
   14139                 :        5997 :   tree num_teams = omp_find_clause (gimple_omp_teams_clauses (teams_stmt),
   14140                 :        5997 :                                     OMP_CLAUSE_NUM_TEAMS);
   14141                 :        5997 :   tree num_teams_lower = NULL_TREE;
   14142                 :        5997 :   if (num_teams == NULL_TREE)
   14143                 :        5273 :     num_teams = build_int_cst (unsigned_type_node, 0);
   14144                 :             :   else
   14145                 :             :     {
   14146                 :         724 :       num_teams_lower = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (num_teams);
   14147                 :         724 :       if (num_teams_lower)
   14148                 :             :         {
   14149                 :         172 :           num_teams_lower = fold_convert (unsigned_type_node, num_teams_lower);
   14150                 :         172 :           gimplify_expr (&num_teams_lower, &bind_body, NULL, is_gimple_val,
   14151                 :             :                          fb_rvalue);
   14152                 :             :         }
   14153                 :         724 :       num_teams = OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (num_teams);
   14154                 :         724 :       num_teams = fold_convert (unsigned_type_node, num_teams);
   14155                 :         724 :       gimplify_expr (&num_teams, &bind_body, NULL, is_gimple_val, fb_rvalue);
   14156                 :             :     }
   14157                 :        5997 :   if (num_teams_lower == NULL_TREE)
   14158                 :        5825 :     num_teams_lower = num_teams;
   14159                 :        5997 :   tree thread_limit = omp_find_clause (gimple_omp_teams_clauses (teams_stmt),
   14160                 :        5997 :                                        OMP_CLAUSE_THREAD_LIMIT);
   14161                 :        5997 :   if (thread_limit == NULL_TREE)
   14162                 :        5449 :     thread_limit = build_int_cst (unsigned_type_node, 0);
   14163                 :             :   else
   14164                 :             :     {
   14165                 :         548 :       thread_limit = OMP_CLAUSE_THREAD_LIMIT_EXPR (thread_limit);
   14166                 :         548 :       thread_limit = fold_convert (unsigned_type_node, thread_limit);
   14167                 :         548 :       gimplify_expr (&thread_limit, &bind_body, NULL, is_gimple_val,
   14168                 :             :                      fb_rvalue);
   14169                 :             :     }
   14170                 :        5997 :   location_t loc = gimple_location (teams_stmt);
   14171                 :        5997 :   tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TEAMS4);
   14172                 :        5997 :   tree rettype = TREE_TYPE (TREE_TYPE (decl));
   14173                 :        5997 :   tree first = create_tmp_var (rettype);
   14174                 :        5997 :   gimple_seq_add_stmt (&bind_body,
   14175                 :        5997 :                        gimple_build_assign (first, build_one_cst (rettype)));
   14176                 :        5997 :   tree llabel = create_artificial_label (loc);
   14177                 :        5997 :   gimple_seq_add_stmt (&bind_body, gimple_build_label (llabel));
   14178                 :        5997 :   gimple *call
   14179                 :        5997 :     = gimple_build_call (decl, 4, num_teams_lower, num_teams, thread_limit,
   14180                 :             :                          first);
   14181                 :        5997 :   gimple_set_location (call, loc);
   14182                 :        5997 :   tree temp = create_tmp_var (rettype);
   14183                 :        5997 :   gimple_call_set_lhs (call, temp);
   14184                 :        5997 :   gimple_seq_add_stmt (&bind_body, call);
   14185                 :             : 
   14186                 :        5997 :   tree tlabel = create_artificial_label (loc);
   14187                 :        5997 :   tree flabel = create_artificial_label (loc);
   14188                 :        5997 :   gimple *cond = gimple_build_cond (NE_EXPR, temp, build_zero_cst (rettype),
   14189                 :             :                                     tlabel, flabel);
   14190                 :        5997 :   gimple_seq_add_stmt (&bind_body, cond);
   14191                 :        5997 :   gimple_seq_add_stmt (&bind_body, gimple_build_label (tlabel));
   14192                 :        5997 :   gimple_seq_add_stmt (&bind_body,
   14193                 :        5997 :                        gimple_build_assign (first, build_zero_cst (rettype)));
   14194                 :             : 
   14195                 :        5997 :   lower_rec_input_clauses (gimple_omp_teams_clauses (teams_stmt),
   14196                 :             :                            &bind_body, &dlist, ctx, NULL);
   14197                 :        5997 :   lower_omp (gimple_omp_body_ptr (teams_stmt), ctx);
   14198                 :        5997 :   lower_reduction_clauses (gimple_omp_teams_clauses (teams_stmt), &olist,
   14199                 :             :                            NULL, ctx);
   14200                 :        5997 :   gimple_seq_add_stmt (&bind_body, teams_stmt);
   14201                 :             : 
   14202                 :        5997 :   gimple_seq_add_seq (&bind_body, gimple_omp_body (teams_stmt));
   14203                 :        5997 :   gimple_omp_set_body (teams_stmt, NULL);
   14204                 :        5997 :   gimple_seq_add_seq (&bind_body, olist);
   14205                 :        5997 :   gimple_seq_add_seq (&bind_body, dlist);
   14206                 :        5997 :   gimple_seq_add_stmt (&bind_body, gimple_build_omp_return (true));
   14207                 :        5997 :   gimple_seq_add_stmt (&bind_body, gimple_build_goto (llabel));
   14208                 :        5997 :   gimple_seq_add_stmt (&bind_body, gimple_build_label (flabel));
   14209                 :        5997 :   gimple_bind_set_body (bind, bind_body);
   14210                 :             : 
   14211                 :        5997 :   pop_gimplify_context (bind);
   14212                 :             : 
   14213                 :        5997 :   gimple_bind_append_vars (bind, ctx->block_vars);
   14214                 :        5997 :   BLOCK_VARS (block) = ctx->block_vars;
   14215                 :        5997 :   if (BLOCK_VARS (block))
   14216                 :         740 :     TREE_USED (block) = 1;
   14217                 :        5997 : }
   14218                 :             : 
   14219                 :             : /* Callback for lower_omp_1.  Return non-NULL if *tp needs to be
   14220                 :             :    regimplified.  If DATA is non-NULL, lower_omp_1 is outside
   14221                 :             :    of OMP context, but with make_addressable_vars set.  */
   14222                 :             : 
   14223                 :             : static tree
   14224                 :     2969304 : lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
   14225                 :             :                         void *data)
   14226                 :             : {
   14227                 :     2969304 :   tree t = *tp;
   14228                 :             : 
   14229                 :             :   /* Any variable with DECL_VALUE_EXPR needs to be regimplified.  */
   14230                 :     2969304 :   if ((VAR_P (t) || TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
   14231                 :     1389070 :       && data == NULL
   14232                 :     1324828 :       && DECL_HAS_VALUE_EXPR_P (t))
   14233                 :             :     return t;
   14234                 :             : 
   14235                 :     2875745 :   if (make_addressable_vars
   14236                 :      418516 :       && DECL_P (t)
   14237                 :     3081513 :       && bitmap_bit_p (make_addressable_vars, DECL_UID (t)))
   14238                 :             :     return t;
   14239                 :             : 
   14240                 :             :   /* If a global variable has been privatized, TREE_CONSTANT on
   14241                 :             :      ADDR_EXPR might be wrong.  */
   14242                 :     2873154 :   if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
   14243                 :       99698 :     recompute_tree_invariant_for_addr_expr (t);
   14244                 :             : 
   14245                 :     2873154 :   *walk_subtrees = !IS_TYPE_OR_DECL_P (t);
   14246                 :     2873154 :   return NULL_TREE;
   14247                 :             : }
   14248                 :             : 
   14249                 :             : /* Data to be communicated between lower_omp_regimplify_operands and
   14250                 :             :    lower_omp_regimplify_operands_p.  */
   14251                 :             : 
   14252                 :             : struct lower_omp_regimplify_operands_data
   14253                 :             : {
   14254                 :             :   omp_context *ctx;
   14255                 :             :   vec<tree> *decls;
   14256                 :             : };
   14257                 :             : 
   14258                 :             : /* Helper function for lower_omp_regimplify_operands.  Find
   14259                 :             :    omp_member_access_dummy_var vars and adjust temporarily their
   14260                 :             :    DECL_VALUE_EXPRs if needed.  */
   14261                 :             : 
   14262                 :             : static tree
   14263                 :      364658 : lower_omp_regimplify_operands_p (tree *tp, int *walk_subtrees,
   14264                 :             :                                  void *data)
   14265                 :             : {
   14266                 :      364658 :   tree t = omp_member_access_dummy_var (*tp);
   14267                 :      364658 :   if (t)
   14268                 :             :     {
   14269                 :           8 :       struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
   14270                 :           8 :       lower_omp_regimplify_operands_data *ldata
   14271                 :             :         = (lower_omp_regimplify_operands_data *) wi->info;
   14272                 :           8 :       tree o = maybe_lookup_decl (t, ldata->ctx);
   14273                 :           8 :       if (o != t)
   14274                 :             :         {
   14275                 :           8 :           ldata->decls->safe_push (DECL_VALUE_EXPR (*tp));
   14276                 :           8 :           ldata->decls->safe_push (*tp);
   14277                 :           8 :           tree v = unshare_and_remap (DECL_VALUE_EXPR (*tp), t, o);
   14278                 :           8 :           SET_DECL_VALUE_EXPR (*tp, v);
   14279                 :             :         }
   14280                 :             :     }
   14281                 :      364658 :   *walk_subtrees = !IS_TYPE_OR_DECL_P (*tp);
   14282                 :      364658 :   return NULL_TREE;
   14283                 :             : }
   14284                 :             : 
   14285                 :             : /* Wrapper around gimple_regimplify_operands that adjusts DECL_VALUE_EXPRs
   14286                 :             :    of omp_member_access_dummy_var vars during regimplification.  */
   14287                 :             : 
   14288                 :             : static void
   14289                 :       96014 : lower_omp_regimplify_operands (omp_context *ctx, gimple *stmt,
   14290                 :             :                                gimple_stmt_iterator *gsi_p)
   14291                 :             : {
   14292                 :       96014 :   auto_vec<tree, 10> decls;
   14293                 :       96014 :   if (ctx)
   14294                 :             :     {
   14295                 :       93484 :       struct walk_stmt_info wi;
   14296                 :       93484 :       memset (&wi, '\0', sizeof (wi));
   14297                 :       93484 :       struct lower_omp_regimplify_operands_data data;
   14298                 :       93484 :       data.ctx = ctx;
   14299                 :       93484 :       data.decls = &decls;
   14300                 :       93484 :       wi.info = &data;
   14301                 :       93484 :       walk_gimple_op (stmt, lower_omp_regimplify_operands_p, &wi);
   14302                 :             :     }
   14303                 :       96014 :   gimple_regimplify_operands (stmt, gsi_p);
   14304                 :      288050 :   while (!decls.is_empty ())
   14305                 :             :     {
   14306                 :           8 :       tree t = decls.pop ();
   14307                 :           8 :       tree v = decls.pop ();
   14308                 :           8 :       SET_DECL_VALUE_EXPR (t, v);
   14309                 :             :     }
   14310                 :       96014 : }
   14311                 :             : 
   14312                 :             : static void
   14313                 :     2287947 : lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   14314                 :             : {
   14315                 :     2287947 :   gimple *stmt = gsi_stmt (*gsi_p);
   14316                 :     2287947 :   struct walk_stmt_info wi;
   14317                 :     2287947 :   gcall *call_stmt;
   14318                 :             : 
   14319                 :     2287947 :   if (gimple_has_location (stmt))
   14320                 :     1874186 :     input_location = gimple_location (stmt);
   14321                 :             : 
   14322                 :     2287947 :   if (make_addressable_vars)
   14323                 :      154642 :     memset (&wi, '\0', sizeof (wi));
   14324                 :             : 
   14325                 :             :   /* If we have issued syntax errors, avoid doing any heavy lifting.
   14326                 :             :      Just replace the OMP directives with a NOP to avoid
   14327                 :             :      confusing RTL expansion.  */
   14328                 :     2287947 :   if (seen_error () && is_gimple_omp (stmt))
   14329                 :             :     {
   14330                 :       12570 :       gsi_replace (gsi_p, gimple_build_nop (), true);
   14331                 :       12570 :       return;
   14332                 :             :     }
   14333                 :             : 
   14334                 :     2275377 :   switch (gimple_code (stmt))
   14335                 :             :     {
   14336                 :      144719 :     case GIMPLE_COND:
   14337                 :      144719 :       {
   14338                 :      144719 :         gcond *cond_stmt = as_a <gcond *> (stmt);
   14339                 :       82996 :         if ((ctx || make_addressable_vars)
   14340                 :      148649 :             && (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
   14341                 :             :                            lower_omp_regimplify_p,
   14342                 :             :                            ctx ? NULL : &wi, NULL)
   14343                 :      125614 :                 || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
   14344                 :             :                               lower_omp_regimplify_p,
   14345                 :             :                               ctx ? NULL : &wi, NULL)))
   14346                 :        1160 :           lower_omp_regimplify_operands (ctx, cond_stmt, gsi_p);
   14347                 :             :       }
   14348                 :             :       break;
   14349                 :          20 :     case GIMPLE_CATCH:
   14350                 :          20 :       lower_omp (gimple_catch_handler_ptr (as_a <gcatch *> (stmt)), ctx);
   14351                 :          20 :       break;
   14352                 :           0 :     case GIMPLE_EH_FILTER:
   14353                 :           0 :       lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
   14354                 :           0 :       break;
   14355                 :       23859 :     case GIMPLE_TRY:
   14356                 :       23859 :       lower_omp (gimple_try_eval_ptr (stmt), ctx);
   14357                 :       23854 :       lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
   14358                 :       23854 :       break;
   14359                 :           0 :     case GIMPLE_ASSUME:
   14360                 :           0 :       lower_omp (gimple_assume_body_ptr (stmt), ctx);
   14361                 :           0 :       break;
   14362                 :           6 :     case GIMPLE_TRANSACTION:
   14363                 :           6 :       lower_omp (gimple_transaction_body_ptr (as_a <gtransaction *> (stmt)),
   14364                 :             :                  ctx);
   14365                 :           6 :       break;
   14366                 :      159351 :     case GIMPLE_BIND:
   14367                 :      159351 :       if (ctx && is_gimple_omp_oacc (ctx->stmt))
   14368                 :             :         {
   14369                 :       17474 :           tree vars = gimple_bind_vars (as_a <gbind *> (stmt));
   14370                 :       17474 :           oacc_privatization_scan_decl_chain (ctx, vars);
   14371                 :             :         }
   14372                 :      159351 :       lower_omp (gimple_bind_body_ptr (as_a <gbind *> (stmt)), ctx);
   14373                 :      159344 :       maybe_remove_omp_member_access_dummy_vars (as_a <gbind *> (stmt));
   14374                 :      159344 :       break;
   14375                 :       19937 :     case GIMPLE_OMP_PARALLEL:
   14376                 :       19937 :     case GIMPLE_OMP_TASK:
   14377                 :       19937 :       ctx = maybe_lookup_ctx (stmt);
   14378                 :       19937 :       gcc_assert (ctx);
   14379                 :       19937 :       if (ctx->cancellable)
   14380                 :         149 :         ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
   14381                 :       19937 :       lower_omp_taskreg (gsi_p, ctx);
   14382                 :       19937 :       break;
   14383                 :       46675 :     case GIMPLE_OMP_FOR:
   14384                 :       46675 :       ctx = maybe_lookup_ctx (stmt);
   14385                 :       46675 :       gcc_assert (ctx);
   14386                 :       46675 :       if (ctx->cancellable)
   14387                 :          86 :         ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
   14388                 :       46675 :       lower_omp_for (gsi_p, ctx);
   14389                 :       46675 :       break;
   14390                 :         433 :     case GIMPLE_OMP_SECTIONS:
   14391                 :         433 :       ctx = maybe_lookup_ctx (stmt);
   14392                 :         433 :       gcc_assert (ctx);
   14393                 :         433 :       if (ctx->cancellable)
   14394                 :          21 :         ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
   14395                 :         433 :       lower_omp_sections (gsi_p, ctx);
   14396                 :         433 :       break;
   14397                 :         148 :     case GIMPLE_OMP_SCOPE:
   14398                 :         148 :       ctx = maybe_lookup_ctx (stmt);
   14399                 :         148 :       gcc_assert (ctx);
   14400                 :         148 :       lower_omp_scope (gsi_p, ctx);
   14401                 :         148 :       break;
   14402                 :        1156 :     case GIMPLE_OMP_SINGLE:
   14403                 :        1156 :       ctx = maybe_lookup_ctx (stmt);
   14404                 :        1156 :       gcc_assert (ctx);
   14405                 :        1156 :       lower_omp_single (gsi_p, ctx);
   14406                 :        1156 :       break;
   14407                 :         582 :     case GIMPLE_OMP_STRUCTURED_BLOCK:
   14408                 :             :       /* We have already done error checking at this point, so these nodes
   14409                 :             :          can be completely removed and replaced with their body.  */
   14410                 :         582 :       ctx = maybe_lookup_ctx (stmt);
   14411                 :         582 :       gcc_assert (ctx);
   14412                 :         582 :       lower_omp (gimple_omp_body_ptr (stmt), ctx);
   14413                 :         582 :       gsi_replace_with_seq (gsi_p, gimple_omp_body (stmt), true);
   14414                 :         582 :       break;
   14415                 :        1152 :     case GIMPLE_OMP_MASTER:
   14416                 :        1152 :     case GIMPLE_OMP_MASKED:
   14417                 :        1152 :       ctx = maybe_lookup_ctx (stmt);
   14418                 :        1152 :       gcc_assert (ctx);
   14419                 :        1152 :       lower_omp_master (gsi_p, ctx);
   14420                 :        1152 :       break;
   14421                 :         572 :     case GIMPLE_OMP_TASKGROUP:
   14422                 :         572 :       ctx = maybe_lookup_ctx (stmt);
   14423                 :         572 :       gcc_assert (ctx);
   14424                 :         572 :       lower_omp_taskgroup (gsi_p, ctx);
   14425                 :         572 :       break;
   14426                 :        1209 :     case GIMPLE_OMP_ORDERED:
   14427                 :        1209 :       ctx = maybe_lookup_ctx (stmt);
   14428                 :        1209 :       gcc_assert (ctx);
   14429                 :        1209 :       lower_omp_ordered (gsi_p, ctx);
   14430                 :        1209 :       break;
   14431                 :        1356 :     case GIMPLE_OMP_SCAN:
   14432                 :        1356 :       ctx = maybe_lookup_ctx (stmt);
   14433                 :        1356 :       gcc_assert (ctx);
   14434                 :        1356 :       lower_omp_scan (gsi_p, ctx);
   14435                 :        1356 :       break;
   14436                 :         334 :     case GIMPLE_OMP_CRITICAL:
   14437                 :         334 :       ctx = maybe_lookup_ctx (stmt);
   14438                 :         334 :       gcc_assert (ctx);
   14439                 :         334 :       lower_omp_critical (gsi_p, ctx);
   14440                 :         334 :       break;
   14441                 :        2548 :     case GIMPLE_OMP_ATOMIC_LOAD:
   14442                 :          90 :       if ((ctx || make_addressable_vars)
   14443                 :        2548 :           && walk_tree (gimple_omp_atomic_load_rhs_ptr (
   14444                 :             :                           as_a <gomp_atomic_load *> (stmt)),
   14445                 :             :                         lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
   14446                 :        1426 :         lower_omp_regimplify_operands (ctx, stmt, gsi_p);
   14447                 :             :       break;
   14448                 :       35389 :     case GIMPLE_OMP_TARGET:
   14449                 :       35389 :       ctx = maybe_lookup_ctx (stmt);
   14450                 :       35389 :       gcc_assert (ctx);
   14451                 :       35389 :       lower_omp_target (gsi_p, ctx);
   14452                 :       35389 :       break;
   14453                 :        8622 :     case GIMPLE_OMP_TEAMS:
   14454                 :        8622 :       ctx = maybe_lookup_ctx (stmt);
   14455                 :        8622 :       gcc_assert (ctx);
   14456                 :        8622 :       if (gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
   14457                 :        2625 :         lower_omp_taskreg (gsi_p, ctx);
   14458                 :             :       else
   14459                 :        5997 :         lower_omp_teams (gsi_p, ctx);
   14460                 :             :       break;
   14461                 :      119487 :     case GIMPLE_CALL:
   14462                 :      119487 :       tree fndecl;
   14463                 :      119487 :       call_stmt = as_a <gcall *> (stmt);
   14464                 :      119487 :       fndecl = gimple_call_fndecl (call_stmt);
   14465                 :      119487 :       if (fndecl
   14466                 :      119487 :           && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
   14467                 :       33040 :         switch (DECL_FUNCTION_CODE (fndecl))
   14468                 :             :           {
   14469                 :         723 :           case BUILT_IN_GOMP_BARRIER:
   14470                 :         723 :             if (ctx == NULL)
   14471                 :             :               break;
   14472                 :             :             /* FALLTHRU */
   14473                 :        1053 :           case BUILT_IN_GOMP_CANCEL:
   14474                 :        1053 :           case BUILT_IN_GOMP_CANCELLATION_POINT:
   14475                 :        1053 :             omp_context *cctx;
   14476                 :        1053 :             cctx = ctx;
   14477                 :        1053 :             if (gimple_code (cctx->stmt) == GIMPLE_OMP_SECTION)
   14478                 :          45 :               cctx = cctx->outer;
   14479                 :        1053 :             gcc_assert (gimple_call_lhs (call_stmt) == NULL_TREE);
   14480                 :        1053 :             if (!cctx->cancellable)
   14481                 :             :               {
   14482                 :         676 :                 if (DECL_FUNCTION_CODE (fndecl)
   14483                 :             :                     == BUILT_IN_GOMP_CANCELLATION_POINT)
   14484                 :             :                   {
   14485                 :           0 :                     stmt = gimple_build_nop ();
   14486                 :           0 :                     gsi_replace (gsi_p, stmt, false);
   14487                 :             :                   }
   14488                 :             :                 break;
   14489                 :             :               }
   14490                 :         377 :             if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
   14491                 :             :               {
   14492                 :          14 :                 fndecl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER_CANCEL);
   14493                 :          14 :                 gimple_call_set_fndecl (call_stmt, fndecl);
   14494                 :          14 :                 gimple_call_set_fntype (call_stmt, TREE_TYPE (fndecl));
   14495                 :             :               }
   14496                 :         377 :             tree lhs;
   14497                 :         377 :             lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (fndecl)));
   14498                 :         377 :             gimple_call_set_lhs (call_stmt, lhs);
   14499                 :         377 :             tree fallthru_label;
   14500                 :         377 :             fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
   14501                 :         377 :             gimple *g;
   14502                 :         377 :             g = gimple_build_label (fallthru_label);
   14503                 :         377 :             gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
   14504                 :         377 :             g = gimple_build_cond (NE_EXPR, lhs,
   14505                 :         377 :                                    fold_convert (TREE_TYPE (lhs),
   14506                 :             :                                                  boolean_false_node),
   14507                 :             :                                    cctx->cancel_label, fallthru_label);
   14508                 :         377 :             gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
   14509                 :         377 :             break;
   14510                 :             :           default:
   14511                 :             :             break;
   14512                 :             :           }
   14513                 :      119453 :       goto regimplify;
   14514                 :             : 
   14515                 :             :     case GIMPLE_ASSIGN:
   14516                 :     1316068 :       for (omp_context *up = ctx; up; up = up->outer)
   14517                 :             :         {
   14518                 :      635402 :           if (gimple_code (up->stmt) == GIMPLE_OMP_ORDERED
   14519                 :             :               || gimple_code (up->stmt) == GIMPLE_OMP_CRITICAL
   14520                 :             :               || gimple_code (up->stmt) == GIMPLE_OMP_TASKGROUP
   14521                 :             :               || gimple_code (up->stmt) == GIMPLE_OMP_SCOPE
   14522                 :             :               || gimple_code (up->stmt) == GIMPLE_OMP_SECTION
   14523                 :             :               || gimple_code (up->stmt) == GIMPLE_OMP_SCAN
   14524                 :             :               || (gimple_code (up->stmt) == GIMPLE_OMP_TARGET
   14525                 :      195544 :                   && (gimple_omp_target_kind (up->stmt)
   14526                 :             :                       == GF_OMP_TARGET_KIND_DATA)))
   14527                 :       90499 :             continue;
   14528                 :      544903 :           else if (!up->lastprivate_conditional_map)
   14529                 :             :             break;
   14530                 :        4278 :           tree lhs = get_base_address (gimple_assign_lhs (stmt));
   14531                 :        4278 :           if (TREE_CODE (lhs) == MEM_REF
   14532                 :          26 :               && DECL_P (TREE_OPERAND (lhs, 0))
   14533                 :        4301 :               && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs,
   14534                 :             :                                                      0))) == REFERENCE_TYPE)
   14535                 :          19 :             lhs = TREE_OPERAND (lhs, 0);
   14536                 :        4278 :           if (DECL_P (lhs))
   14537                 :        3211 :             if (tree *v = up->lastprivate_conditional_map->get (lhs))
   14538                 :             :               {
   14539                 :         393 :                 tree clauses;
   14540                 :         393 :                 if (up->combined_into_simd_safelen1)
   14541                 :             :                   {
   14542                 :          56 :                     up = up->outer;
   14543                 :          56 :                     if (gimple_code (up->stmt) == GIMPLE_OMP_SCAN)
   14544                 :           3 :                       up = up->outer;
   14545                 :             :                   }
   14546                 :         393 :                 if (gimple_code (up->stmt) == GIMPLE_OMP_FOR)
   14547                 :         309 :                   clauses = gimple_omp_for_clauses (up->stmt);
   14548                 :             :                 else
   14549                 :          84 :                   clauses = gimple_omp_sections_clauses (up->stmt);
   14550                 :         393 :                 tree c = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_);
   14551                 :         393 :                 if (!OMP_CLAUSE__CONDTEMP__ITER (c))
   14552                 :         359 :                   c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
   14553                 :             :                                        OMP_CLAUSE__CONDTEMP_);
   14554                 :         393 :                 gcc_assert (OMP_CLAUSE__CONDTEMP__ITER (c));
   14555                 :         393 :                 gimple *g = gimple_build_assign (*v, OMP_CLAUSE_DECL (c));
   14556                 :         393 :                 gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
   14557                 :             :               }
   14558                 :             :         }
   14559                 :             :       /* FALLTHRU */
   14560                 :             : 
   14561                 :     1827309 :     default:
   14562                 :     1827309 :     regimplify:
   14563                 :      948805 :       if ((ctx || make_addressable_vars)
   14564                 :     1904032 :           && walk_gimple_op (stmt, lower_omp_regimplify_p,
   14565                 :             :                              ctx ? NULL : &wi))
   14566                 :             :         {
   14567                 :             :           /* Just remove clobbers, this should happen only if we have
   14568                 :             :              "privatized" local addressable variables in SIMD regions,
   14569                 :             :              the clobber isn't needed in that case and gimplifying address
   14570                 :             :              of the ARRAY_REF into a pointer and creating MEM_REF based
   14571                 :             :              clobber would create worse code than we get with the clobber
   14572                 :             :              dropped.  */
   14573                 :       93564 :           if (gimple_clobber_p (stmt))
   14574                 :             :             {
   14575                 :         136 :               gsi_replace (gsi_p, gimple_build_nop (), true);
   14576                 :         136 :               break;
   14577                 :             :             }
   14578                 :       93428 :           lower_omp_regimplify_operands (ctx, stmt, gsi_p);
   14579                 :             :         }
   14580                 :             :       break;
   14581                 :             :     }
   14582                 :             : }
   14583                 :             : 
   14584                 :             : static void
   14585                 :      394716 : lower_omp (gimple_seq *body, omp_context *ctx)
   14586                 :             : {
   14587                 :      394716 :   location_t saved_location = input_location;
   14588                 :      394716 :   gimple_stmt_iterator gsi;
   14589                 :     3028170 :   for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
   14590                 :     2287947 :     lower_omp_1 (&gsi, ctx);
   14591                 :             :   /* During gimplification, we haven't folded statments inside offloading
   14592                 :             :      or taskreg regions (gimplify.cc:maybe_fold_stmt); do that now.  */
   14593                 :      394700 :   if (target_nesting_level || taskreg_nesting_level)
   14594                 :      572876 :     for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
   14595                 :      374373 :       fold_stmt (&gsi);
   14596                 :      394700 :   input_location = saved_location;
   14597                 :      394700 : }
   14598                 :             : 
   14599                 :             : /* Main entry point.  */
   14600                 :             : 
   14601                 :             : static unsigned int
   14602                 :     2688906 : execute_lower_omp (void)
   14603                 :             : {
   14604                 :     2688906 :   gimple_seq body;
   14605                 :     2688906 :   int i;
   14606                 :     2688906 :   omp_context *ctx;
   14607                 :             : 
   14608                 :             :   /* This pass always runs, to provide PROP_gimple_lomp.
   14609                 :             :      But often, there is nothing to do.  */
   14610                 :     2688906 :   if (flag_openacc == 0 && flag_openmp == 0
   14611                 :     2648596 :       && flag_openmp_simd == 0)
   14612                 :             :     return 0;
   14613                 :             : 
   14614                 :       42651 :   all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
   14615                 :             :                                  delete_omp_context);
   14616                 :             : 
   14617                 :       42651 :   body = gimple_body (current_function_decl);
   14618                 :             : 
   14619                 :       42651 :   scan_omp (&body, NULL);
   14620                 :       42651 :   gcc_assert (taskreg_nesting_level == 0);
   14621                 :       69562 :   FOR_EACH_VEC_ELT (taskreg_contexts, i, ctx)
   14622                 :       26911 :     finish_taskreg_scan (ctx);
   14623                 :       42651 :   taskreg_contexts.release ();
   14624                 :             : 
   14625                 :       42651 :   if (all_contexts->root)
   14626                 :             :     {
   14627                 :       24510 :       if (make_addressable_vars)
   14628                 :         632 :         push_gimplify_context ();
   14629                 :       24510 :       lower_omp (&body, NULL);
   14630                 :       24506 :       if (make_addressable_vars)
   14631                 :         632 :         pop_gimplify_context (NULL);
   14632                 :             :     }
   14633                 :             : 
   14634                 :       42647 :   if (all_contexts)
   14635                 :             :     {
   14636                 :       42647 :       splay_tree_delete (all_contexts);
   14637                 :       42647 :       all_contexts = NULL;
   14638                 :             :     }
   14639                 :       42647 :   BITMAP_FREE (make_addressable_vars);
   14640                 :       42647 :   BITMAP_FREE (global_nonaddressable_vars);
   14641                 :             : 
   14642                 :             :   /* If current function is a method, remove artificial dummy VAR_DECL created
   14643                 :             :      for non-static data member privatization, they aren't needed for
   14644                 :             :      debuginfo nor anything else, have been already replaced everywhere in the
   14645                 :             :      IL and cause problems with LTO.  */
   14646                 :       42647 :   if (DECL_ARGUMENTS (current_function_decl)
   14647                 :       20886 :       && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl))
   14648                 :       46111 :       && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl)))
   14649                 :             :           == POINTER_TYPE))
   14650                 :        3119 :     remove_member_access_dummy_vars (DECL_INITIAL (current_function_decl));
   14651                 :             : 
   14652                 :       43696 :   for (auto task_stmt : task_cpyfns)
   14653                 :         549 :     finalize_task_copyfn (task_stmt);
   14654                 :       42647 :   task_cpyfns.release ();
   14655                 :       42647 :   return 0;
   14656                 :             : }
   14657                 :             : 
   14658                 :             : namespace {
   14659                 :             : 
   14660                 :             : const pass_data pass_data_lower_omp =
   14661                 :             : {
   14662                 :             :   GIMPLE_PASS, /* type */
   14663                 :             :   "omplower", /* name */
   14664                 :             :   OPTGROUP_OMP, /* optinfo_flags */
   14665                 :             :   TV_NONE, /* tv_id */
   14666                 :             :   PROP_gimple_any, /* properties_required */
   14667                 :             :   PROP_gimple_lomp | PROP_gimple_lomp_dev, /* properties_provided */
   14668                 :             :   0, /* properties_destroyed */
   14669                 :             :   0, /* todo_flags_start */
   14670                 :             :   0, /* todo_flags_finish */
   14671                 :             : };
   14672                 :             : 
   14673                 :             : class pass_lower_omp : public gimple_opt_pass
   14674                 :             : {
   14675                 :             : public:
   14676                 :      281914 :   pass_lower_omp (gcc::context *ctxt)
   14677                 :      563828 :     : gimple_opt_pass (pass_data_lower_omp, ctxt)
   14678                 :             :   {}
   14679                 :             : 
   14680                 :             :   /* opt_pass methods: */
   14681                 :     2688906 :   unsigned int execute (function *) final override
   14682                 :             :   {
   14683                 :     2688906 :     return execute_lower_omp ();
   14684                 :             :   }
   14685                 :             : 
   14686                 :             : }; // class pass_lower_omp
   14687                 :             : 
   14688                 :             : } // anon namespace
   14689                 :             : 
   14690                 :             : gimple_opt_pass *
   14691                 :      281914 : make_pass_lower_omp (gcc::context *ctxt)
   14692                 :             : {
   14693                 :      281914 :   return new pass_lower_omp (ctxt);
   14694                 :             : }
   14695                 :             : 
   14696                 :             : /* The following is a utility to diagnose structured block violations.
   14697                 :             :    It is not part of the "omplower" pass, as that's invoked too late.  It
   14698                 :             :    should be invoked by the respective front ends after gimplification.  */
   14699                 :             : 
   14700                 :             : static splay_tree all_labels;
   14701                 :             : 
   14702                 :             : /* Check for mismatched contexts and generate an error if needed.  Return
   14703                 :             :    true if an error is detected.  */
   14704                 :             : 
   14705                 :             : static bool
   14706                 :      480296 : diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
   14707                 :             :                gimple *branch_ctx, gimple *label_ctx)
   14708                 :             : {
   14709                 :      480296 :   gcc_checking_assert (!branch_ctx || is_gimple_omp (branch_ctx));
   14710                 :      480296 :   gcc_checking_assert (!label_ctx || is_gimple_omp (label_ctx));
   14711                 :             : 
   14712                 :      480296 :   if (label_ctx == branch_ctx)
   14713                 :             :     return false;
   14714                 :             : 
   14715                 :         202 :   const char* kind = NULL;
   14716                 :             : 
   14717                 :         202 :   if (flag_openacc)
   14718                 :             :     {
   14719                 :           6 :       if ((branch_ctx && is_gimple_omp_oacc (branch_ctx))
   14720                 :          13 :           || (label_ctx && is_gimple_omp_oacc (label_ctx)))
   14721                 :             :         {
   14722                 :             :           gcc_checking_assert (kind == NULL);
   14723                 :             :           kind = "OpenACC";
   14724                 :             :         }
   14725                 :             :     }
   14726                 :             :   if (kind == NULL)
   14727                 :             :     {
   14728                 :         189 :       gcc_checking_assert (flag_openmp || flag_openmp_simd);
   14729                 :             :       kind = "OpenMP";
   14730                 :             :     }
   14731                 :             : 
   14732                 :             :   /* Previously we kept track of the label's entire context in diagnose_sb_[12]
   14733                 :             :      so we could traverse it and issue a correct "exit" or "enter" error
   14734                 :             :      message upon a structured block violation.
   14735                 :             : 
   14736                 :             :      We built the context by building a list with tree_cons'ing, but there is
   14737                 :             :      no easy counterpart in gimple tuples.  It seems like far too much work
   14738                 :             :      for issuing exit/enter error messages.  If someone really misses the
   14739                 :             :      distinct error message... patches welcome.  */
   14740                 :             : 
   14741                 :             : #if 0
   14742                 :             :   /* Try to avoid confusing the user by producing and error message
   14743                 :             :      with correct "exit" or "enter" verbiage.  We prefer "exit"
   14744                 :             :      unless we can show that LABEL_CTX is nested within BRANCH_CTX.  */
   14745                 :             :   if (branch_ctx == NULL)
   14746                 :             :     exit_p = false;
   14747                 :             :   else
   14748                 :             :     {
   14749                 :             :       while (label_ctx)
   14750                 :             :         {
   14751                 :             :           if (TREE_VALUE (label_ctx) == branch_ctx)
   14752                 :             :             {
   14753                 :             :               exit_p = false;
   14754                 :             :               break;
   14755                 :             :             }
   14756                 :             :           label_ctx = TREE_CHAIN (label_ctx);
   14757                 :             :         }
   14758                 :             :     }
   14759                 :             : 
   14760                 :             :   if (exit_p)
   14761                 :             :     error ("invalid exit from %s structured block", kind);
   14762                 :             :   else
   14763                 :             :     error ("invalid entry to %s structured block", kind);
   14764                 :             : #endif
   14765                 :             : 
   14766                 :             :   /* If it's obvious we have an invalid entry, be specific about the error.  */
   14767                 :         202 :   if (branch_ctx == NULL)
   14768                 :          59 :     error ("invalid entry to %s structured block", kind);
   14769                 :             :   else
   14770                 :             :     {
   14771                 :             :       /* Otherwise, be vague and lazy, but efficient.  */
   14772                 :         143 :       error ("invalid branch to/from %s structured block", kind);
   14773                 :             :     }
   14774                 :             : 
   14775                 :         202 :   gsi_replace (gsi_p, gimple_build_nop (), false);
   14776                 :         202 :   return true;
   14777                 :             : }
   14778                 :             : 
   14779                 :             : /* Pass 1: Create a minimal tree of structured blocks, and record
   14780                 :             :    where each label is found.  */
   14781                 :             : 
   14782                 :             : static tree
   14783                 :     2853715 : diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
   14784                 :             :                struct walk_stmt_info *wi)
   14785                 :             : {
   14786                 :     2853715 :   gimple *context = (gimple *) wi->info;
   14787                 :     2853715 :   gimple *inner_context;
   14788                 :     2853715 :   gimple *stmt = gsi_stmt (*gsi_p);
   14789                 :             : 
   14790                 :     2853715 :   *handled_ops_p = true;
   14791                 :             : 
   14792                 :     2853715 :   switch (gimple_code (stmt))
   14793                 :             :     {
   14794                 :      274507 :     WALK_SUBSTMTS;
   14795                 :             : 
   14796                 :       83929 :     case GIMPLE_OMP_PARALLEL:
   14797                 :       83929 :     case GIMPLE_OMP_TASK:
   14798                 :       83929 :     case GIMPLE_OMP_SCOPE:
   14799                 :       83929 :     case GIMPLE_OMP_SECTIONS:
   14800                 :       83929 :     case GIMPLE_OMP_SINGLE:
   14801                 :       83929 :     case GIMPLE_OMP_SECTION:
   14802                 :       83929 :     case GIMPLE_OMP_STRUCTURED_BLOCK:
   14803                 :       83929 :     case GIMPLE_OMP_MASTER:
   14804                 :       83929 :     case GIMPLE_OMP_MASKED:
   14805                 :       83929 :     case GIMPLE_OMP_ORDERED:
   14806                 :       83929 :     case GIMPLE_OMP_SCAN:
   14807                 :       83929 :     case GIMPLE_OMP_CRITICAL:
   14808                 :       83929 :     case GIMPLE_OMP_TARGET:
   14809                 :       83929 :     case GIMPLE_OMP_TEAMS:
   14810                 :       83929 :     case GIMPLE_OMP_TASKGROUP:
   14811                 :             :       /* The minimal context here is just the current OMP construct.  */
   14812                 :       83929 :       inner_context = stmt;
   14813                 :       83929 :       wi->info = inner_context;
   14814                 :       83929 :       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
   14815                 :       83929 :       wi->info = context;
   14816                 :       83929 :       break;
   14817                 :             : 
   14818                 :       53569 :     case GIMPLE_OMP_FOR:
   14819                 :       53569 :       inner_context = stmt;
   14820                 :       53569 :       wi->info = inner_context;
   14821                 :             :       /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
   14822                 :             :          walk them.  */
   14823                 :       53569 :       walk_gimple_seq (gimple_omp_for_pre_body (stmt),
   14824                 :             :                        diagnose_sb_1, NULL, wi);
   14825                 :       53569 :       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
   14826                 :       53569 :       wi->info = context;
   14827                 :       53569 :       break;
   14828                 :             : 
   14829                 :      482856 :     case GIMPLE_LABEL:
   14830                 :      965712 :       splay_tree_insert (all_labels,
   14831                 :      482856 :                          (splay_tree_key) gimple_label_label (
   14832                 :      482856 :                                             as_a <glabel *> (stmt)),
   14833                 :             :                          (splay_tree_value) context);
   14834                 :      482856 :       break;
   14835                 :             : 
   14836                 :             :     default:
   14837                 :             :       break;
   14838                 :             :     }
   14839                 :             : 
   14840                 :     2853715 :   return NULL_TREE;
   14841                 :             : }
   14842                 :             : 
   14843                 :             : /* Pass 2: Check each branch and see if its context differs from that of
   14844                 :             :    the destination label's context.  */
   14845                 :             : 
   14846                 :             : static tree
   14847                 :     2853715 : diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
   14848                 :             :                struct walk_stmt_info *wi)
   14849                 :             : {
   14850                 :     2853715 :   gimple *context = (gimple *) wi->info;
   14851                 :     2853715 :   splay_tree_node n;
   14852                 :     2853715 :   gimple *stmt = gsi_stmt (*gsi_p);
   14853                 :             : 
   14854                 :     2853715 :   *handled_ops_p = true;
   14855                 :             : 
   14856                 :     2853715 :   switch (gimple_code (stmt))
   14857                 :             :     {
   14858                 :      274507 :     WALK_SUBSTMTS;
   14859                 :             : 
   14860                 :       83929 :     case GIMPLE_OMP_PARALLEL:
   14861                 :       83929 :     case GIMPLE_OMP_TASK:
   14862                 :       83929 :     case GIMPLE_OMP_SCOPE:
   14863                 :       83929 :     case GIMPLE_OMP_SECTIONS:
   14864                 :       83929 :     case GIMPLE_OMP_SINGLE:
   14865                 :       83929 :     case GIMPLE_OMP_SECTION:
   14866                 :       83929 :     case GIMPLE_OMP_STRUCTURED_BLOCK:
   14867                 :       83929 :     case GIMPLE_OMP_MASTER:
   14868                 :       83929 :     case GIMPLE_OMP_MASKED:
   14869                 :       83929 :     case GIMPLE_OMP_ORDERED:
   14870                 :       83929 :     case GIMPLE_OMP_SCAN:
   14871                 :       83929 :     case GIMPLE_OMP_CRITICAL:
   14872                 :       83929 :     case GIMPLE_OMP_TARGET:
   14873                 :       83929 :     case GIMPLE_OMP_TEAMS:
   14874                 :       83929 :     case GIMPLE_OMP_TASKGROUP:
   14875                 :       83929 :       wi->info = stmt;
   14876                 :       83929 :       walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
   14877                 :       83929 :       wi->info = context;
   14878                 :       83929 :       break;
   14879                 :             : 
   14880                 :       53569 :     case GIMPLE_OMP_FOR:
   14881                 :       53569 :       wi->info = stmt;
   14882                 :             :       /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
   14883                 :             :          walk them.  */
   14884                 :       53569 :       walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
   14885                 :             :                            diagnose_sb_2, NULL, wi);
   14886                 :       53569 :       walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
   14887                 :       53569 :       wi->info = context;
   14888                 :       53569 :       break;
   14889                 :             : 
   14890                 :      179986 :     case GIMPLE_COND:
   14891                 :      179986 :         {
   14892                 :      179986 :           gcond *cond_stmt = as_a <gcond *> (stmt);
   14893                 :      179986 :           tree lab = gimple_cond_true_label (cond_stmt);
   14894                 :      179986 :           if (lab)
   14895                 :             :             {
   14896                 :      179986 :               n = splay_tree_lookup (all_labels,
   14897                 :             :                                      (splay_tree_key) lab);
   14898                 :      359972 :               diagnose_sb_0 (gsi_p, context,
   14899                 :      179986 :                              n ? (gimple *) n->value : NULL);
   14900                 :             :             }
   14901                 :      179986 :           lab = gimple_cond_false_label (cond_stmt);
   14902                 :      179986 :           if (lab)
   14903                 :             :             {
   14904                 :      179986 :               n = splay_tree_lookup (all_labels,
   14905                 :             :                                      (splay_tree_key) lab);
   14906                 :      359972 :               diagnose_sb_0 (gsi_p, context,
   14907                 :      179986 :                              n ? (gimple *) n->value : NULL);
   14908                 :             :             }
   14909                 :             :         }
   14910                 :             :       break;
   14911                 :             : 
   14912                 :       94787 :     case GIMPLE_GOTO:
   14913                 :       94787 :       {
   14914                 :       94787 :         tree lab = gimple_goto_dest (stmt);
   14915                 :       94787 :         if (TREE_CODE (lab) != LABEL_DECL)
   14916                 :             :           break;
   14917                 :             : 
   14918                 :       94787 :         n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
   14919                 :       94787 :         diagnose_sb_0 (gsi_p, context, n ? (gimple *) n->value : NULL);
   14920                 :             :       }
   14921                 :       94787 :       break;
   14922                 :             : 
   14923                 :         432 :     case GIMPLE_SWITCH:
   14924                 :         432 :       {
   14925                 :         432 :         gswitch *switch_stmt = as_a <gswitch *> (stmt);
   14926                 :         432 :         unsigned int i;
   14927                 :        1507 :         for (i = 0; i < gimple_switch_num_labels (switch_stmt); ++i)
   14928                 :             :           {
   14929                 :        1090 :             tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
   14930                 :        1090 :             n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
   14931                 :        1090 :             if (n && diagnose_sb_0 (gsi_p, context, (gimple *) n->value))
   14932                 :             :               break;
   14933                 :             :           }
   14934                 :             :       }
   14935                 :             :       break;
   14936                 :             : 
   14937                 :       24447 :     case GIMPLE_RETURN:
   14938                 :       24447 :       diagnose_sb_0 (gsi_p, context, NULL);
   14939                 :       24447 :       break;
   14940                 :             : 
   14941                 :             :     default:
   14942                 :             :       break;
   14943                 :             :     }
   14944                 :             : 
   14945                 :     2853715 :   return NULL_TREE;
   14946                 :             : }
   14947                 :             : 
   14948                 :             : static unsigned int
   14949                 :       42664 : diagnose_omp_structured_block_errors (void)
   14950                 :             : {
   14951                 :       42664 :   struct walk_stmt_info wi;
   14952                 :       42664 :   gimple_seq body = gimple_body (current_function_decl);
   14953                 :             : 
   14954                 :       42664 :   all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
   14955                 :             : 
   14956                 :       42664 :   memset (&wi, 0, sizeof (wi));
   14957                 :       42664 :   walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
   14958                 :             : 
   14959                 :       42664 :   memset (&wi, 0, sizeof (wi));
   14960                 :       42664 :   wi.want_locations = true;
   14961                 :       42664 :   walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);
   14962                 :             : 
   14963                 :       42664 :   gimple_set_body (current_function_decl, body);
   14964                 :             : 
   14965                 :       42664 :   splay_tree_delete (all_labels);
   14966                 :       42664 :   all_labels = NULL;
   14967                 :             : 
   14968                 :       42664 :   return 0;
   14969                 :             : }
   14970                 :             : 
   14971                 :             : namespace {
   14972                 :             : 
   14973                 :             : const pass_data pass_data_diagnose_omp_blocks =
   14974                 :             : {
   14975                 :             :   GIMPLE_PASS, /* type */
   14976                 :             :   "*diagnose_omp_blocks", /* name */
   14977                 :             :   OPTGROUP_OMP, /* optinfo_flags */
   14978                 :             :   TV_NONE, /* tv_id */
   14979                 :             :   PROP_gimple_any, /* properties_required */
   14980                 :             :   0, /* properties_provided */
   14981                 :             :   0, /* properties_destroyed */
   14982                 :             :   0, /* todo_flags_start */
   14983                 :             :   0, /* todo_flags_finish */
   14984                 :             : };
   14985                 :             : 
   14986                 :             : class pass_diagnose_omp_blocks : public gimple_opt_pass
   14987                 :             : {
   14988                 :             : public:
   14989                 :      281914 :   pass_diagnose_omp_blocks (gcc::context *ctxt)
   14990                 :      563828 :     : gimple_opt_pass (pass_data_diagnose_omp_blocks, ctxt)
   14991                 :             :   {}
   14992                 :             : 
   14993                 :             :   /* opt_pass methods: */
   14994                 :     2688925 :   bool gate (function *) final override
   14995                 :             :   {
   14996                 :     2688925 :     return flag_openacc || flag_openmp || flag_openmp_simd;
   14997                 :             :   }
   14998                 :       42664 :   unsigned int execute (function *) final override
   14999                 :             :     {
   15000                 :       42664 :       return diagnose_omp_structured_block_errors ();
   15001                 :             :     }
   15002                 :             : 
   15003                 :             : }; // class pass_diagnose_omp_blocks
   15004                 :             : 
   15005                 :             : } // anon namespace
   15006                 :             : 
   15007                 :             : gimple_opt_pass *
   15008                 :      281914 : make_pass_diagnose_omp_blocks (gcc::context *ctxt)
   15009                 :             : {
   15010                 :      281914 :   return new pass_diagnose_omp_blocks (ctxt);
   15011                 :             : }
   15012                 :             : 
   15013                 :             : 
   15014                 :             : #include "gt-omp-low.h"
        

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