/* Lowering pass for OMP directives.  Converts OMP directives into explicit
   calls to the runtime library (libgomp), data marshalling to implement data
   sharing and copying clauses, offloading to accelerators, and more.

   Contributed by Diego Novillo <dnovillo@redhat.com>

   Copyright (C) 2005-2021 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "ssa.h"
#include "cgraph.h"
#include "pretty-print.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "internal-fn.h"
#include "gimple-fold.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "gimple-walk.h"
#include "tree-iterator.h"
#include "tree-inline.h"
#include "langhooks.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "splay-tree.h"
#include "omp-general.h"
#include "omp-low.h"
#include "gimple-low.h"
#include "alloc-pool.h"
#include "symbol-summary.h"
#include "tree-nested.h"
#include "context.h"
#include "gomp-constants.h"
#include "gimple-pretty-print.h"
#include "stringpool.h"
#include "attribs.h"
#include "omp-offload.h"

/* Lowering of OMP parallel and workshare constructs proceeds in two
   phases.  The first phase scans the function looking for OMP statements
   and then for variables that must be replaced to satisfy data sharing
   clauses.  The second phase expands code for the constructs, as well as
   re-gimplifying things when variables have been replaced with complex
   expressions.

   Final code generation is done by pass_expand_omp.  The flowgraph is
   scanned for regions which are then moved to a new
   function, to be invoked by the thread library, or offloaded.  */

/* Context structure.  Used to store information about each parallel
   directive in the code.  */

struct omp_context
{
  /* This field must be at the beginning, as we do "inheritance": Some
     callback functions for tree-inline.c (e.g., omp_copy_decl)
     receive a copy_body_data pointer that is up-casted to an
     omp_context pointer.  */
  copy_body_data cb;

  /* The tree of contexts corresponding to the encountered constructs.  */
  struct omp_context *outer;
  gimple *stmt;

  /* Map variables to fields in a structure that allows communication
     between sending and receiving threads.  */
  splay_tree field_map;
  tree record_type;
  tree sender_decl;
  tree receiver_decl;

  /* These are used just by task contexts, if task firstprivate fn is
     needed.  srecord_type is used to communicate from the thread
     that encountered the task construct to task firstprivate fn,
     record_type is allocated by GOMP_task, initialized by task firstprivate
     fn and passed to the task body fn.  */
  splay_tree sfield_map;
  tree srecord_type;

  /* A chain of variables to add to the top-level block surrounding the
     construct.  In the case of a parallel, this is in the child function.  */
  tree block_vars;

  /* Label to which GOMP_cancel{,llation_point} and explicit and implicit
     barriers should jump to during omplower pass.  */
  tree cancel_label;

  /* The sibling GIMPLE_OMP_FOR simd with _simt_ clause or NULL
     otherwise.  */
  gimple *simt_stmt;

  /* For task reductions registered in this context, a vector containing
     the length of the private copies block (if constant, otherwise NULL)
     and then offsets (if constant, otherwise NULL) for each entry.  */
  vec<tree> task_reductions;

  /* A hash map from the reduction clauses to the registered array
     elts.  */
  hash_map<tree, unsigned> *task_reduction_map;

  /* And a hash map from the lastprivate(conditional:) variables to their
     corresponding tracking loop iteration variables.  */
  hash_map<tree, tree> *lastprivate_conditional_map;

  /* And a hash map from the allocate variables to their corresponding
     allocators.  */
  hash_map<tree, tree> *allocate_map;

  /* A tree_list of the reduction clauses in this context. This is
    only used for checking the consistency of OpenACC reduction
    clauses in scan_omp_for and is not guaranteed to contain a valid
    value outside of this function. */
  tree local_reduction_clauses;

  /* A tree_list of the reduction clauses in outer contexts. This is
    only used for checking the consistency of OpenACC reduction
    clauses in scan_omp_for and is not guaranteed to contain a valid
    value outside of this function. */
  tree outer_reduction_clauses;

  /* Nesting depth of this context.  Used to beautify error messages re
     invalid gotos.  The outermost ctx is depth 1, with depth 0 being
     reserved for the main body of the function.  */
  int depth;

  /* True if this parallel directive is nested within another.  */
  bool is_nested;

  /* True if this construct can be cancelled.  */
  bool cancellable;

  /* True if lower_omp_1 should look up lastprivate conditional in parent
     context.  */
  bool combined_into_simd_safelen1;

  /* True if there is nested scan context with inclusive clause.  */
  bool scan_inclusive;

  /* True if there is nested scan context with exclusive clause.  */
  bool scan_exclusive;

  /* True in the second simd loop of for simd with inscan reductions.  */
  bool for_simd_scan_phase;

  /* True if there is order(concurrent) clause on the construct.  */
  bool order_concurrent;

  /* True if there is bind clause on the construct (i.e. a loop construct).  */
  bool loop_p;

  /* Only used for omp target contexts.  True if a teams construct is
     strictly nested in it.  */
  bool teams_nested_p;

  /* Only used for omp target contexts.  True if an OpenMP construct other
     than teams is strictly nested in it.  */
  bool nonteams_nested_p;

  /* Candidates for adjusting OpenACC privatization level.  */
  vec<tree> oacc_privatization_candidates;
};

static splay_tree all_contexts;
static int taskreg_nesting_level;
static int target_nesting_level;
static bitmap task_shared_vars;
static bitmap global_nonaddressable_vars;
static vec<omp_context *> taskreg_contexts;

static void scan_omp (gimple_seq *, omp_context *);
static tree scan_omp_1_op (tree *, int *, void *);

#define WALK_SUBSTMTS  \
    case GIMPLE_BIND: \
    case GIMPLE_TRY: \
    case GIMPLE_CATCH: \
    case GIMPLE_EH_FILTER: \
    case GIMPLE_TRANSACTION: \
      /* The sub-statements for these should be walked.  */ \
      *handled_ops_p = false; \
      break;

/* Return whether CTX represents an OpenACC 'parallel' or 'serial' construct.
   (This doesn't include OpenACC 'kernels' decomposed parts.)  */

static bool
is_oacc_parallel_or_serial (omp_context *ctx)
{
  enum gimple_code outer_type = gimple_code (ctx->stmt);
  return ((outer_type == GIMPLE_OMP_TARGET)
	  && ((gimple_omp_target_kind (ctx->stmt)
	       == GF_OMP_TARGET_KIND_OACC_PARALLEL)
	      || (gimple_omp_target_kind (ctx->stmt)
		  == GF_OMP_TARGET_KIND_OACC_SERIAL)));
}

/* Return whether CTX represents an OpenACC 'kernels' construct.
   (This doesn't include OpenACC 'kernels' decomposed parts.)  */

static bool
is_oacc_kernels (omp_context *ctx)
{
  enum gimple_code outer_type = gimple_code (ctx->stmt);
  return ((outer_type == GIMPLE_OMP_TARGET)
	  && (gimple_omp_target_kind (ctx->stmt)
	      == GF_OMP_TARGET_KIND_OACC_KERNELS));
}

/* Return whether CTX represents an OpenACC 'kernels' decomposed part.  */

static bool
is_oacc_kernels_decomposed_part (omp_context *ctx)
{
  enum gimple_code outer_type = gimple_code (ctx->stmt);
  return ((outer_type == GIMPLE_OMP_TARGET)
	  && ((gimple_omp_target_kind (ctx->stmt)
	       == GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED)
	      || (gimple_omp_target_kind (ctx->stmt)
		  == GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE)
	      || (gimple_omp_target_kind (ctx->stmt)
		  == GF_OMP_TARGET_KIND_OACC_DATA_KERNELS)));
}

/* Return true if STMT corresponds to an OpenMP target region.  */
static bool
is_omp_target (gimple *stmt)
{
  if (gimple_code (stmt) == GIMPLE_OMP_TARGET)
    {
      int kind = gimple_omp_target_kind (stmt);
      return (kind == GF_OMP_TARGET_KIND_REGION
	      || kind == GF_OMP_TARGET_KIND_DATA
	      || kind == GF_OMP_TARGET_KIND_ENTER_DATA
	      || kind == GF_OMP_TARGET_KIND_EXIT_DATA);
    }
  return false;
}

/* If DECL is the artificial dummy VAR_DECL created for non-static
   data member privatization, return the underlying "this" parameter,
   otherwise return NULL.  */

tree
omp_member_access_dummy_var (tree decl)
{
  if (!VAR_P (decl)
      || !DECL_ARTIFICIAL (decl)
      || !DECL_IGNORED_P (decl)
      || !DECL_HAS_VALUE_EXPR_P (decl)
      || !lang_hooks.decls.omp_disregard_value_expr (decl, false))
    return NULL_TREE;

  tree v = DECL_VALUE_EXPR (decl);
  if (TREE_CODE (v) != COMPONENT_REF)
    return NULL_TREE;

  while (1)
    switch (TREE_CODE (v))
      {
      case COMPONENT_REF:
      case MEM_REF:
      case INDIRECT_REF:
      CASE_CONVERT:
      case POINTER_PLUS_EXPR:
	v = TREE_OPERAND (v, 0);
	continue;
      case PARM_DECL:
	if (DECL_CONTEXT (v) == current_function_decl
	    && DECL_ARTIFICIAL (v)
	    && TREE_CODE (TREE_TYPE (v)) == POINTER_TYPE)
	  return v;
	return NULL_TREE;
      default:
	return NULL_TREE;
      }
}

/* Helper for unshare_and_remap, called through walk_tree.  */

static tree
unshare_and_remap_1 (tree *tp, int *walk_subtrees, void *data)
{
  tree *pair = (tree *) data;
  if (*tp == pair[0])
    {
      *tp = unshare_expr (pair[1]);
      *walk_subtrees = 0;
    }
  else if (IS_TYPE_OR_DECL_P (*tp))
    *walk_subtrees = 0;
  return NULL_TREE;
}

/* Return unshare_expr (X) with all occurrences of FROM
   replaced with TO.  */

static tree
unshare_and_remap (tree x, tree from, tree to)
{
  tree pair[2] = { from, to };
  x = unshare_expr (x);
  walk_tree (&x, unshare_and_remap_1, pair, NULL);
  return x;
}

/* Convenience function for calling scan_omp_1_op on tree operands.  */

static inline tree
scan_omp_op (tree *tp, omp_context *ctx)
{
  struct walk_stmt_info wi;

  memset (&wi, 0, sizeof (wi));
  wi.info = ctx;
  wi.want_locations = true;

  return walk_tree (tp, scan_omp_1_op, &wi, NULL);
}

static void lower_omp (gimple_seq *, omp_context *);
static tree lookup_decl_in_outer_ctx (tree, omp_context *);
static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);

/* Return true if CTX is for an omp parallel.  */

static inline bool
is_parallel_ctx (omp_context *ctx)
{
  return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
}


/* Return true if CTX is for an omp task.  */

static inline bool
is_task_ctx (omp_context *ctx)
{
  return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
}


/* Return true if CTX is for an omp taskloop.  */

static inline bool
is_taskloop_ctx (omp_context *ctx)
{
  return gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
	 && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_TASKLOOP;
}


/* Return true if CTX is for a host omp teams.  */

static inline bool
is_host_teams_ctx (omp_context *ctx)
{
  return gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
	 && gimple_omp_teams_host (as_a <gomp_teams *> (ctx->stmt));
}

/* Return true if CTX is for an omp parallel or omp task or host omp teams
   (the last one is strictly not a task region in OpenMP speak, but we
   need to treat it similarly).  */

static inline bool
is_taskreg_ctx (omp_context *ctx)
{
  return is_parallel_ctx (ctx) || is_task_ctx (ctx) || is_host_teams_ctx (ctx);
}

/* Return true if EXPR is variable sized.  */

static inline bool
is_variable_sized (const_tree expr)
{
  return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
}

/* Lookup variables.  The "maybe" form
   allows for the variable form to not have been entered, otherwise we
   assert that the variable must have been entered.  */

static inline tree
lookup_decl (tree var, omp_context *ctx)
{
  tree *n = ctx->cb.decl_map->get (var);
  return *n;
}

static inline tree
maybe_lookup_decl (const_tree var, omp_context *ctx)
{
  tree *n = ctx->cb.decl_map->get (const_cast<tree> (var));
  return n ? *n : NULL_TREE;
}

static inline tree
lookup_field (tree var, omp_context *ctx)
{
  splay_tree_node n;
  n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
  return (tree) n->value;
}

static inline tree
lookup_sfield (splay_tree_key key, omp_context *ctx)
{
  splay_tree_node n;
  n = splay_tree_lookup (ctx->sfield_map
			 ? ctx->sfield_map : ctx->field_map, key);
  return (tree) n->value;
}

static inline tree
lookup_sfield (tree var, omp_context *ctx)
{
  return lookup_sfield ((splay_tree_key) var, ctx);
}

static inline tree
maybe_lookup_field (splay_tree_key key, omp_context *ctx)
{
  splay_tree_node n;
  n = splay_tree_lookup (ctx->field_map, key);
  return n ? (tree) n->value : NULL_TREE;
}

static inline tree
maybe_lookup_field (tree var, omp_context *ctx)
{
  return maybe_lookup_field ((splay_tree_key) var, ctx);
}

/* Return true if DECL should be copied by pointer.  SHARED_CTX is
   the parallel context if DECL is to be shared.  */

static bool
use_pointer_for_field (tree decl, omp_context *shared_ctx)
{
  if (AGGREGATE_TYPE_P (TREE_TYPE (decl))
      || TYPE_ATOMIC (TREE_TYPE (decl)))
    return true;

  /* We can only use copy-in/copy-out semantics for shared variables
     when we know the value is not accessible from an outer scope.  */
  if (shared_ctx)
    {
      gcc_assert (!is_gimple_omp_oacc (shared_ctx->stmt));

      /* ??? Trivially accessible from anywhere.  But why would we even
	 be passing an address in this case?  Should we simply assert
	 this to be false, or should we have a cleanup pass that removes
	 these from the list of mappings?  */
      if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, shared_ctx)))
	return true;

      /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
	 without analyzing the expression whether or not its location
	 is accessible to anyone else.  In the case of nested parallel
	 regions it certainly may be.  */
      if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
	return true;

      /* Do not use copy-in/copy-out for variables that have their
	 address taken.  */
      if (is_global_var (decl))
	{
	  /* For file scope vars, track whether we've seen them as
	     non-addressable initially and in that case, keep the same
	     answer for the duration of the pass, even when they are made
	     addressable later on e.g. through reduction expansion.  Global
	     variables which weren't addressable before the pass will not
	     have their privatized copies address taken.  See PR91216.  */
	  if (!TREE_ADDRESSABLE (decl))
	    {
	      if (!global_nonaddressable_vars)
		global_nonaddressable_vars = BITMAP_ALLOC (NULL);
	      bitmap_set_bit (global_nonaddressable_vars, DECL_UID (decl));
	    }
	  else if (!global_nonaddressable_vars
		   || !bitmap_bit_p (global_nonaddressable_vars,
				     DECL_UID (decl)))
	    return true;
	}
      else if (TREE_ADDRESSABLE (decl))
	return true;

      /* lower_send_shared_vars only uses copy-in, but not copy-out
	 for these.  */
      if (TREE_READONLY (decl)
	  || ((TREE_CODE (decl) == RESULT_DECL
	       || TREE_CODE (decl) == PARM_DECL)
	      && DECL_BY_REFERENCE (decl)))
	return false;

      /* Disallow copy-in/out in nested parallel if
	 decl is shared in outer parallel, otherwise
	 each thread could store the shared variable
	 in its own copy-in location, making the
	 variable no longer really shared.  */
      if (shared_ctx->is_nested)
	{
	  omp_context *up;

	  for (up = shared_ctx->outer; up; up = up->outer)
	    if ((is_taskreg_ctx (up)
		 || (gimple_code (up->stmt) == GIMPLE_OMP_TARGET
		     && is_gimple_omp_offloaded (up->stmt)))
		&& maybe_lookup_decl (decl, up))
	      break;

	  if (up)
	    {
	      tree c;

	      if (gimple_code (up->stmt) == GIMPLE_OMP_TARGET)
		{
		  for (c = gimple_omp_target_clauses (up->stmt);
		       c; c = OMP_CLAUSE_CHAIN (c))
		    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
			&& OMP_CLAUSE_DECL (c) == decl)
		      break;
		}
	      else
		for (c = gimple_omp_taskreg_clauses (up->stmt);
		     c; c = OMP_CLAUSE_CHAIN (c))
		  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
		      && OMP_CLAUSE_DECL (c) == decl)
		    break;

	      if (c)
		goto maybe_mark_addressable_and_ret;
	    }
	}

      /* For tasks avoid using copy-in/out.  As tasks can be
	 deferred or executed in different thread, when GOMP_task
	 returns, the task hasn't necessarily terminated.  */
      if (is_task_ctx (shared_ctx))
	{
	  tree outer;
	maybe_mark_addressable_and_ret:
	  outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
	  if (is_gimple_reg (outer) && !omp_member_access_dummy_var (outer))
	    {
	      /* Taking address of OUTER in lower_send_shared_vars
		 might need regimplification of everything that uses the
		 variable.  */
	      if (!task_shared_vars)
		task_shared_vars = BITMAP_ALLOC (NULL);
	      bitmap_set_bit (task_shared_vars, DECL_UID (outer));
	      TREE_ADDRESSABLE (outer) = 1;
	    }
	  return true;
	}
    }

  return false;
}

/* Construct a new automatic decl similar to VAR.  */

static tree
omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
{
  tree copy = copy_var_decl (var, name, type);

  DECL_CONTEXT (copy) = current_function_decl;

  if (ctx)
    {
      DECL_CHAIN (copy) = ctx->block_vars;
      ctx->block_vars = copy;
    }
  else
    record_vars (copy);

  /* If VAR is listed in task_shared_vars, it means it wasn't
     originally addressable and is just because task needs to take
     it's address.  But we don't need to take address of privatizations
     from that var.  */
  if (TREE_ADDRESSABLE (var)
      && ((task_shared_vars
	   && bitmap_bit_p (task_shared_vars, DECL_UID (var)))
	  || (global_nonaddressable_vars
	      && bitmap_bit_p (global_nonaddressable_vars, DECL_UID (var)))))
    TREE_ADDRESSABLE (copy) = 0;

  return copy;
}

static tree
omp_copy_decl_1 (tree var, omp_context *ctx)
{
  return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
}

/* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
   as appropriate.  */
/* See also 'gcc/omp-oacc-neuter-broadcast.cc:oacc_build_component_ref'.  */

static tree
omp_build_component_ref (tree obj, tree field)
{
  tree ret = build3 (COMPONENT_REF, TREE_TYPE (field), obj, field, NULL);
  if (TREE_THIS_VOLATILE (field))
    TREE_THIS_VOLATILE (ret) |= 1;
  if (TREE_READONLY (field))
    TREE_READONLY (ret) |= 1;
  return ret;
}

/* Build tree nodes to access the field for VAR on the receiver side.  */

static tree
build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
{
  tree x, field = lookup_field (var, ctx);

  /* If the receiver record type was remapped in the child function,
     remap the field into the new record type.  */
  x = maybe_lookup_field (field, ctx);
  if (x != NULL)
    field = x;

  x = build_simple_mem_ref (ctx->receiver_decl);
  TREE_THIS_NOTRAP (x) = 1;
  x = omp_build_component_ref (x, field);
  if (by_ref)
    {
      x = build_simple_mem_ref (x);
      TREE_THIS_NOTRAP (x) = 1;
    }

  return x;
}

/* Build tree nodes to access VAR in the scope outer to CTX.  In the case
   of a parallel, this is a component reference; for workshare constructs
   this is some variable.  */

static tree
build_outer_var_ref (tree var, omp_context *ctx,
		     enum omp_clause_code code = OMP_CLAUSE_ERROR)
{
  tree x;
  omp_context *outer = ctx->outer;
  for (; outer; outer = outer->outer)
    {
      if (gimple_code (outer->stmt) == GIMPLE_OMP_TASKGROUP)
	continue;
      if (gimple_code (outer->stmt) == GIMPLE_OMP_SCOPE
	  && !maybe_lookup_decl (var, outer))
	continue;
      break;
    }

  if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
    x = var;
  else if (is_variable_sized (var))
    {
      x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
      x = build_outer_var_ref (x, ctx, code);
      x = build_simple_mem_ref (x);
    }
  else if (is_taskreg_ctx (ctx))
    {
      bool by_ref = use_pointer_for_field (var, NULL);
      x = build_receiver_ref (var, by_ref, ctx);
    }
  else if ((gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
	    && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
	   || ctx->loop_p
	   || (code == OMP_CLAUSE_PRIVATE
	       && (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
		   || gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS
		   || gimple_code (ctx->stmt) == GIMPLE_OMP_SINGLE)))
    {
      /* #pragma omp simd isn't a worksharing construct, and can reference
	 even private vars in its linear etc. clauses.
	 Similarly for OMP_CLAUSE_PRIVATE with outer ref, that can refer
	 to private vars in all worksharing constructs.  */
      x = NULL_TREE;
      if (outer && is_taskreg_ctx (outer))
	x = lookup_decl (var, outer);
      else if (outer)
	x = maybe_lookup_decl_in_outer_ctx (var, ctx);
      if (x == NULL_TREE)
	x = var;
    }
  else if (code == OMP_CLAUSE_LASTPRIVATE && is_taskloop_ctx (ctx))
    {
      gcc_assert (outer);
      splay_tree_node n
	= splay_tree_lookup (outer->field_map,
			     (splay_tree_key) &DECL_UID (var));
      if (n == NULL)
	{
	  if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, outer)))
	    x = var;
	  else
	    x = lookup_decl (var, outer);
	}
      else
	{
	  tree field = (tree) n->value;
	  /* If the receiver record type was remapped in the child function,
	     remap the field into the new record type.  */
	  x = maybe_lookup_field (field, outer);
	  if (x != NULL)
	    field = x;

	  x = build_simple_mem_ref (outer->receiver_decl);
	  x = omp_build_component_ref (x, field);
	  if (use_pointer_for_field (var, outer))
	    x = build_simple_mem_ref (x);
	}
    }
  else if (outer)
    x = lookup_decl (var, outer);
  else if (omp_privatize_by_reference (var))
    /* This can happen with orphaned constructs.  If var is reference, it is
       possible it is shared and as such valid.  */
    x = var;
  else if (omp_member_access_dummy_var (var))
    x = var;
  else
    gcc_unreachable ();

  if (x == var)
    {
      tree t = omp_member_access_dummy_var (var);
      if (t)
	{
	  x = DECL_VALUE_EXPR (var);
	  tree o = maybe_lookup_decl_in_outer_ctx (t, ctx);
	  if (o != t)
	    x = unshare_and_remap (x, t, o);
	  else
	    x = unshare_expr (x);
	}
    }

  if (omp_privatize_by_reference (var))
    x = build_simple_mem_ref (x);

  return x;
}

/* Build tree nodes to access the field for VAR on the sender side.  */

static tree
build_sender_ref (splay_tree_key key, omp_context *ctx)
{
  tree field = lookup_sfield (key, ctx);
  return omp_build_component_ref (ctx->sender_decl, field);
}

static tree
build_sender_ref (tree var, omp_context *ctx)
{
  return build_sender_ref ((splay_tree_key) var, ctx);
}

/* Add a new field for VAR inside the structure CTX->SENDER_DECL.  If
   BASE_POINTERS_RESTRICT, declare the field with restrict.  */

static void
install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
{
  tree field, type, sfield = NULL_TREE;
  splay_tree_key key = (splay_tree_key) var;

  if ((mask & 16) != 0)
    {
      key = (splay_tree_key) &DECL_NAME (var);
      gcc_checking_assert (key != (splay_tree_key) var);
    }
  if ((mask & 8) != 0)
    {
      key = (splay_tree_key) &DECL_UID (var);
      gcc_checking_assert (key != (splay_tree_key) var);
    }
  gcc_assert ((mask & 1) == 0
	      || !splay_tree_lookup (ctx->field_map, key));
  gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
	      || !splay_tree_lookup (ctx->sfield_map, key));
  gcc_assert ((mask & 3) == 3
	      || !is_gimple_omp_oacc (ctx->stmt));

  type = TREE_TYPE (var);
  if ((mask & 16) != 0)
    type = lang_hooks.decls.omp_array_data (var, true);

  /* Prevent redeclaring the var in the split-off function with a restrict
     pointer type.  Note that we only clear type itself, restrict qualifiers in
     the pointed-to type will be ignored by points-to analysis.  */
  if (POINTER_TYPE_P (type)
      && TYPE_RESTRICT (type))
    type = build_qualified_type (type, TYPE_QUALS (type) & ~TYPE_QUAL_RESTRICT);

  if (mask & 4)
    {
      gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
      type = build_pointer_type (build_pointer_type (type));
    }
  else if (by_ref)
    type = build_pointer_type (type);
  else if ((mask & (32 | 3)) == 1
	   && omp_privatize_by_reference (var))
    type = TREE_TYPE (type);

  field = build_decl (DECL_SOURCE_LOCATION (var),
		      FIELD_DECL, DECL_NAME (var), type);

  /* Remember what variable this field was created for.  This does have a
     side effect of making dwarf2out ignore this member, so for helpful
     debugging we clear it later in delete_omp_context.  */
  DECL_ABSTRACT_ORIGIN (field) = var;
  if ((mask & 16) == 0 && type == TREE_TYPE (var))
    {
      SET_DECL_ALIGN (field, DECL_ALIGN (var));
      DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
      TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
    }
  else
    SET_DECL_ALIGN (field, TYPE_ALIGN (type));

  if ((mask & 3) == 3)
    {
      insert_field_into_struct (ctx->record_type, field);
      if (ctx->srecord_type)
	{
	  sfield = build_decl (DECL_SOURCE_LOCATION (var),
			       FIELD_DECL, DECL_NAME (var), type);
	  DECL_ABSTRACT_ORIGIN (sfield) = var;
	  SET_DECL_ALIGN (sfield, DECL_ALIGN (field));
	  DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
	  TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
	  insert_field_into_struct (ctx->srecord_type, sfield);
	}
    }
  else
    {
      if (ctx->srecord_type == NULL_TREE)
	{
	  tree t;

	  ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
	  ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
	  for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
	    {
	      sfield = build_decl (DECL_SOURCE_LOCATION (t),
				   FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
	      DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
	      insert_field_into_struct (ctx->srecord_type, sfield);
	      splay_tree_insert (ctx->sfield_map,
				 (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
				 (splay_tree_value) sfield);
	    }
	}
      sfield = field;
      insert_field_into_struct ((mask & 1) ? ctx->record_type
				: ctx->srecord_type, field);
    }

  if (mask & 1)
    splay_tree_insert (ctx->field_map, key, (splay_tree_value) field);
  if ((mask & 2) && ctx->sfield_map)
    splay_tree_insert (ctx->sfield_map, key, (splay_tree_value) sfield);
}

static tree
install_var_local (tree var, omp_context *ctx)
{
  tree new_var = omp_copy_decl_1 (var, ctx);
  insert_decl_map (&ctx->cb, var, new_var);
  return new_var;
}

/* Adjust the replacement for DECL in CTX for the new context.  This means
   copying the DECL_VALUE_EXPR, and fixing up the type.  */

static void
fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
{
  tree new_decl, size;

  new_decl = lookup_decl (decl, ctx);

  TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);

  if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
      && DECL_HAS_VALUE_EXPR_P (decl))
    {
      tree ve = DECL_VALUE_EXPR (decl);
      walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
      SET_DECL_VALUE_EXPR (new_decl, ve);
      DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
    }

  if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
    {
      size = remap_decl (DECL_SIZE (decl), &ctx->cb);
      if (size == error_mark_node)
	size = TYPE_SIZE (TREE_TYPE (new_decl));
      DECL_SIZE (new_decl) = size;

      size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
      if (size == error_mark_node)
	size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
      DECL_SIZE_UNIT (new_decl) = size;
    }
}

/* The callback for remap_decl.  Search all containing contexts for a
   mapping of the variable; this avoids having to duplicate the splay
   tree ahead of time.  We know a mapping doesn't already exist in the
   given context.  Create new mappings to implement default semantics.  */

static tree
omp_copy_decl (tree var, copy_body_data *cb)
{
  omp_context *ctx = (omp_context *) cb;
  tree new_var;

  if (TREE_CODE (var) == LABEL_DECL)
    {
      if (FORCED_LABEL (var) || DECL_NONLOCAL (var))
	return var;
      new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
      DECL_CONTEXT (new_var) = current_function_decl;
      insert_decl_map (&ctx->cb, var, new_var);
      return new_var;
    }

  while (!is_taskreg_ctx (ctx))
    {
      ctx = ctx->outer;
      if (ctx == NULL)
	return var;
      new_var = maybe_lookup_decl (var, ctx);
      if (new_var)
	return new_var;
    }

  if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
    return var;

  return error_mark_node;
}

/* Create a new context, with OUTER_CTX being the surrounding context.  */

static omp_context *
new_omp_context (gimple *stmt, omp_context *outer_ctx)
{
  omp_context *ctx = XCNEW (omp_context);

  splay_tree_insert (all_contexts, (splay_tree_key) stmt,
		     (splay_tree_value) ctx);
  ctx->stmt = stmt;

  if (outer_ctx)
    {
      ctx->outer = outer_ctx;
      ctx->cb = outer_ctx->cb;
      ctx->cb.block = NULL;
      ctx->depth = outer_ctx->depth + 1;
    }
  else
    {
      ctx->cb.src_fn = current_function_decl;
      ctx->cb.dst_fn = current_function_decl;
      ctx->cb.src_node = cgraph_node::get (current_function_decl);
      gcc_checking_assert (ctx->cb.src_node);
      ctx->cb.dst_node = ctx->cb.src_node;
      ctx->cb.src_cfun = cfun;
      ctx->cb.copy_decl = omp_copy_decl;
      ctx->cb.eh_lp_nr = 0;
      ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
      ctx->cb.adjust_array_error_bounds = true;
      ctx->cb.dont_remap_vla_if_no_change = true;
      ctx->depth = 1;
    }

  ctx->cb.decl_map = new hash_map<tree, tree>;

  return ctx;
}

static gimple_seq maybe_catch_exception (gimple_seq);

/* Finalize task copyfn.  */

static void
finalize_task_copyfn (gomp_task *task_stmt)
{
  struct function *child_cfun;
  tree child_fn;
  gimple_seq seq = NULL, new_seq;
  gbind *bind;

  child_fn = gimple_omp_task_copy_fn (task_stmt);
  if (child_fn == NULL_TREE)
    return;

  child_cfun = DECL_STRUCT_FUNCTION (child_fn);
  DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;

  push_cfun (child_cfun);
  bind = gimplify_body (child_fn, false);
  gimple_seq_add_stmt (&seq, bind);
  new_seq = maybe_catch_exception (seq);
  if (new_seq != seq)
    {
      bind = gimple_build_bind (NULL, new_seq, NULL);
      seq = NULL;
      gimple_seq_add_stmt (&seq, bind);
    }
  gimple_set_body (child_fn, seq);
  pop_cfun ();

  /* Inform the callgraph about the new function.  */
  cgraph_node *node = cgraph_node::get_create (child_fn);
  node->parallelized_function = 1;
  cgraph_node::add_new_function (child_fn, false);
}

/* Destroy a omp_context data structures.  Called through the splay tree
   value delete callback.  */

static void
delete_omp_context (splay_tree_value value)
{
  omp_context *ctx = (omp_context *) value;

  delete ctx->cb.decl_map;

  if (ctx->field_map)
    splay_tree_delete (ctx->field_map);
  if (ctx->sfield_map)
    splay_tree_delete (ctx->sfield_map);

  /* We hijacked DECL_ABSTRACT_ORIGIN earlier.  We need to clear it before
     it produces corrupt debug information.  */
  if (ctx->record_type)
    {
      tree t;
      for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
	DECL_ABSTRACT_ORIGIN (t) = NULL;
    }
  if (ctx->srecord_type)
    {
      tree t;
      for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = DECL_CHAIN (t))
	DECL_ABSTRACT_ORIGIN (t) = NULL;
    }

  if (is_task_ctx (ctx))
    finalize_task_copyfn (as_a <gomp_task *> (ctx->stmt));

  if (ctx->task_reduction_map)
    {
      ctx->task_reductions.release ();
      delete ctx->task_reduction_map;
    }

  delete ctx->lastprivate_conditional_map;
  delete ctx->allocate_map;

  XDELETE (ctx);
}

/* Fix up RECEIVER_DECL with a type that has been remapped to the child
   context.  */

static void
fixup_child_record_type (omp_context *ctx)
{
  tree f, type = ctx->record_type;

  if (!ctx->receiver_decl)
    return;
  /* ??? It isn't sufficient to just call remap_type here, because
     variably_modified_type_p doesn't work the way we expect for
     record types.  Testing each field for whether it needs remapping
     and creating a new record by hand works, however.  */
  for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
    if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
      break;
  if (f)
    {
      tree name, new_fields = NULL;

      type = lang_hooks.types.make_type (RECORD_TYPE);
      name = DECL_NAME (TYPE_NAME (ctx->record_type));
      name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
			 TYPE_DECL, name, type);
      TYPE_NAME (type) = name;

      for (f = TYPE_FIELDS (ctx->record_type); f ; f = DECL_CHAIN (f))
	{
	  tree new_f = copy_node (f);
	  DECL_CONTEXT (new_f) = type;
	  TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
	  DECL_CHAIN (new_f) = new_fields;
	  walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
	  walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
		     &ctx->cb, NULL);
	  walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
		     &ctx->cb, NULL);
	  new_fields = new_f;

	  /* Arrange to be able to look up the receiver field
	     given the sender field.  */
	  splay_tree_insert (ctx->field_map, (splay_tree_key) f,
			     (splay_tree_value) new_f);
	}
      TYPE_FIELDS (type) = nreverse (new_fields);
      layout_type (type);
    }

  /* In a target region we never modify any of the pointers in *.omp_data_i,
     so attempt to help the optimizers.  */
  if (is_gimple_omp_offloaded (ctx->stmt))
    type = build_qualified_type (type, TYPE_QUAL_CONST);

  TREE_TYPE (ctx->receiver_decl)
    = build_qualified_type (build_reference_type (type), TYPE_QUAL_RESTRICT);
}

/* Instantiate decls as necessary in CTX to satisfy the data sharing
   specified by CLAUSES.  */

static void
scan_sharing_clauses (tree clauses, omp_context *ctx)
{
  tree c, decl;
  bool scan_array_reductions = false;

  for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE
	&& (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
	    /* omp_default_mem_alloc is 1 */
	    || !integer_onep (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
	    || OMP_CLAUSE_ALLOCATE_ALIGN (c) != NULL_TREE))
      {
	if (ctx->allocate_map == NULL)
	  ctx->allocate_map = new hash_map<tree, tree>;
	tree val = integer_zero_node;
	if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
	  val = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
	if (OMP_CLAUSE_ALLOCATE_ALIGN (c))
	  val = build_tree_list (val, OMP_CLAUSE_ALLOCATE_ALIGN (c));
	ctx->allocate_map->put (OMP_CLAUSE_DECL (c), val);
      }

  for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    {
      bool by_ref;

      switch (OMP_CLAUSE_CODE (c))
	{
	case OMP_CLAUSE_PRIVATE:
	  decl = OMP_CLAUSE_DECL (c);
	  if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
	    goto do_private;
	  else if (!is_variable_sized (decl))
	    install_var_local (decl, ctx);
	  break;

	case OMP_CLAUSE_SHARED:
	  decl = OMP_CLAUSE_DECL (c);
	  if (ctx->allocate_map && ctx->allocate_map->get (decl))
	    ctx->allocate_map->remove (decl);
	  /* Ignore shared directives in teams construct inside of
	     target construct.  */
	  if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
	      && !is_host_teams_ctx (ctx))
	    {
	      /* Global variables don't need to be copied,
		 the receiver side will use them directly.  */
	      tree odecl = maybe_lookup_decl_in_outer_ctx (decl, ctx);
	      if (is_global_var (odecl))
		break;
	      insert_decl_map (&ctx->cb, decl, odecl);
	      break;
	    }
	  gcc_assert (is_taskreg_ctx (ctx));
	  gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
		      || !is_variable_sized (decl));
	  /* Global variables don't need to be copied,
	     the receiver side will use them directly.  */
	  if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
	    break;
	  if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
	    {
	      use_pointer_for_field (decl, ctx);
	      break;
	    }
	  by_ref = use_pointer_for_field (decl, NULL);
	  if ((! TREE_READONLY (decl) && !OMP_CLAUSE_SHARED_READONLY (c))
	      || TREE_ADDRESSABLE (decl)
	      || by_ref
	      || omp_privatize_by_reference (decl))
	    {
	      by_ref = use_pointer_for_field (decl, ctx);
	      install_var_field (decl, by_ref, 3, ctx);
	      install_var_local (decl, ctx);
	      break;
	    }
	  /* We don't need to copy const scalar vars back.  */
	  OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
	  goto do_private;

	case OMP_CLAUSE_REDUCTION:
	  /* Collect 'reduction' clauses on OpenACC compute construct.  */
	  if (is_gimple_omp_oacc (ctx->stmt)
	      && is_gimple_omp_offloaded (ctx->stmt))
	    {
	      /* No 'reduction' clauses on OpenACC 'kernels'.  */
	      gcc_checking_assert (!is_oacc_kernels (ctx));
	      /* Likewise, on OpenACC 'kernels' decomposed parts.  */
	      gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));

	      ctx->local_reduction_clauses
		= tree_cons (NULL, c, ctx->local_reduction_clauses);
	    }
	  /* FALLTHRU */

	case OMP_CLAUSE_IN_REDUCTION:
	  decl = OMP_CLAUSE_DECL (c);
	  if (ctx->allocate_map
	      && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
		   && (OMP_CLAUSE_REDUCTION_INSCAN (c)
		       || OMP_CLAUSE_REDUCTION_TASK (c)))
		  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
		  || is_task_ctx (ctx)))
	    {
	      /* For now.  */
	      if (ctx->allocate_map->get (decl))
		ctx->allocate_map->remove (decl);
	    }
	  if (TREE_CODE (decl) == MEM_REF)
	    {
	      tree t = TREE_OPERAND (decl, 0);
	      if (TREE_CODE (t) == POINTER_PLUS_EXPR)
		t = TREE_OPERAND (t, 0);
	      if (TREE_CODE (t) == INDIRECT_REF
		  || TREE_CODE (t) == ADDR_EXPR)
		t = TREE_OPERAND (t, 0);
	      if (is_omp_target (ctx->stmt))
		{
		  if (is_variable_sized (t))
		    {
		      gcc_assert (DECL_HAS_VALUE_EXPR_P (t));
		      t = DECL_VALUE_EXPR (t);
		      gcc_assert (TREE_CODE (t) == INDIRECT_REF);
		      t = TREE_OPERAND (t, 0);
		      gcc_assert (DECL_P (t));
		    }
		  tree at = t;
		  if (ctx->outer)
		    scan_omp_op (&at, ctx->outer);
		  tree nt = omp_copy_decl_1 (at, ctx->outer);
		  splay_tree_insert (ctx->field_map,
				     (splay_tree_key) &DECL_CONTEXT (t),
				     (splay_tree_value) nt);
		  if (at != t)
		    splay_tree_insert (ctx->field_map,
				       (splay_tree_key) &DECL_CONTEXT (at),
				       (splay_tree_value) nt);
		  break;
		}
	      install_var_local (t, ctx);
	      if (is_taskreg_ctx (ctx)
		  && (!is_global_var (maybe_lookup_decl_in_outer_ctx (t, ctx))
		      || (is_task_ctx (ctx)
			  && (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
			      || (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE
				  && (TREE_CODE (TREE_TYPE (TREE_TYPE (t)))
				      == POINTER_TYPE)))))
		  && !is_variable_sized (t)
		  && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
		      || (!OMP_CLAUSE_REDUCTION_TASK (c)
			  && !is_task_ctx (ctx))))
		{
		  by_ref = use_pointer_for_field (t, NULL);
		  if (is_task_ctx (ctx)
		      && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE
		      && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) == POINTER_TYPE)
		    {
		      install_var_field (t, false, 1, ctx);
		      install_var_field (t, by_ref, 2, ctx);
		    }
		  else
		    install_var_field (t, by_ref, 3, ctx);
		}
	      break;
	    }
	  if (is_omp_target (ctx->stmt))
	    {
	      tree at = decl;
	      if (ctx->outer)
		scan_omp_op (&at, ctx->outer);
	      tree nt = omp_copy_decl_1 (at, ctx->outer);
	      splay_tree_insert (ctx->field_map,
				 (splay_tree_key) &DECL_CONTEXT (decl),
				 (splay_tree_value) nt);
	      if (at != decl)
		splay_tree_insert (ctx->field_map,
				   (splay_tree_key) &DECL_CONTEXT (at),
				   (splay_tree_value) nt);
	      break;
	    }
	  if (is_task_ctx (ctx)
	      || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
		  && OMP_CLAUSE_REDUCTION_TASK (c)
		  && is_parallel_ctx (ctx)))
	    {
	      /* Global variables don't need to be copied,
		 the receiver side will use them directly.  */
	      if (!is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
		{
		  by_ref = use_pointer_for_field (decl, ctx);
		  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
		    install_var_field (decl, by_ref, 3, ctx);
		}
	      install_var_local (decl, ctx);
	      break;
	    }
	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
	      && OMP_CLAUSE_REDUCTION_TASK (c))
	    {
	      install_var_local (decl, ctx);
	      break;
	    }
	  goto do_private;

	case OMP_CLAUSE_LASTPRIVATE:
	  /* Let the corresponding firstprivate clause create
	     the variable.  */
	  if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
	    break;
	  /* FALLTHRU */

	case OMP_CLAUSE_FIRSTPRIVATE:
	case OMP_CLAUSE_LINEAR:
	  decl = OMP_CLAUSE_DECL (c);
	do_private:
	  if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
	       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
	      && is_gimple_omp_offloaded (ctx->stmt))
	    {
	      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
		{
		  by_ref = !omp_privatize_by_reference (decl);
		  install_var_field (decl, by_ref, 3, ctx);
		}
	      else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
		install_var_field (decl, true, 3, ctx);
	      else
		install_var_field (decl, false, 3, ctx);
	    }
	  if (is_variable_sized (decl))
	    {
	      if (is_task_ctx (ctx))
		{
		  if (ctx->allocate_map
		      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
		    {
		      /* For now.  */
		      if (ctx->allocate_map->get (decl))
			ctx->allocate_map->remove (decl);
		    }
		  install_var_field (decl, false, 1, ctx);
		}
	      break;
	    }
	  else if (is_taskreg_ctx (ctx))
	    {
	      bool global
		= is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
	      by_ref = use_pointer_for_field (decl, NULL);

	      if (is_task_ctx (ctx)
		  && (global || by_ref || omp_privatize_by_reference (decl)))
		{
		  if (ctx->allocate_map
		      && ctx->allocate_map->get (decl))
		    install_var_field (decl, by_ref, 32 | 1, ctx);
		  else
		    install_var_field (decl, false, 1, ctx);
		  if (!global)
		    install_var_field (decl, by_ref, 2, ctx);
		}
	      else if (!global)
		install_var_field (decl, by_ref, 3, ctx);
	    }
	  install_var_local (decl, ctx);
	  break;

	case OMP_CLAUSE_USE_DEVICE_PTR:
	case OMP_CLAUSE_USE_DEVICE_ADDR:
	  decl = OMP_CLAUSE_DECL (c);

	  /* Fortran array descriptors.  */
	  if (lang_hooks.decls.omp_array_data (decl, true))
	    install_var_field (decl, false, 19, ctx);
	  else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
		    && !omp_privatize_by_reference (decl)
		    && !omp_is_allocatable_or_ptr (decl))
		   || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
	    install_var_field (decl, true, 11, ctx);
	  else
	    install_var_field (decl, false, 11, ctx);
	  if (DECL_SIZE (decl)
	      && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
	    {
	      tree decl2 = DECL_VALUE_EXPR (decl);
	      gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
	      decl2 = TREE_OPERAND (decl2, 0);
	      gcc_assert (DECL_P (decl2));
	      install_var_local (decl2, ctx);
	    }
	  install_var_local (decl, ctx);
	  break;

	case OMP_CLAUSE_IS_DEVICE_PTR:
	  decl = OMP_CLAUSE_DECL (c);
	  goto do_private;

	case OMP_CLAUSE__LOOPTEMP_:
	case OMP_CLAUSE__REDUCTEMP_:
	  gcc_assert (is_taskreg_ctx (ctx));
	  decl = OMP_CLAUSE_DECL (c);
	  install_var_field (decl, false, 3, ctx);
	  install_var_local (decl, ctx);
	  break;

	case OMP_CLAUSE_COPYPRIVATE:
	case OMP_CLAUSE_COPYIN:
	  decl = OMP_CLAUSE_DECL (c);
	  by_ref = use_pointer_for_field (decl, NULL);
	  install_var_field (decl, by_ref, 3, ctx);
	  break;

	case OMP_CLAUSE_FINAL:
	case OMP_CLAUSE_IF:
	case OMP_CLAUSE_NUM_THREADS:
	case OMP_CLAUSE_NUM_TEAMS:
	case OMP_CLAUSE_THREAD_LIMIT:
	case OMP_CLAUSE_DEVICE:
	case OMP_CLAUSE_SCHEDULE:
	case OMP_CLAUSE_DIST_SCHEDULE:
	case OMP_CLAUSE_DEPEND:
	case OMP_CLAUSE_PRIORITY:
	case OMP_CLAUSE_GRAINSIZE:
	case OMP_CLAUSE_NUM_TASKS:
	case OMP_CLAUSE_NUM_GANGS:
	case OMP_CLAUSE_NUM_WORKERS:
	case OMP_CLAUSE_VECTOR_LENGTH:
	case OMP_CLAUSE_DETACH:
	case OMP_CLAUSE_FILTER:
	  if (ctx->outer)
	    scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
	  break;

	case OMP_CLAUSE_TO:
	case OMP_CLAUSE_FROM:
	case OMP_CLAUSE_MAP:
	  if (ctx->outer)
	    scan_omp_op (&OMP_CLAUSE_SIZE (c), ctx->outer);
	  decl = OMP_CLAUSE_DECL (c);
	  /* Global variables with "omp declare target" attribute
	     don't need to be copied, the receiver side will use them
	     directly.  However, global variables with "omp declare target link"
	     attribute need to be copied.  Or when ALWAYS modifier is used.  */
	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
	      && DECL_P (decl)
	      && ((OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
		   && (OMP_CLAUSE_MAP_KIND (c)
		       != GOMP_MAP_FIRSTPRIVATE_REFERENCE)
		   && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
		   && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH)
		  || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
	      && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_TO
	      && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_FROM
	      && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_TOFROM
	      && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
	      && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
	      && varpool_node::get_create (decl)->offloadable
	      && !lookup_attribute ("omp declare target link",
				    DECL_ATTRIBUTES (decl)))
	    break;
	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
	      && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)
	    {
	      /* Ignore GOMP_MAP_POINTER kind for arrays in regions that are
		 not offloaded; there is nothing to map for those.  */
	      if (!is_gimple_omp_offloaded (ctx->stmt)
		  && !POINTER_TYPE_P (TREE_TYPE (decl))
		  && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
		break;
	    }
	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
	      && DECL_P (decl)
	      && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
		  || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
	      && is_omp_target (ctx->stmt))
	    {
	      /* If this is an offloaded region, an attach operation should
		 only exist when the pointer variable is mapped in a prior
		 clause.  */
	      if (is_gimple_omp_offloaded (ctx->stmt))
		gcc_assert
		  (maybe_lookup_decl (decl, ctx)
		   || (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
		       && lookup_attribute ("omp declare target",
					    DECL_ATTRIBUTES (decl))));

	      /* By itself, attach/detach is generated as part of pointer
		 variable mapping and should not create new variables in the
		 offloaded region, however sender refs for it must be created
		 for its address to be passed to the runtime.  */
	      tree field
		= build_decl (OMP_CLAUSE_LOCATION (c),
			      FIELD_DECL, NULL_TREE, ptr_type_node);
	      SET_DECL_ALIGN (field, TYPE_ALIGN (ptr_type_node));
	      insert_field_into_struct (ctx->record_type, field);
	      /* To not clash with a map of the pointer variable itself,
		 attach/detach maps have their field looked up by the *clause*
		 tree expression, not the decl.  */
	      gcc_assert (!splay_tree_lookup (ctx->field_map,
					      (splay_tree_key) c));
	      splay_tree_insert (ctx->field_map, (splay_tree_key) c,
				 (splay_tree_value) field);
	      break;
	    }
	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
	      && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
		  || (OMP_CLAUSE_MAP_KIND (c)
		      == GOMP_MAP_FIRSTPRIVATE_REFERENCE)))
	    {
	      if (TREE_CODE (decl) == COMPONENT_REF
		  || (TREE_CODE (decl) == INDIRECT_REF
		      && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
		      && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
			  == REFERENCE_TYPE)))
		break;
	      if (DECL_SIZE (decl)
		  && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
		{
		  tree decl2 = DECL_VALUE_EXPR (decl);
		  gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
		  decl2 = TREE_OPERAND (decl2, 0);
		  gcc_assert (DECL_P (decl2));
		  install_var_local (decl2, ctx);
		}
	      install_var_local (decl, ctx);
	      break;
	    }
	  if (DECL_P (decl))
	    {
	      if (DECL_SIZE (decl)
		  && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
		{
		  tree decl2 = DECL_VALUE_EXPR (decl);
		  gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
		  decl2 = TREE_OPERAND (decl2, 0);
		  gcc_assert (DECL_P (decl2));
		  install_var_field (decl2, true, 3, ctx);
		  install_var_local (decl2, ctx);
		  install_var_local (decl, ctx);
		}
	      else
		{
		  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
		      && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
		      && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
		      && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
		    install_var_field (decl, true, 7, ctx);
		  else
		    install_var_field (decl, true, 3, ctx);
		  if (is_gimple_omp_offloaded (ctx->stmt)
		      && !(is_gimple_omp_oacc (ctx->stmt)
			   && OMP_CLAUSE_MAP_IN_REDUCTION (c)))
		    install_var_local (decl, ctx);
		}
	    }
	  else
	    {
	      tree base = get_base_address (decl);
	      tree nc = OMP_CLAUSE_CHAIN (c);
	      if (DECL_P (base)
		  && nc != NULL_TREE
		  && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
		  && OMP_CLAUSE_DECL (nc) == base
		  && OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
		  && integer_zerop (OMP_CLAUSE_SIZE (nc)))
		{
		  OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c) = 1;
		  OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (nc) = 1;
		}
	      else
		{
		  if (ctx->outer)
		    {
		      scan_omp_op (&OMP_CLAUSE_DECL (c), ctx->outer);
		      decl = OMP_CLAUSE_DECL (c);
		    }
		  gcc_assert (!splay_tree_lookup (ctx->field_map,
						  (splay_tree_key) decl));
		  tree field
		    = build_decl (OMP_CLAUSE_LOCATION (c),
				  FIELD_DECL, NULL_TREE, ptr_type_node);
		  SET_DECL_ALIGN (field, TYPE_ALIGN (ptr_type_node));
		  insert_field_into_struct (ctx->record_type, field);
		  splay_tree_insert (ctx->field_map, (splay_tree_key) decl,
				     (splay_tree_value) field);
		}
	    }
	  break;

	case OMP_CLAUSE_ORDER:
	  ctx->order_concurrent = true;
	  break;

	case OMP_CLAUSE_BIND:
	  ctx->loop_p = true;
	  break;

	case OMP_CLAUSE_NOWAIT:
	case OMP_CLAUSE_ORDERED:
	case OMP_CLAUSE_COLLAPSE:
	case OMP_CLAUSE_UNTIED:
	case OMP_CLAUSE_MERGEABLE:
	case OMP_CLAUSE_PROC_BIND:
	case OMP_CLAUSE_SAFELEN:
	case OMP_CLAUSE_SIMDLEN:
	case OMP_CLAUSE_THREADS:
	case OMP_CLAUSE_SIMD:
	case OMP_CLAUSE_NOGROUP:
	case OMP_CLAUSE_DEFAULTMAP:
	case OMP_CLAUSE_ASYNC:
	case OMP_CLAUSE_WAIT:
	case OMP_CLAUSE_GANG:
	case OMP_CLAUSE_WORKER:
	case OMP_CLAUSE_VECTOR:
	case OMP_CLAUSE_INDEPENDENT:
	case OMP_CLAUSE_AUTO:
	case OMP_CLAUSE_SEQ:
	case OMP_CLAUSE_TILE:
	case OMP_CLAUSE__SIMT_:
	case OMP_CLAUSE_DEFAULT:
	case OMP_CLAUSE_NONTEMPORAL:
	case OMP_CLAUSE_IF_PRESENT:
	case OMP_CLAUSE_FINALIZE:
	case OMP_CLAUSE_TASK_REDUCTION:
	case OMP_CLAUSE_ALLOCATE:
	  break;

	case OMP_CLAUSE_ALIGNED:
	  decl = OMP_CLAUSE_DECL (c);
	  if (is_global_var (decl)
	      && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
	    install_var_local (decl, ctx);
	  break;

	case OMP_CLAUSE__CONDTEMP_:
	  decl = OMP_CLAUSE_DECL (c);
	  if (is_parallel_ctx (ctx))
	    {
	      install_var_field (decl, false, 3, ctx);
	      install_var_local (decl, ctx);
	    }
	  else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
		   && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
		   && !OMP_CLAUSE__CONDTEMP__ITER (c))
	    install_var_local (decl, ctx);
	  break;

	case OMP_CLAUSE__CACHE_:
	case OMP_CLAUSE_NOHOST:
	default:
	  gcc_unreachable ();
	}
    }

  for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    {
      switch (OMP_CLAUSE_CODE (c))
	{
	case OMP_CLAUSE_LASTPRIVATE:
	  /* Let the corresponding firstprivate clause create
	     the variable.  */
	  if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
	    scan_array_reductions = true;
	  if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
	    break;
	  /* FALLTHRU */

	case OMP_CLAUSE_FIRSTPRIVATE:
	case OMP_CLAUSE_PRIVATE:
	case OMP_CLAUSE_LINEAR:
	case OMP_CLAUSE_IS_DEVICE_PTR:
	  decl = OMP_CLAUSE_DECL (c);
	  if (is_variable_sized (decl))
	    {
	      if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
		   || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
		  && is_gimple_omp_offloaded (ctx->stmt))
		{
		  tree decl2 = DECL_VALUE_EXPR (decl);
		  gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
		  decl2 = TREE_OPERAND (decl2, 0);
		  gcc_assert (DECL_P (decl2));
		  install_var_local (decl2, ctx);
		  fixup_remapped_decl (decl2, ctx, false);
		}
	      install_var_local (decl, ctx);
	    }
	  fixup_remapped_decl (decl, ctx,
			       OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
			       && OMP_CLAUSE_PRIVATE_DEBUG (c));
	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
	      && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
	    scan_array_reductions = true;
	  break;

	case OMP_CLAUSE_REDUCTION:
	case OMP_CLAUSE_IN_REDUCTION:
	  decl = OMP_CLAUSE_DECL (c);
	  if (TREE_CODE (decl) != MEM_REF && !is_omp_target (ctx->stmt))
	    {
	      if (is_variable_sized (decl))
		install_var_local (decl, ctx);
	      fixup_remapped_decl (decl, ctx, false);
	    }
	  if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
	    scan_array_reductions = true;
	  break;

	case OMP_CLAUSE_TASK_REDUCTION:
	  if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
	    scan_array_reductions = true;
	  break;

	case OMP_CLAUSE_SHARED:
	  /* Ignore shared directives in teams construct inside of
	     target construct.  */
	  if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
	      && !is_host_teams_ctx (ctx))
	    break;
	  decl = OMP_CLAUSE_DECL (c);
	  if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
	    break;
	  if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
	    {
	      if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl,
								 ctx->outer)))
		break;
	      bool by_ref = use_pointer_for_field (decl, ctx);
	      install_var_field (decl, by_ref, 11, ctx);
	      break;
	    }
	  fixup_remapped_decl (decl, ctx, false);
	  break;

	case OMP_CLAUSE_MAP:
	  if (!is_gimple_omp_offloaded (ctx->stmt))
	    break;
	  decl = OMP_CLAUSE_DECL (c);
	  if (DECL_P (decl)
	      && ((OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
		   && (OMP_CLAUSE_MAP_KIND (c)
		       != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
		  || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
	      && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
	      && varpool_node::get_create (decl)->offloadable)
	    break;
	  if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
	       || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
	      && is_omp_target (ctx->stmt)
	      && !is_gimple_omp_offloaded (ctx->stmt))
	    break;
	  if (DECL_P (decl))
	    {
	      if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
		   || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
		  && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
		  && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
		{
		  tree new_decl = lookup_decl (decl, ctx);
		  TREE_TYPE (new_decl)
		    = remap_type (TREE_TYPE (decl), &ctx->cb);
		}
	      else if (DECL_SIZE (decl)
		       && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
		{
		  tree decl2 = DECL_VALUE_EXPR (decl);
		  gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
		  decl2 = TREE_OPERAND (decl2, 0);
		  gcc_assert (DECL_P (decl2));
		  fixup_remapped_decl (decl2, ctx, false);
		  fixup_remapped_decl (decl, ctx, true);
		}
	      else
		fixup_remapped_decl (decl, ctx, false);
	    }
	  break;

	case OMP_CLAUSE_COPYPRIVATE:
	case OMP_CLAUSE_COPYIN:
	case OMP_CLAUSE_DEFAULT:
	case OMP_CLAUSE_IF:
	case OMP_CLAUSE_NUM_THREADS:
	case OMP_CLAUSE_NUM_TEAMS:
	case OMP_CLAUSE_THREAD_LIMIT:
	case OMP_CLAUSE_DEVICE:
	case OMP_CLAUSE_SCHEDULE:
	case OMP_CLAUSE_DIST_SCHEDULE:
	case OMP_CLAUSE_NOWAIT:
	case OMP_CLAUSE_ORDERED:
	case OMP_CLAUSE_COLLAPSE:
	case OMP_CLAUSE_UNTIED:
	case OMP_CLAUSE_FINAL:
	case OMP_CLAUSE_MERGEABLE:
	case OMP_CLAUSE_PROC_BIND:
	case OMP_CLAUSE_SAFELEN:
	case OMP_CLAUSE_SIMDLEN:
	case OMP_CLAUSE_ALIGNED:
	case OMP_CLAUSE_DEPEND:
	case OMP_CLAUSE_DETACH:
	case OMP_CLAUSE_ALLOCATE:
	case OMP_CLAUSE__LOOPTEMP_:
	case OMP_CLAUSE__REDUCTEMP_:
	case OMP_CLAUSE_TO:
	case OMP_CLAUSE_FROM:
	case OMP_CLAUSE_PRIORITY:
	case OMP_CLAUSE_GRAINSIZE:
	case OMP_CLAUSE_NUM_TASKS:
	case OMP_CLAUSE_THREADS:
	case OMP_CLAUSE_SIMD:
	case OMP_CLAUSE_NOGROUP:
	case OMP_CLAUSE_DEFAULTMAP:
	case OMP_CLAUSE_ORDER:
	case OMP_CLAUSE_BIND:
	case OMP_CLAUSE_USE_DEVICE_PTR:
	case OMP_CLAUSE_USE_DEVICE_ADDR:
	case OMP_CLAUSE_NONTEMPORAL:
	case OMP_CLAUSE_ASYNC:
	case OMP_CLAUSE_WAIT:
	case OMP_CLAUSE_NUM_GANGS:
	case OMP_CLAUSE_NUM_WORKERS:
	case OMP_CLAUSE_VECTOR_LENGTH:
	case OMP_CLAUSE_GANG:
	case OMP_CLAUSE_WORKER:
	case OMP_CLAUSE_VECTOR:
	case OMP_CLAUSE_INDEPENDENT:
	case OMP_CLAUSE_AUTO:
	case OMP_CLAUSE_SEQ:
	case OMP_CLAUSE_TILE:
	case OMP_CLAUSE__SIMT_:
	case OMP_CLAUSE_IF_PRESENT:
	case OMP_CLAUSE_FINALIZE:
	case OMP_CLAUSE_FILTER:
	case OMP_CLAUSE__CONDTEMP_:
	  break;

	case OMP_CLAUSE__CACHE_:
	case OMP_CLAUSE_NOHOST:
	default:
	  gcc_unreachable ();
	}
    }

  gcc_checking_assert (!scan_array_reductions
		       || !is_gimple_omp_oacc (ctx->stmt));
  if (scan_array_reductions)
    {
      for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
	if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
	     || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
	     || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
	    && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
	  {
	    omp_context *rctx = ctx;
	    if (is_omp_target (ctx->stmt))
	      rctx = ctx->outer;
	    scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), rctx);
	    scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), rctx);
	  }
	else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
		 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
	  scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
	else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
		 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
	  scan_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
    }
}

/* Create a new name for omp child function.  Returns an identifier. */

static tree
create_omp_child_function_name (bool task_copy)
{
  return clone_function_name_numbered (current_function_decl,
				       task_copy ? "_omp_cpyfn" : "_omp_fn");
}

/* Return true if CTX may belong to offloaded code: either if current function
   is offloaded, or any enclosing context corresponds to a target region.  */

static bool
omp_maybe_offloaded_ctx (omp_context *ctx)
{
  if (cgraph_node::get (current_function_decl)->offloadable)
    return true;
  for (; ctx; ctx = ctx->outer)
    if (is_gimple_omp_offloaded (ctx->stmt))
      return true;
  return false;
}

/* Build a decl for the omp child function.  It'll not contain a body
   yet, just the bare decl.  */

static void
create_omp_child_function (omp_context *ctx, bool task_copy)
{
  tree decl, type, name, t;

  name = create_omp_child_function_name (task_copy);
  if (task_copy)
    type = build_function_type_list (void_type_node, ptr_type_node,
				     ptr_type_node, NULL_TREE);
  else
    type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);

  decl = build_decl (gimple_location (ctx->stmt), FUNCTION_DECL, name, type);

  gcc_checking_assert (!is_gimple_omp_oacc (ctx->stmt)
		       || !task_copy);
  if (!task_copy)
    ctx->cb.dst_fn = decl;
  else
    gimple_omp_task_set_copy_fn (ctx->stmt, decl);

  TREE_STATIC (decl) = 1;
  TREE_USED (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 0;
  TREE_PUBLIC (decl) = 0;
  DECL_UNINLINABLE (decl) = 1;
  DECL_EXTERNAL (decl) = 0;
  DECL_CONTEXT (decl) = NULL_TREE;
  DECL_INITIAL (decl) = make_node (BLOCK);
  BLOCK_SUPERCONTEXT (DECL_INITIAL (decl)) = decl;
  DECL_ATTRIBUTES (decl) = DECL_ATTRIBUTES (current_function_decl);
  /* Remove omp declare simd attribute from the new attributes.  */
  if (tree a = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (decl)))
    {
      while (tree a2 = lookup_attribute ("omp declare simd", TREE_CHAIN (a)))
	a = a2;
      a = TREE_CHAIN (a);
      for (tree *p = &DECL_ATTRIBUTES (decl); *p != a;)
	if (is_attribute_p ("omp declare simd", get_attribute_name (*p)))
	  *p = TREE_CHAIN (*p);
	else
	  {
	    tree chain = TREE_CHAIN (*p);
	    *p = copy_node (*p);
	    p = &TREE_CHAIN (*p);
	    *p = chain;
	  }
    }
  DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl)
    = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (current_function_decl);
  DECL_FUNCTION_SPECIFIC_TARGET (decl)
    = DECL_FUNCTION_SPECIFIC_TARGET (current_function_decl);
  DECL_FUNCTION_VERSIONED (decl)
    = DECL_FUNCTION_VERSIONED (current_function_decl);

  if (omp_maybe_offloaded_ctx (ctx))
    {
      cgraph_node::get_create (decl)->offloadable = 1;
      if (ENABLE_OFFLOADING)
	g->have_offload = true;
    }

  if (cgraph_node::get_create (decl)->offloadable)
    {
      const char *target_attr = (is_gimple_omp_offloaded (ctx->stmt)
				 ? "omp target entrypoint"
				 : "omp declare target");
      if (lookup_attribute ("omp declare target",
			    DECL_ATTRIBUTES (current_function_decl)))
	{
	  if (is_gimple_omp_offloaded (ctx->stmt))
	    DECL_ATTRIBUTES (decl)
	      = remove_attribute ("omp declare target",
				  copy_list (DECL_ATTRIBUTES (decl)));
	  else
	    target_attr = NULL;
	}
      if (target_attr)
	DECL_ATTRIBUTES (decl)
	  = tree_cons (get_identifier (target_attr),
		       NULL_TREE, DECL_ATTRIBUTES (decl));
    }

  t = build_decl (DECL_SOURCE_LOCATION (decl),
		  RESULT_DECL, NULL_TREE, void_type_node);
  DECL_ARTIFICIAL (t) = 1;
  DECL_IGNORED_P (t) = 1;
  DECL_CONTEXT (t) = decl;
  DECL_RESULT (decl) = t;

  tree data_name = get_identifier (".omp_data_i");
  t = build_decl (DECL_SOURCE_LOCATION (decl), PARM_DECL, data_name,
		  ptr_type_node);
  DECL_ARTIFICIAL (t) = 1;
  DECL_NAMELESS (t) = 1;
  DECL_ARG_TYPE (t) = ptr_type_node;
  DECL_CONTEXT (t) = current_function_decl;
  TREE_USED (t) = 1;
  TREE_READONLY (t) = 1;
  DECL_ARGUMENTS (decl) = t;
  if (!task_copy)
    ctx->receiver_decl = t;
  else
    {
      t = build_decl (DECL_SOURCE_LOCATION (decl),
		      PARM_DECL, get_identifier (".omp_data_o"),
		      ptr_type_node);
      DECL_ARTIFICIAL (t) = 1;
      DECL_NAMELESS (t) = 1;
      DECL_ARG_TYPE (t) = ptr_type_node;
      DECL_CONTEXT (t) = current_function_decl;
      TREE_USED (t) = 1;
      TREE_ADDRESSABLE (t) = 1;
      DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
      DECL_ARGUMENTS (decl) = t;
    }

  /* Allocate memory for the function structure.  The call to
     allocate_struct_function clobbers CFUN, so we need to restore
     it afterward.  */
  push_struct_function (decl);
  cfun->function_end_locus = gimple_location (ctx->stmt);
  init_tree_ssa (cfun);
  pop_cfun ();
}

/* Callback for walk_gimple_seq.  Check if combined parallel
   contains gimple_omp_for_combined_into_p OMP_FOR.  */

tree
omp_find_combined_for (gimple_stmt_iterator *gsi_p,
		       bool *handled_ops_p,
		       struct walk_stmt_info *wi)
{
  gimple *stmt = gsi_stmt (*gsi_p);

  *handled_ops_p = true;
  switch (gimple_code (stmt))
    {
    WALK_SUBSTMTS;

    case GIMPLE_OMP_FOR:
      if (gimple_omp_for_combined_into_p (stmt)
	  && gimple_omp_for_kind (stmt)
	     == *(const enum gf_mask *) (wi->info))
	{
	  wi->info = stmt;
	  return integer_zero_node;
	}
      break;
    default:
      break;
    }
  return NULL;
}

/* Add _LOOPTEMP_/_REDUCTEMP_ clauses on OpenMP parallel or task.  */

static void
add_taskreg_looptemp_clauses (enum gf_mask msk, gimple *stmt,
			      omp_context *outer_ctx)
{
  struct walk_stmt_info wi;

  memset (&wi, 0, sizeof (wi));
  wi.val_only = true;
  wi.info = (void *) &msk;
  walk_gimple_seq (gimple_omp_body (stmt), omp_find_combined_for, NULL, &wi);
  if (wi.info != (void *) &msk)
    {
      gomp_for *for_stmt = as_a <gomp_for *> ((gimple *) wi.info);
      struct omp_for_data fd;
      omp_extract_for_data (for_stmt, &fd, NULL);
      /* We need two temporaries with fd.loop.v type (istart/iend)
	 and then (fd.collapse - 1) temporaries with the same
	 type for count2 ... countN-1 vars if not constant.  */
      size_t count = 2, i;
      tree type = fd.iter_type;
      if (fd.collapse > 1
	  && TREE_CODE (fd.loop.n2) != INTEGER_CST)
	{
	  count += fd.collapse - 1;
	  /* If there are lastprivate clauses on the inner
	     GIMPLE_OMP_FOR, add one more temporaries for the total number
	     of iterations (product of count1 ... countN-1).  */
	  if (omp_find_clause (gimple_omp_for_clauses (for_stmt),
			       OMP_CLAUSE_LASTPRIVATE)
	      || (msk == GF_OMP_FOR_KIND_FOR
		  && omp_find_clause (gimple_omp_parallel_clauses (stmt),
				      OMP_CLAUSE_LASTPRIVATE)))
	    {
	      tree temp = create_tmp_var (type);
	      tree c = build_omp_clause (UNKNOWN_LOCATION,
					 OMP_CLAUSE__LOOPTEMP_);
	      insert_decl_map (&outer_ctx->cb, temp, temp);
	      OMP_CLAUSE_DECL (c) = temp;
	      OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
	      gimple_omp_taskreg_set_clauses (stmt, c);
	    }
	  if (fd.non_rect
	      && fd.last_nonrect == fd.first_nonrect + 1)
	    if (tree v = gimple_omp_for_index (for_stmt, fd.last_nonrect))
	      if (!TYPE_UNSIGNED (TREE_TYPE (v)))
		{
		  v = gimple_omp_for_index (for_stmt, fd.first_nonrect);
		  tree type2 = TREE_TYPE (v);
		  count++;
		  for (i = 0; i < 3; i++)
		    {
		      tree temp = create_tmp_var (type2);
		      tree c = build_omp_clause (UNKNOWN_LOCATION,
						 OMP_CLAUSE__LOOPTEMP_);
		      insert_decl_map (&outer_ctx->cb, temp, temp);
		      OMP_CLAUSE_DECL (c) = temp;
		      OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
		      gimple_omp_taskreg_set_clauses (stmt, c);
		    }
		}
	}
      for (i = 0; i < count; i++)
	{
	  tree temp = create_tmp_var (type);
	  tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_);
	  insert_decl_map (&outer_ctx->cb, temp, temp);
	  OMP_CLAUSE_DECL (c) = temp;
	  OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
	  gimple_omp_taskreg_set_clauses (stmt, c);
	}
    }
  if (msk == GF_OMP_FOR_KIND_TASKLOOP
      && omp_find_clause (gimple_omp_task_clauses (stmt),
			  OMP_CLAUSE_REDUCTION))
    {
      tree type = build_pointer_type (pointer_sized_int_node);
      tree temp = create_tmp_var (type);
      tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
      insert_decl_map (&outer_ctx->cb, temp, temp);
      OMP_CLAUSE_DECL (c) = temp;
      OMP_CLAUSE_CHAIN (c) = gimple_omp_task_clauses (stmt);
      gimple_omp_task_set_clauses (stmt, c);
    }
}

/* Scan an OpenMP parallel directive.  */

static void
scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
{
  omp_context *ctx;
  tree name;
  gomp_parallel *stmt = as_a <gomp_parallel *> (gsi_stmt (*gsi));

  /* Ignore parallel directives with empty bodies, unless there
     are copyin clauses.  */
  if (optimize > 0
      && empty_body_p (gimple_omp_body (stmt))
      && omp_find_clause (gimple_omp_parallel_clauses (stmt),
			  OMP_CLAUSE_COPYIN) == NULL)
    {
      gsi_replace (gsi, gimple_build_nop (), false);
      return;
    }

  if (gimple_omp_parallel_combined_p (stmt))
    add_taskreg_looptemp_clauses (GF_OMP_FOR_KIND_FOR, stmt, outer_ctx);
  for (tree c = omp_find_clause (gimple_omp_parallel_clauses (stmt),
				 OMP_CLAUSE_REDUCTION);
       c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE_REDUCTION))
    if (OMP_CLAUSE_REDUCTION_TASK (c))
      {
	tree type = build_pointer_type (pointer_sized_int_node);
	tree temp = create_tmp_var (type);
	tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
	if (outer_ctx)
	  insert_decl_map (&outer_ctx->cb, temp, temp);
	OMP_CLAUSE_DECL (c) = temp;
	OMP_CLAUSE_CHAIN (c) = gimple_omp_parallel_clauses (stmt);
	gimple_omp_parallel_set_clauses (stmt, c);
	break;
      }
    else if (OMP_CLAUSE_CHAIN (c) == NULL_TREE)
      break;

  ctx = new_omp_context (stmt, outer_ctx);
  taskreg_contexts.safe_push (ctx);
  if (taskreg_nesting_level > 1)
    ctx->is_nested = true;
  ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
  name = create_tmp_var_name (".omp_data_s");
  name = build_decl (gimple_location (stmt),
		     TYPE_DECL, name, ctx->record_type);
  DECL_ARTIFICIAL (name) = 1;
  DECL_NAMELESS (name) = 1;
  TYPE_NAME (ctx->record_type) = name;
  TYPE_ARTIFICIAL (ctx->record_type) = 1;
  create_omp_child_function (ctx, false);
  gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);

  scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
  scan_omp (gimple_omp_body_ptr (stmt), ctx);

  if (TYPE_FIELDS (ctx->record_type) == NULL)
    ctx->record_type = ctx->receiver_decl = NULL;
}

/* Scan an OpenMP task directive.  */

static void
scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
{
  omp_context *ctx;
  tree name, t;
  gomp_task *stmt = as_a <gomp_task *> (gsi_stmt (*gsi));

  /* Ignore task directives with empty bodies, unless they have depend
     clause.  */
  if (optimize > 0
      && gimple_omp_body (stmt)
      && empty_body_p (gimple_omp_body (stmt))
      && !omp_find_clause (gimple_omp_task_clauses (stmt), OMP_CLAUSE_DEPEND))
    {
      gsi_replace (gsi, gimple_build_nop (), false);
      return;
    }

  if (gimple_omp_task_taskloop_p (stmt))
    add_taskreg_looptemp_clauses (GF_OMP_FOR_KIND_TASKLOOP, stmt, outer_ctx);

  ctx = new_omp_context (stmt, outer_ctx);

  if (gimple_omp_task_taskwait_p (stmt))
    {
      scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
      return;
    }

  taskreg_contexts.safe_push (ctx);
  if (taskreg_nesting_level > 1)
    ctx->is_nested = true;
  ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
  name = create_tmp_var_name (".omp_data_s");
  name = build_decl (gimple_location (stmt),
		     TYPE_DECL, name, ctx->record_type);
  DECL_ARTIFICIAL (name) = 1;
  DECL_NAMELESS (name) = 1;
  TYPE_NAME (ctx->record_type) = name;
  TYPE_ARTIFICIAL (ctx->record_type) = 1;
  create_omp_child_function (ctx, false);
  gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);

  scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);

  if (ctx->srecord_type)
    {
      name = create_tmp_var_name (".omp_data_a");
      name = build_decl (gimple_location (stmt),
			 TYPE_DECL, name, ctx->srecord_type);
      DECL_ARTIFICIAL (name) = 1;
      DECL_NAMELESS (name) = 1;
      TYPE_NAME (ctx->srecord_type) = name;
      TYPE_ARTIFICIAL (ctx->srecord_type) = 1;
      create_omp_child_function (ctx, true);
    }

  scan_omp (gimple_omp_body_ptr (stmt), ctx);

  if (TYPE_FIELDS (ctx->record_type) == NULL)
    {
      ctx->record_type = ctx->receiver_decl = NULL;
      t = build_int_cst (long_integer_type_node, 0);
      gimple_omp_task_set_arg_size (stmt, t);
      t = build_int_cst (long_integer_type_node, 1);
      gimple_omp_task_set_arg_align (stmt, t);
    }
}

/* Helper function for finish_taskreg_scan, called through walk_tree.
   If maybe_lookup_decl_in_outer_context returns non-NULL for some
   tree, replace it in the expression.  */

static tree
finish_taskreg_remap (tree *tp, int *walk_subtrees, void *data)
{
  if (VAR_P (*tp))
    {
      omp_context *ctx = (omp_context *) data;
      tree t = maybe_lookup_decl_in_outer_ctx (*tp, ctx);
      if (t != *tp)
	{
	  if (DECL_HAS_VALUE_EXPR_P (t))
	    t = unshare_expr (DECL_VALUE_EXPR (t));
	  *tp = t;
	}
      *walk_subtrees = 0;
    }
  else if (IS_TYPE_OR_DECL_P (*tp))
    *walk_subtrees = 0;
  return NULL_TREE;
}

/* If any decls have been made addressable during scan_omp,
   adjust their fields if needed, and layout record types
   of parallel/task constructs.  */

static void
finish_taskreg_scan (omp_context *ctx)
{
  if (ctx->record_type == NULL_TREE)
    return;

  /* If any task_shared_vars were needed, verify all
     OMP_CLAUSE_SHARED clauses on GIMPLE_OMP_{PARALLEL,TASK,TEAMS}
     statements if use_pointer_for_field hasn't changed
     because of that.  If it did, update field types now.  */
  if (task_shared_vars)
    {
      tree c;

      for (c = gimple_omp_taskreg_clauses (ctx->stmt);
	   c; c = OMP_CLAUSE_CHAIN (c))
	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
	    && !OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
	  {
	    tree decl = OMP_CLAUSE_DECL (c);

	    /* Global variables don't need to be copied,
	       the receiver side will use them directly.  */
	    if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
	      continue;
	    if (!bitmap_bit_p (task_shared_vars, DECL_UID (decl))
		|| !use_pointer_for_field (decl, ctx))
	      continue;
	    tree field = lookup_field (decl, ctx);
	    if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
		&& TREE_TYPE (TREE_TYPE (field)) == TREE_TYPE (decl))
	      continue;
	    TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
	    TREE_THIS_VOLATILE (field) = 0;
	    DECL_USER_ALIGN (field) = 0;
	    SET_DECL_ALIGN (field, TYPE_ALIGN (TREE_TYPE (field)));
	    if (TYPE_ALIGN (ctx->record_type) < DECL_ALIGN (field))
	      SET_TYPE_ALIGN (ctx->record_type, DECL_ALIGN (field));
	    if (ctx->srecord_type)
	      {
		tree sfield = lookup_sfield (decl, ctx);
		TREE_TYPE (sfield) = TREE_TYPE (field);
		TREE_THIS_VOLATILE (sfield) = 0;
		DECL_USER_ALIGN (sfield) = 0;
		SET_DECL_ALIGN (sfield, DECL_ALIGN (field));
		if (TYPE_ALIGN (ctx->srecord_type) < DECL_ALIGN (sfield))
		  SET_TYPE_ALIGN (ctx->srecord_type, DECL_ALIGN (sfield));
	      }
	  }
    }

  if (gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
    {
      tree clauses = gimple_omp_parallel_clauses (ctx->stmt);
      tree c = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
      if (c)
	{
	  /* Move the _reductemp_ clause first.  GOMP_parallel_reductions
	     expects to find it at the start of data.  */
	  tree f = lookup_field (OMP_CLAUSE_DECL (c), ctx);
	  tree *p = &TYPE_FIELDS (ctx->record_type);
	  while (*p)
	    if (*p == f)
	      {
		*p = DECL_CHAIN (*p);
		break;
	      }
	    else
	      p = &DECL_CHAIN (*p);
	  DECL_CHAIN (f) = TYPE_FIELDS (ctx->record_type);
	  TYPE_FIELDS (ctx->record_type) = f;
	}
      layout_type (ctx->record_type);
      fixup_child_record_type (ctx);
    }
  else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
    {
      layout_type (ctx->record_type);
      fixup_child_record_type (ctx);
    }
  else
    {
      location_t loc = gimple_location (ctx->stmt);
      tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
      tree detach_clause
	= omp_find_clause (gimple_omp_task_clauses (ctx->stmt),
			   OMP_CLAUSE_DETACH);
      /* Move VLA fields to the end.  */
      p = &TYPE_FIELDS (ctx->record_type);
      while (*p)
	if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
	    || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
	  {
	    *q = *p;
	    *p = TREE_CHAIN (*p);
	    TREE_CHAIN (*q) = NULL_TREE;
	    q = &TREE_CHAIN (*q);
	  }
	else
	  p = &DECL_CHAIN (*p);
      *p = vla_fields;
      if (gimple_omp_task_taskloop_p (ctx->stmt))
	{
	  /* Move fields corresponding to first and second _looptemp_
	     clause first.  There are filled by GOMP_taskloop
	     and thus need to be in specific positions.  */
	  tree clauses = gimple_omp_task_clauses (ctx->stmt);
	  tree c1 = omp_find_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
	  tree c2 = omp_find_clause (OMP_CLAUSE_CHAIN (c1),
				     OMP_CLAUSE__LOOPTEMP_);
	  tree c3 = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
	  tree f1 = lookup_field (OMP_CLAUSE_DECL (c1), ctx);
	  tree f2 = lookup_field (OMP_CLAUSE_DECL (c2), ctx);
	  tree f3 = c3 ? lookup_field (OMP_CLAUSE_DECL (c3), ctx) : NULL_TREE;
	  p = &TYPE_FIELDS (ctx->record_type);
	  while (*p)
	    if (*p == f1 || *p == f2 || *p == f3)
	      *p = DECL_CHAIN (*p);
	    else
	      p = &DECL_CHAIN (*p);
	  DECL_CHAIN (f1) = f2;
	  if (c3)
	    {
	      DECL_CHAIN (f2) = f3;
	      DECL_CHAIN (f3) = TYPE_FIELDS (ctx->record_type);
	    }
	  else
	    DECL_CHAIN (f2) = TYPE_FIELDS (ctx->record_type);
	  TYPE_FIELDS (ctx->record_type) = f1;
	  if (ctx->srecord_type)
	    {
	      f1 = lookup_sfield (OMP_CLAUSE_DECL (c1), ctx);
	      f2 = lookup_sfield (OMP_CLAUSE_DECL (c2), ctx);
	      if (c3)
		f3 = lookup_sfield (OMP_CLAUSE_DECL (c3), ctx);
	      p = &TYPE_FIELDS (ctx->srecord_type);
	      while (*p)
		if (*p == f1 || *p == f2 || *p == f3)
		  *p = DECL_CHAIN (*p);
		else
		  p = &DECL_CHAIN (*p);
	      DECL_CHAIN (f1) = f2;
	      DECL_CHAIN (f2) = TYPE_FIELDS (ctx->srecord_type);
	      if (c3)
		{
		  DECL_CHAIN (f2) = f3;
		  DECL_CHAIN (f3) = TYPE_FIELDS (ctx->srecord_type);
		}
	      else
		DECL_CHAIN (f2) = TYPE_FIELDS (ctx->srecord_type);
	      TYPE_FIELDS (ctx->srecord_type) = f1;
	    }
	}
      if (detach_clause)
	{
	  tree c, field;

	  /* Look for a firstprivate clause with the detach event handle.  */
	  for (c = gimple_omp_taskreg_clauses (ctx->stmt);
	       c; c = OMP_CLAUSE_CHAIN (c))
	    {
	      if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
		continue;
	      if (maybe_lookup_decl_in_outer_ctx (OMP_CLAUSE_DECL (c), ctx)
		  == OMP_CLAUSE_DECL (detach_clause))
		break;
	    }

	  gcc_assert (c);
	  field = lookup_field (OMP_CLAUSE_DECL (c), ctx);

	  /* Move field corresponding to the detach clause first.
	     This is filled by GOMP_task and needs to be in a
	     specific position.  */
	  p = &TYPE_FIELDS (ctx->record_type);
	  while (*p)
	    if (*p == field)
	      *p = DECL_CHAIN (*p);
	    else
	      p = &DECL_CHAIN (*p);
	  DECL_CHAIN (field) = TYPE_FIELDS (ctx->record_type);
	  TYPE_FIELDS (ctx->record_type) = field;
	  if (ctx->srecord_type)
	    {
	      field = lookup_sfield (OMP_CLAUSE_DECL (c), ctx);
	      p = &TYPE_FIELDS (ctx->srecord_type);
	      while (*p)
		if (*p == field)
		  *p = DECL_CHAIN (*p);
		else
		  p = &DECL_CHAIN (*p);
	      DECL_CHAIN (field) = TYPE_FIELDS (ctx->srecord_type);
	      TYPE_FIELDS (ctx->srecord_type) = field;
	    }
	}
      layout_type (ctx->record_type);
      fixup_child_record_type (ctx);
      if (ctx->srecord_type)
	layout_type (ctx->srecord_type);
      tree t = fold_convert_loc (loc, long_integer_type_node,
				 TYPE_SIZE_UNIT (ctx->record_type));
      if (TREE_CODE (t) != INTEGER_CST)
	{
	  t = unshare_expr (t);
	  walk_tree (&t, finish_taskreg_remap, ctx, NULL);
	}
      gimple_omp_task_set_arg_size (ctx->stmt, t);
      t = build_int_cst (long_integer_type_node,
			 TYPE_ALIGN_UNIT (ctx->record_type));
      gimple_omp_task_set_arg_align (ctx->stmt, t);
    }
}

/* Find the enclosing offload context.  */

static omp_context *
enclosing_target_ctx (omp_context *ctx)
{
  for (; ctx; ctx = ctx->outer)
    if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET)
      break;

  return ctx;
}

/* Return whether CTX's parent compute construct is an OpenACC 'kernels'
   construct.
   (This doesn't include OpenACC 'kernels' decomposed parts.)  */

static bool
ctx_in_oacc_kernels_region (omp_context *ctx)
{
  for (;ctx != NULL; ctx = ctx->outer)
    {
      gimple *stmt = ctx->stmt;
      if (gimple_code (stmt) == GIMPLE_OMP_TARGET
	  && gimple_omp_target_kind (stmt) == GF_OMP_TARGET_KIND_OACC_KERNELS)
	return true;
    }

  return false;
}

/* Check the parallelism clauses inside a OpenACC 'kernels' region.
   (This doesn't include OpenACC 'kernels' decomposed parts.)
   Until kernels handling moves to use the same loop indirection
   scheme as parallel, we need to do this checking early.  */

static unsigned
check_oacc_kernel_gwv (gomp_for *stmt, omp_context *ctx)
{
  bool checking = true;
  unsigned outer_mask = 0;
  unsigned this_mask = 0;
  bool has_seq = false, has_auto = false;

  if (ctx->outer)
    outer_mask = check_oacc_kernel_gwv (NULL,  ctx->outer);
  if (!stmt)
    {
      checking = false;
      if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR)
	return outer_mask;
      stmt = as_a <gomp_for *> (ctx->stmt);
    }

  for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
    {
      switch (OMP_CLAUSE_CODE (c))
	{
	case OMP_CLAUSE_GANG:
	  this_mask |= GOMP_DIM_MASK (GOMP_DIM_GANG);
	  break;
	case OMP_CLAUSE_WORKER:
	  this_mask |= GOMP_DIM_MASK (GOMP_DIM_WORKER);
	  break;
	case OMP_CLAUSE_VECTOR:
	  this_mask |= GOMP_DIM_MASK (GOMP_DIM_VECTOR);
	  break;
	case OMP_CLAUSE_SEQ:
	  has_seq = true;
	  break;
	case OMP_CLAUSE_AUTO:
	  has_auto = true;
	  break;
	default:
	  break;
	}
    }

  if (checking)
    {
      if (has_seq && (this_mask || has_auto))
	error_at (gimple_location (stmt), "%<seq%> overrides other"
		  " OpenACC loop specifiers");
      else if (has_auto && this_mask)
	error_at (gimple_location (stmt), "%<auto%> conflicts with other"
		  " OpenACC loop specifiers");

      if (this_mask & outer_mask)
	error_at (gimple_location (stmt), "inner loop uses same"
		  " OpenACC parallelism as containing loop");
    }

  return outer_mask | this_mask;
}

/* Scan a GIMPLE_OMP_FOR.  */

static omp_context *
scan_omp_for (gomp_for *stmt, omp_context *outer_ctx)
{
  omp_context *ctx;
  size_t i;
  tree clauses = gimple_omp_for_clauses (stmt);

  ctx = new_omp_context (stmt, outer_ctx);

  if (is_gimple_omp_oacc (stmt))
    {
      omp_context *tgt = enclosing_target_ctx (outer_ctx);

      if (!(tgt && is_oacc_kernels (tgt)))
	for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
	  {
	    tree c_op0;
	    switch (OMP_CLAUSE_CODE (c))
	      {
	      case OMP_CLAUSE_GANG:
		c_op0 = OMP_CLAUSE_GANG_EXPR (c);
		break;

	      case OMP_CLAUSE_WORKER:
		c_op0 = OMP_CLAUSE_WORKER_EXPR (c);
		break;

	      case OMP_CLAUSE_VECTOR:
		c_op0 = OMP_CLAUSE_VECTOR_EXPR (c);
		break;

	      default:
		continue;
	      }

	    if (c_op0)
	      {
		/* By construction, this is impossible for OpenACC 'kernels'
		   decomposed parts.  */
		gcc_assert (!(tgt && is_oacc_kernels_decomposed_part (tgt)));

		error_at (OMP_CLAUSE_LOCATION (c),
			  "argument not permitted on %qs clause",
			  omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
		if (tgt)
		  inform (gimple_location (tgt->stmt),
			  "enclosing parent compute construct");
		else if (oacc_get_fn_attrib (current_function_decl))
		  inform (DECL_SOURCE_LOCATION (current_function_decl),
			  "enclosing routine");
		else
		  gcc_unreachable ();
	      }
	  }

      if (tgt && is_oacc_kernels (tgt))
	check_oacc_kernel_gwv (stmt, ctx);

      /* Collect all variables named in reductions on this loop.  Ensure
	 that, if this loop has a reduction on some variable v, and there is
	 a reduction on v somewhere in an outer context, then there is a
	 reduction on v on all intervening loops as well.  */
      tree local_reduction_clauses = NULL;
      for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
	{
	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
	    local_reduction_clauses
	      = tree_cons (NULL, c, local_reduction_clauses);
	}
      if (ctx->outer_reduction_clauses == NULL && ctx->outer != NULL)
	ctx->outer_reduction_clauses
	  = chainon (unshare_expr (ctx->outer->local_reduction_clauses),
		     ctx->outer->outer_reduction_clauses);
      tree outer_reduction_clauses = ctx->outer_reduction_clauses;
      tree local_iter = local_reduction_clauses;
      for (; local_iter; local_iter = TREE_CHAIN (local_iter))
	{
	  tree local_clause = TREE_VALUE (local_iter);
	  tree local_var = OMP_CLAUSE_DECL (local_clause);
	  tree_code local_op = OMP_CLAUSE_REDUCTION_CODE (local_clause);
	  bool have_outer_reduction = false;
	  tree ctx_iter = outer_reduction_clauses;
	  for (; ctx_iter; ctx_iter = TREE_CHAIN (ctx_iter))
	    {
	      tree outer_clause = TREE_VALUE (ctx_iter);
	      tree outer_var = OMP_CLAUSE_DECL (outer_clause);
	      tree_code outer_op = OMP_CLAUSE_REDUCTION_CODE (outer_clause);
	      if (outer_var == local_var && outer_op != local_op)
		{
		  warning_at (OMP_CLAUSE_LOCATION (local_clause), 0,
			      "conflicting reduction operations for %qE",
			      local_var);
		  inform (OMP_CLAUSE_LOCATION (outer_clause),
			  "location of the previous reduction for %qE",
			  outer_var);
		}
	      if (outer_var == local_var)
		{
		  have_outer_reduction = true;
		  break;
		}
	    }
	  if (have_outer_reduction)
	    {
	      /* There is a reduction on outer_var both on this loop and on
		 some enclosing loop.  Walk up the context tree until such a
		 loop with a reduction on outer_var is found, and complain
		 about all intervening loops that do not have such a
		 reduction.  */
	      struct omp_context *curr_loop = ctx->outer;
	      bool found = false;
	      while (curr_loop != NULL)
		{
		  tree curr_iter = curr_loop->local_reduction_clauses;
		  for (; curr_iter; curr_iter = TREE_CHAIN (curr_iter))
		    {
		      tree curr_clause = TREE_VALUE (curr_iter);
		      tree curr_var = OMP_CLAUSE_DECL (curr_clause);
		      if (curr_var == local_var)
			{
			  found = true;
			  break;
			}
		    }
		  if (!found)
		    warning_at (gimple_location (curr_loop->stmt), 0,
				"nested loop in reduction needs "
				"reduction clause for %qE",
				local_var);
		  else
		    break;
		  curr_loop = curr_loop->outer;
		}
	    }
	}
      ctx->local_reduction_clauses = local_reduction_clauses;
      ctx->outer_reduction_clauses
	= chainon (unshare_expr (ctx->local_reduction_clauses),
		   ctx->outer_reduction_clauses);

      if (tgt && is_oacc_kernels (tgt))
	{
	  /* Strip out reductions, as they are not handled yet.  */
	  tree *prev_ptr = &clauses;

	  while (tree probe = *prev_ptr)
	    {
	      tree *next_ptr = &OMP_CLAUSE_CHAIN (probe);

	      if (OMP_CLAUSE_CODE (probe) == OMP_CLAUSE_REDUCTION)
		*prev_ptr = *next_ptr;
	      else
		prev_ptr = next_ptr;
	    }

	  gimple_omp_for_set_clauses (stmt, clauses);
	}
    }

  scan_sharing_clauses (clauses, ctx);

  scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
  for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
    {
      scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
      scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
      scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
      scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
    }
  scan_omp (gimple_omp_body_ptr (stmt), ctx);
  return ctx;
}

/* Duplicate #pragma omp simd, one for SIMT, another one for SIMD.  */

static void
scan_omp_simd (gimple_stmt_iterator *gsi, gomp_for *stmt,
	       omp_context *outer_ctx)
{
  gbind *bind = gimple_build_bind (NULL, NULL, NULL);
  gsi_replace (gsi, bind, false);
  gimple_seq seq = NULL;
  gimple *g = gimple_build_call_internal (IFN_GOMP_USE_SIMT, 0);
  tree cond = create_tmp_var_raw (integer_type_node);
  DECL_CONTEXT (cond) = current_function_decl;
  DECL_SEEN_IN_BIND_EXPR_P (cond) = 1;
  gimple_bind_set_vars (bind, cond);
  gimple_call_set_lhs (g, cond);
  gimple_seq_add_stmt (&seq, g);
  tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
  tree lab2 = create_artificial_label (UNKNOWN_LOCATION);
  tree lab3 = create_artificial_label (UNKNOWN_LOCATION);
  g = gimple_build_cond (NE_EXPR, cond, integer_zero_node, lab1, lab2);
  gimple_seq_add_stmt (&seq, g);
  g = gimple_build_label (lab1);
  gimple_seq_add_stmt (&seq, g);
  gimple_seq new_seq = copy_gimple_seq_and_replace_locals (stmt);
  gomp_for *new_stmt = as_a <gomp_for *> (new_seq);
  tree clause = build_omp_clause (gimple_location (stmt), OMP_CLAUSE__SIMT_);
  OMP_CLAUSE_CHAIN (clause) = gimple_omp_for_clauses (new_stmt);
  gimple_omp_for_set_clauses (new_stmt, clause);
  gimple_seq_add_stmt (&seq, new_stmt);
  g = gimple_build_goto (lab3);
  gimple_seq_add_stmt (&seq, g);
  g = gimple_build_label (lab2);
  gimple_seq_add_stmt (&seq, g);
  gimple_seq_add_stmt (&seq, stmt);
  g = gimple_build_label (lab3);
  gimple_seq_add_stmt (&seq, g);
  gimple_bind_set_body (bind, seq);
  update_stmt (bind);
  scan_omp_for (new_stmt, outer_ctx);
  scan_omp_for (stmt, outer_ctx)->simt_stmt = new_stmt;
}

static tree omp_find_scan (gimple_stmt_iterator *, bool *,
			   struct walk_stmt_info *);
static omp_context *maybe_lookup_ctx (gimple *);

/* Duplicate #pragma omp simd, one for the scan input phase loop and one
   for scan phase loop.  */

static void
scan_omp_simd_scan (gimple_stmt_iterator *gsi, gomp_for *stmt,
		    omp_context *outer_ctx)
{
  /* The only change between inclusive and exclusive scan will be
     within the first simd loop, so just use inclusive in the
     worksharing loop.  */
  outer_ctx->scan_inclusive = true;
  tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_INCLUSIVE);
  OMP_CLAUSE_DECL (c) = integer_zero_node;

  gomp_scan *input_stmt = gimple_build_omp_scan (NULL, NULL_TREE);
  gomp_scan *scan_stmt = gimple_build_omp_scan (NULL, c);
  gsi_replace (gsi, input_stmt, false);
  gimple_seq input_body = NULL;
  gimple_seq_add_stmt (&input_body, stmt);
  gsi_insert_after (gsi, scan_stmt, GSI_NEW_STMT);

  gimple_stmt_iterator input1_gsi = gsi_none ();
  struct walk_stmt_info wi;
  memset (&wi, 0, sizeof (wi));
  wi.val_only = true;
  wi.info = (void *) &input1_gsi;
  walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), omp_find_scan, NULL, &wi);
  gcc_assert (!gsi_end_p (input1_gsi));

  gimple *input_stmt1 = gsi_stmt (input1_gsi);
  gsi_next (&input1_gsi);
  gimple *scan_stmt1 = gsi_stmt (input1_gsi);
  gcc_assert (scan_stmt1 && gimple_code (scan_stmt1) == GIMPLE_OMP_SCAN);
  c = gimple_omp_scan_clauses (as_a <gomp_scan *> (scan_stmt1));
  if (c && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_EXCLUSIVE)
    std::swap (input_stmt1, scan_stmt1);

  gimple_seq input_body1 = gimple_omp_body (input_stmt1);
  gimple_omp_set_body (input_stmt1, NULL);

  gimple_seq scan_body = copy_gimple_seq_and_replace_locals (stmt);
  gomp_for *new_stmt = as_a <gomp_for *> (scan_body);

  gimple_omp_set_body (input_stmt1, input_body1);
  gimple_omp_set_body (scan_stmt1, NULL);

  gimple_stmt_iterator input2_gsi = gsi_none ();
  memset (&wi, 0, sizeof (wi));
  wi.val_only = true;
  wi.info = (void *) &input2_gsi;
  walk_gimple_seq_mod (gimple_omp_body_ptr (new_stmt), omp_find_scan,
		       NULL, &wi);
  gcc_assert (!gsi_end_p (input2_gsi));

  gimple *input_stmt2 = gsi_stmt (input2_gsi);
  gsi_next (&input2_gsi);
  gimple *scan_stmt2 = gsi_stmt (input2_gsi);
  gcc_assert (scan_stmt2 && gimple_code (scan_stmt2) == GIMPLE_OMP_SCAN);
  if (c && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_EXCLUSIVE)
    std::swap (input_stmt2, scan_stmt2);

  gimple_omp_set_body (input_stmt2, NULL);

  gimple_omp_set_body (input_stmt, input_body);
  gimple_omp_set_body (scan_stmt, scan_body);

  omp_context *ctx = new_omp_context (input_stmt, outer_ctx);
  scan_omp (gimple_omp_body_ptr (input_stmt), ctx);

  ctx = new_omp_context (scan_stmt, outer_ctx);
  scan_omp (gimple_omp_body_ptr (scan_stmt), ctx);

  maybe_lookup_ctx (new_stmt)->for_simd_scan_phase = true;
}

/* Scan an OpenMP sections directive.  */

static void
scan_omp_sections (gomp_sections *stmt, omp_context *outer_ctx)
{
  omp_context *ctx;

  ctx = new_omp_context (stmt, outer_ctx);
  scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
  scan_omp (gimple_omp_body_ptr (stmt), ctx);
}

/* Scan an OpenMP single directive.  */

static void
scan_omp_single (gomp_single *stmt, omp_context *outer_ctx)
{
  omp_context *ctx;
  tree name;

  ctx = new_omp_context (stmt, outer_ctx);
  ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
  name = create_tmp_var_name (".omp_copy_s");
  name = build_decl (gimple_location (stmt),
		     TYPE_DECL, name, ctx->record_type);
  TYPE_NAME (ctx->record_type) = name;

  scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
  scan_omp (gimple_omp_body_ptr (stmt), ctx);

  if (TYPE_FIELDS (ctx->record_type) == NULL)
    ctx->record_type = NULL;
  else
    layout_type (ctx->record_type);
}

/* Scan a GIMPLE_OMP_TARGET.  */

static void
scan_omp_target (gomp_target *stmt, omp_context *outer_ctx)
{
  omp_context *ctx;
  tree name;
  bool offloaded = is_gimple_omp_offloaded (stmt);
  tree clauses = gimple_omp_target_clauses (stmt);

  ctx = new_omp_context (stmt, outer_ctx);
  ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
  name = create_tmp_var_name (".omp_data_t");
  name = build_decl (gimple_location (stmt),
		     TYPE_DECL, name, ctx->record_type);
  DECL_ARTIFICIAL (name) = 1;
  DECL_NAMELESS (name) = 1;
  TYPE_NAME (ctx->record_type) = name;
  TYPE_ARTIFICIAL (ctx->record_type) = 1;

  if (offloaded)
    {
      create_omp_child_function (ctx, false);
      gimple_omp_target_set_child_fn (stmt, ctx->cb.dst_fn);
    }

  scan_sharing_clauses (clauses, ctx);
  scan_omp (gimple_omp_body_ptr (stmt), ctx);

  if (TYPE_FIELDS (ctx->record_type) == NULL)
    ctx->record_type = ctx->receiver_decl = NULL;
  else
    {
      TYPE_FIELDS (ctx->record_type)
	= nreverse (TYPE_FIELDS (ctx->record_type));
      if (flag_checking)
	{
	  unsigned int align = DECL_ALIGN (TYPE_FIELDS (ctx->record_type));
	  for (tree field = TYPE_FIELDS (ctx->record_type);
	       field;
	       field = DECL_CHAIN (field))
	    gcc_assert (DECL_ALIGN (field) == align);
	}
      layout_type (ctx->record_type);
      if (offloaded)
	fixup_child_record_type (ctx);
    }

  if (ctx->teams_nested_p && ctx->nonteams_nested_p)
    {
      error_at (gimple_location (stmt),
		"%<target%> construct with nested %<teams%> construct "
		"contains directives outside of the %<teams%> construct");
      gimple_omp_set_body (stmt, gimple_build_bind (NULL, NULL, NULL));
    }
}

/* Scan an OpenMP teams directive.  */

static void
scan_omp_teams (gomp_teams *stmt, omp_context *outer_ctx)
{
  omp_context *ctx = new_omp_context (stmt, outer_ctx);

  if (!gimple_omp_teams_host (stmt))
    {
      scan_sharing_clauses (gimple_omp_teams_clauses (stmt), ctx);
      scan_omp (gimple_omp_body_ptr (stmt), ctx);
      return;
    }
  taskreg_contexts.safe_push (ctx);
  gcc_assert (taskreg_nesting_level == 1);
  ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
  tree name = create_tmp_var_name (".omp_data_s");
  name = build_decl (gimple_location (stmt),
		     TYPE_DECL, name, ctx->record_type);
  DECL_ARTIFICIAL (name) = 1;
  DECL_NAMELESS (name) = 1;
  TYPE_NAME (ctx->record_type) = name;
  TYPE_ARTIFICIAL (ctx->record_type) = 1;
  create_omp_child_function (ctx, false);
  gimple_omp_teams_set_child_fn (stmt, ctx->cb.dst_fn);

  scan_sharing_clauses (gimple_omp_teams_clauses (stmt), ctx);
  scan_omp (gimple_omp_body_ptr (stmt), ctx);

  if (TYPE_FIELDS (ctx->record_type) == NULL)
    ctx->record_type = ctx->receiver_decl = NULL;
}

/* Check nesting restrictions.  */
static bool
check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
{
  tree c;

  /* No nesting of non-OpenACC STMT (that is, an OpenMP one, or a GOMP builtin)
     inside an OpenACC CTX.  */
  if (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
      || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE)
    /* ..., except for the atomic codes that OpenACC shares with OpenMP.  */
    ;
  else if (!(is_gimple_omp (stmt)
	     && is_gimple_omp_oacc (stmt)))
    {
      if (oacc_get_fn_attrib (cfun->decl) != NULL)
	{
	  error_at (gimple_location (stmt),
		    "non-OpenACC construct inside of OpenACC routine");
	  return false;
	}
      else
	for (omp_context *octx = ctx; octx != NULL; octx = octx->outer)
	  if (is_gimple_omp (octx->stmt)
	      && is_gimple_omp_oacc (octx->stmt))
	    {
	      error_at (gimple_location (stmt),
			"non-OpenACC construct inside of OpenACC region");
	      return false;
	    }
    }

  if (ctx != NULL)
    {
      if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
	  && gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_REGION)
	{
	  c = omp_find_clause (gimple_omp_target_clauses (ctx->stmt),
			       OMP_CLAUSE_DEVICE);
	  if (c && OMP_CLAUSE_DEVICE_ANCESTOR (c))
	    {
	      error_at (gimple_location (stmt),
			"OpenMP constructs are not allowed in target region "
			"with %<ancestor%>");
	      return false;
	    }

	  if (gimple_code (stmt) == GIMPLE_OMP_TEAMS && !ctx->teams_nested_p)
	    ctx->teams_nested_p = true;
	  else
	    ctx->nonteams_nested_p = true;
	}
      if (gimple_code (ctx->stmt) == GIMPLE_OMP_SCAN
	  && ctx->outer
	  && gimple_code (ctx->outer->stmt) == GIMPLE_OMP_FOR)
	ctx = ctx->outer;
      if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
	  && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
	  && !ctx->loop_p)
	{
	  c = NULL_TREE;
	  if (ctx->order_concurrent
	      && (gimple_code (stmt) == GIMPLE_OMP_ORDERED
		  || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
		  || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE))
	    {
	      error_at (gimple_location (stmt),
			"OpenMP constructs other than %<parallel%>, %<loop%>"
			" or %<simd%> may not be nested inside a region with"
			" the %<order(concurrent)%> clause");
	      return false;
	    }
	  if (gimple_code (stmt) == GIMPLE_OMP_ORDERED)
	    {
	      c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
	      if (omp_find_clause (c, OMP_CLAUSE_SIMD))
		{
		  if (omp_find_clause (c, OMP_CLAUSE_THREADS)
		      && (ctx->outer == NULL
			  || !gimple_omp_for_combined_into_p (ctx->stmt)
			  || gimple_code (ctx->outer->stmt) != GIMPLE_OMP_FOR
			  || (gimple_omp_for_kind (ctx->outer->stmt)
			      != GF_OMP_FOR_KIND_FOR)
			  || !gimple_omp_for_combined_p (ctx->outer->stmt)))
		    {
		      error_at (gimple_location (stmt),
				"%<ordered simd threads%> must be closely "
				"nested inside of %<%s simd%> region",
				lang_GNU_Fortran () ? "do" : "for");
		      return false;
		    }
		  return true;
		}
	    }
	  else if (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
		   || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE
		   || gimple_code (stmt) == GIMPLE_OMP_SCAN)
	    return true;
	  else if (gimple_code (stmt) == GIMPLE_OMP_FOR
		   && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
	    return true;
	  error_at (gimple_location (stmt),
		    "OpenMP constructs other than "
		    "%<ordered simd%>, %<simd%>, %<loop%> or %<atomic%> may "
		    "not be nested inside %<simd%> region");
	  return false;
	}
      else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
	{
	  if ((gimple_code (stmt) != GIMPLE_OMP_FOR
	       || (gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_DISTRIBUTE
		   && omp_find_clause (gimple_omp_for_clauses (stmt),
				       OMP_CLAUSE_BIND) == NULL_TREE))
	      && gimple_code (stmt) != GIMPLE_OMP_PARALLEL)
	    {
	      error_at (gimple_location (stmt),
			"only %<distribute%>, %<parallel%> or %<loop%> "
			"regions are allowed to be strictly nested inside "
			"%<teams%> region");
	      return false;
	    }
	}
      else if (ctx->order_concurrent
	       && gimple_code (stmt) != GIMPLE_OMP_PARALLEL
	       && (gimple_code (stmt) != GIMPLE_OMP_FOR
		   || gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_SIMD)
	       && gimple_code (stmt) != GIMPLE_OMP_SCAN)
	{
	  if (ctx->loop_p)
	    error_at (gimple_location (stmt),
		      "OpenMP constructs other than %<parallel%>, %<loop%> or "
		      "%<simd%> may not be nested inside a %<loop%> region");
	  else
	    error_at (gimple_location (stmt),
		      "OpenMP constructs other than %<parallel%>, %<loop%> or "
		      "%<simd%> may not be nested inside a region with "
		      "the %<order(concurrent)%> clause");
	  return false;
	}
    }
  switch (gimple_code (stmt))
    {
    case GIMPLE_OMP_FOR:
      if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD)
	return true;
      if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
	{
	  if (ctx != NULL && gimple_code (ctx->stmt) != GIMPLE_OMP_TEAMS)
	    {
	      error_at (gimple_location (stmt),
			"%<distribute%> region must be strictly nested "
			"inside %<teams%> construct");
	      return false;
	    }
	  return true;
	}
      /* We split taskloop into task and nested taskloop in it.  */
      if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_TASKLOOP)
	return true;
      /* For now, hope this will change and loop bind(parallel) will not
	 be allowed in lots of contexts.  */
      if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR
	  && omp_find_clause (gimple_omp_for_clauses (stmt), OMP_CLAUSE_BIND))
	return true;
      if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
	{
	  bool ok = false;

	  if (ctx)
	    switch (gimple_code (ctx->stmt))
	      {
	      case GIMPLE_OMP_FOR:
		ok = (gimple_omp_for_kind (ctx->stmt)
		      == GF_OMP_FOR_KIND_OACC_LOOP);
		break;

	      case GIMPLE_OMP_TARGET:
		switch (gimple_omp_target_kind (ctx->stmt))
		  {
		  case GF_OMP_TARGET_KIND_OACC_PARALLEL:
		  case GF_OMP_TARGET_KIND_OACC_KERNELS:
		  case GF_OMP_TARGET_KIND_OACC_SERIAL:
		  case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
		  case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
		    ok = true;
		    break;

		  default:
		    break;
		  }

	      default:
		break;
	      }
	  else if (oacc_get_fn_attrib (current_function_decl))
	    ok = true;
	  if (!ok)
	    {
	      error_at (gimple_location (stmt),
			"OpenACC loop directive must be associated with"
			" an OpenACC compute region");
	      return false;
	    }
	}
      /* FALLTHRU */
    case GIMPLE_CALL:
      if (is_gimple_call (stmt)
	  && (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
	      == BUILT_IN_GOMP_CANCEL
	      || DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
		 == BUILT_IN_GOMP_CANCELLATION_POINT))
	{
	  const char *bad = NULL;
	  const char *kind = NULL;
	  const char *construct
	    = (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
	       == BUILT_IN_GOMP_CANCEL)
	      ? "cancel"
	      : "cancellation point";
	  if (ctx == NULL)
	    {
	      error_at (gimple_location (stmt), "orphaned %qs construct",
			construct);
	      return false;
	    }
	  switch (tree_fits_shwi_p (gimple_call_arg (stmt, 0))
		  ? tree_to_shwi (gimple_call_arg (stmt, 0))
		  : 0)
	    {
	    case 1:
	      if (gimple_code (ctx->stmt) != GIMPLE_OMP_PARALLEL)
		bad = "parallel";
	      else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
		       == BUILT_IN_GOMP_CANCEL
		       && !integer_zerop (gimple_call_arg (stmt, 1)))
		ctx->cancellable = true;
	      kind = "parallel";
	      break;
	    case 2:
	      if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
		  || gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR)
		bad = "for";
	      else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
		       == BUILT_IN_GOMP_CANCEL
		       && !integer_zerop (gimple_call_arg (stmt, 1)))
		{
		  ctx->cancellable = true;
		  if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
				       OMP_CLAUSE_NOWAIT))
		    warning_at (gimple_location (stmt), 0,
				"%<cancel for%> inside "
				"%<nowait%> for construct");
		  if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
				       OMP_CLAUSE_ORDERED))
		    warning_at (gimple_location (stmt), 0,
				"%<cancel for%> inside "
				"%<ordered%> for construct");
		}
	      kind = "for";
	      break;
	    case 4:
	      if (gimple_code (ctx->stmt) != GIMPLE_OMP_SECTIONS
		  && gimple_code (ctx->stmt) != GIMPLE_OMP_SECTION)
		bad = "sections";
	      else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
		       == BUILT_IN_GOMP_CANCEL
		       && !integer_zerop (gimple_call_arg (stmt, 1)))
		{
		  if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
		    {
		      ctx->cancellable = true;
		      if (omp_find_clause (gimple_omp_sections_clauses
								(ctx->stmt),
					   OMP_CLAUSE_NOWAIT))
			warning_at (gimple_location (stmt), 0,
				    "%<cancel sections%> inside "
				    "%<nowait%> sections construct");
		    }
		  else
		    {
		      gcc_assert (ctx->outer
				  && gimple_code (ctx->outer->stmt)
				     == GIMPLE_OMP_SECTIONS);
		      ctx->outer->cancellable = true;
		      if (omp_find_clause (gimple_omp_sections_clauses
							(ctx->outer->stmt),
					   OMP_CLAUSE_NOWAIT))
			warning_at (gimple_location (stmt), 0,
				    "%<cancel sections%> inside "
				    "%<nowait%> sections construct");
		    }
		}
	      kind = "sections";
	      break;
	    case 8:
	      if (!is_task_ctx (ctx)
		  && (!is_taskloop_ctx (ctx)
		      || ctx->outer == NULL
		      || !is_task_ctx (ctx->outer)))
		bad = "task";
	      else
		{
		  for (omp_context *octx = ctx->outer;
		       octx; octx = octx->outer)
		    {
		      switch (gimple_code (octx->stmt))
			{
			case GIMPLE_OMP_TASKGROUP:
			  break;
			case GIMPLE_OMP_TARGET:
			  if (gimple_omp_target_kind (octx->stmt)
			      != GF_OMP_TARGET_KIND_REGION)
			    continue;
			  /* FALLTHRU */
			case GIMPLE_OMP_PARALLEL:
			case GIMPLE_OMP_TEAMS:
			  error_at (gimple_location (stmt),
				    "%<%s taskgroup%> construct not closely "
				    "nested inside of %<taskgroup%> region",
				    construct);
			  return false;
			case GIMPLE_OMP_TASK:
			  if (gimple_omp_task_taskloop_p (octx->stmt)
			      && octx->outer
			      && is_taskloop_ctx (octx->outer))
			    {
			      tree clauses
				= gimple_omp_for_clauses (octx->outer->stmt);
			      if (!omp_find_clause (clauses, OMP_CLAUSE_NOGROUP))
				break;
			    }
			  continue;
			default:
			  continue;
			}
		      break;
		    }
		  ctx->cancellable = true;
		}
	      kind = "taskgroup";
	      break;
	    default:
	      error_at (gimple_location (stmt), "invalid arguments");
	      return false;
	    }
	  if (bad)
	    {
	      error_at (gimple_location (stmt),
			"%<%s %s%> construct not closely nested inside of %qs",
			construct, kind, bad);
	      return false;
	    }
	}
      /* FALLTHRU */
    case GIMPLE_OMP_SECTIONS:
    case GIMPLE_OMP_SINGLE:
      for (; ctx != NULL; ctx = ctx->outer)
	switch (gimple_code (ctx->stmt))
	  {
	  case GIMPLE_OMP_FOR:
	    if (gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR
		&& gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
	      break;
	    /* FALLTHRU */
	  case GIMPLE_OMP_SECTIONS:
	  case GIMPLE_OMP_SINGLE:
	  case GIMPLE_OMP_ORDERED:
	  case GIMPLE_OMP_MASTER:
	  case GIMPLE_OMP_MASKED:
	  case GIMPLE_OMP_TASK:
	  case GIMPLE_OMP_CRITICAL:
	    if (is_gimple_call (stmt))
	      {
		if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
		    != BUILT_IN_GOMP_BARRIER)
		  return true;
		error_at (gimple_location (stmt),
			  "barrier region may not be closely nested inside "
			  "of work-sharing, %<loop%>, %<critical%>, "
			  "%<ordered%>, %<master%>, %<masked%>, explicit "
			  "%<task%> or %<taskloop%> region");
		return false;
	      }
	    error_at (gimple_location (stmt),
		      "work-sharing region may not be closely nested inside "
		      "of work-sharing, %<loop%>, %<critical%>, %<ordered%>, "
		      "%<master%>, %<masked%>, explicit %<task%> or "
		      "%<taskloop%> region");
	    return false;
	  case GIMPLE_OMP_PARALLEL:
	  case GIMPLE_OMP_TEAMS:
	    return true;
	  case GIMPLE_OMP_TARGET:
	    if (gimple_omp_target_kind (ctx->stmt)
		== GF_OMP_TARGET_KIND_REGION)
	      return true;
	    break;
	  default:
	    break;
	  }
      break;
    case GIMPLE_OMP_MASTER:
    case GIMPLE_OMP_MASKED:
      for (; ctx != NULL; ctx = ctx->outer)
	switch (gimple_code (ctx->stmt))
	  {
	  case GIMPLE_OMP_FOR:
	    if (gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR
		&& gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
	      break;
	    /* FALLTHRU */
	  case GIMPLE_OMP_SECTIONS:
	  case GIMPLE_OMP_SINGLE:
	  case GIMPLE_OMP_TASK:
	    error_at (gimple_location (stmt),
		      "%qs region may not be closely nested inside "
		      "of work-sharing, %<loop%>, explicit %<task%> or "
		      "%<taskloop%> region",
		      gimple_code (stmt) == GIMPLE_OMP_MASTER
		      ? "master" : "masked");
	    return false;
	  case GIMPLE_OMP_PARALLEL:
	  case GIMPLE_OMP_TEAMS:
	    return true;
	  case GIMPLE_OMP_TARGET:
	    if (gimple_omp_target_kind (ctx->stmt)
		== GF_OMP_TARGET_KIND_REGION)
	      return true;
	    break;
	  default:
	    break;
	  }
      break;
    case GIMPLE_OMP_SCOPE:
      for (; ctx != NULL; ctx = ctx->outer)
	switch (gimple_code (ctx->stmt))
	  {
	  case GIMPLE_OMP_FOR:
	    if (gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR
		&& gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
	      break;
	    /* FALLTHRU */
	  case GIMPLE_OMP_SECTIONS:
	  case GIMPLE_OMP_SINGLE:
	  case GIMPLE_OMP_TASK:
	  case GIMPLE_OMP_CRITICAL:
	  case GIMPLE_OMP_ORDERED:
	  case GIMPLE_OMP_MASTER:
	  case GIMPLE_OMP_MASKED:
	    error_at (gimple_location (stmt),
		      "%<scope%> region may not be closely nested inside "
		      "of work-sharing, %<loop%>, explicit %<task%>, "
		      "%<taskloop%>, %<critical%>, %<ordered%>, %<master%>, "
		      "or %<masked%> region");
	    return false;
	  case GIMPLE_OMP_PARALLEL:
	  case GIMPLE_OMP_TEAMS:
	    return true;
	  case GIMPLE_OMP_TARGET:
	    if (gimple_omp_target_kind (ctx->stmt)
		== GF_OMP_TARGET_KIND_REGION)
	      return true;
	    break;
	  default:
	    break;
	  }
      break;
    case GIMPLE_OMP_TASK:
      for (c = gimple_omp_task_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
	    && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE
		|| OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK))
	  {
	    enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_KIND (c);
	    error_at (OMP_CLAUSE_LOCATION (c),
		      "%<depend(%s)%> is only allowed in %<omp ordered%>",
		      kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
	    return false;
	  }
      break;
    case GIMPLE_OMP_ORDERED:
      for (c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
	   c; c = OMP_CLAUSE_CHAIN (c))
	{
	  if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
	    {
	      gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREADS
			  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SIMD);
	      continue;
	    }
	  enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_KIND (c);
	  if (kind == OMP_CLAUSE_DEPEND_SOURCE
	      || kind == OMP_CLAUSE_DEPEND_SINK)
	    {
	      tree oclause;
	      /* Look for containing ordered(N) loop.  */
	      if (ctx == NULL
		  || gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
		  || (oclause
			= omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
					   OMP_CLAUSE_ORDERED)) == NULL_TREE)
		{
		  error_at (OMP_CLAUSE_LOCATION (c),
			    "%<ordered%> construct with %<depend%> clause "
			    "must be closely nested inside an %<ordered%> "
			    "loop");
		  return false;
		}
	      else if (OMP_CLAUSE_ORDERED_EXPR (oclause) == NULL_TREE)
		{
		  error_at (OMP_CLAUSE_LOCATION (c),
			    "%<ordered%> construct with %<depend%> clause "
			    "must be closely nested inside a loop with "
			    "%<ordered%> clause with a parameter");
		  return false;
		}
	    }
	  else
	    {
	      error_at (OMP_CLAUSE_LOCATION (c),
			"invalid depend kind in omp %<ordered%> %<depend%>");
	      return false;
	    }
	}
      c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
      if (omp_find_clause (c, OMP_CLAUSE_SIMD))
	{
	  /* ordered simd must be closely nested inside of simd region,
	     and simd region must not encounter constructs other than
	     ordered simd, therefore ordered simd may be either orphaned,
	     or ctx->stmt must be simd.  The latter case is handled already
	     earlier.  */
	  if (ctx != NULL)
	    {
	      error_at (gimple_location (stmt),
			"%<ordered%> %<simd%> must be closely nested inside "
			"%<simd%> region");
	      return false;
	    }
	}
      for (; ctx != NULL; ctx = ctx->outer)
	switch (gimple_code (ctx->stmt))
	  {
	  case GIMPLE_OMP_CRITICAL:
	  case GIMPLE_OMP_TASK:
	  case GIMPLE_OMP_ORDERED:
	  ordered_in_taskloop:
	    error_at (gimple_location (stmt),
		      "%<ordered%> region may not be closely nested inside "
		      "of %<critical%>, %<ordered%>, explicit %<task%> or "
		      "%<taskloop%> region");
	    return false;
	  case GIMPLE_OMP_FOR:
	    if (gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_TASKLOOP)
	      goto ordered_in_taskloop;
	    tree o;
	    o = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
				 OMP_CLAUSE_ORDERED);
	    if (o == NULL)
	      {
		error_at (gimple_location (stmt),
			  "%<ordered%> region must be closely nested inside "
			  "a loop region with an %<ordered%> clause");
		return false;
	      }
	    if (OMP_CLAUSE_ORDERED_EXPR (o) != NULL_TREE
		&& omp_find_clause (c, OMP_CLAUSE_DEPEND) == NULL_TREE)
	      {
		error_at (gimple_location (stmt),
			  "%<ordered%> region without %<depend%> clause may "
			  "not be closely nested inside a loop region with "
			  "an %<ordered%> clause with a parameter");
		return false;
	      }
	    return true;
	  case GIMPLE_OMP_TARGET:
	    if (gimple_omp_target_kind (ctx->stmt)
		!= GF_OMP_TARGET_KIND_REGION)
	      break;
	    /* FALLTHRU */
	  case GIMPLE_OMP_PARALLEL:
	  case GIMPLE_OMP_TEAMS:
	    error_at (gimple_location (stmt),
		      "%<ordered%> region must be closely nested inside "
		      "a loop region with an %<ordered%> clause");
	    return false;
	  default:
	    break;
	  }
      break;
    case GIMPLE_OMP_CRITICAL:
      {
	tree this_stmt_name
	  = gimple_omp_critical_name (as_a <gomp_critical *> (stmt));
	for (; ctx != NULL; ctx = ctx->outer)
	  if (gomp_critical *other_crit
	        = dyn_cast <gomp_critical *> (ctx->stmt))
	    if (this_stmt_name == gimple_omp_critical_name (other_crit))
	      {
		error_at (gimple_location (stmt),
			  "%<critical%> region may not be nested inside "
			   "a %<critical%> region with the same name");
		return false;
	      }
      }
      break;
    case GIMPLE_OMP_TEAMS:
      if (ctx == NULL)
	break;
      else if (gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET
	       || (gimple_omp_target_kind (ctx->stmt)
		   != GF_OMP_TARGET_KIND_REGION))
	{
	  /* Teams construct can appear either strictly nested inside of
	     target construct with no intervening stmts, or can be encountered
	     only by initial task (so must not appear inside any OpenMP
	     construct.  */
	  error_at (gimple_location (stmt),
		    "%<teams%> construct must be closely nested inside of "
		    "%<target%> construct or not nested in any OpenMP "
		    "construct");
	  return false;
	}
      break;
    case GIMPLE_OMP_TARGET:
      for (c = gimple_omp_target_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
	    && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE
		|| OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK))
	  {
	    enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_KIND (c);
	    error_at (OMP_CLAUSE_LOCATION (c),
		      "%<depend(%s)%> is only allowed in %<omp ordered%>",
		      kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
	    return false;
	  }
      if (is_gimple_omp_offloaded (stmt)
	  && oacc_get_fn_attrib (cfun->decl) != NULL)
	{
	  error_at (gimple_location (stmt),
		    "OpenACC region inside of OpenACC routine, nested "
		    "parallelism not supported yet");
	  return false;
	}
      for (; ctx != NULL; ctx = ctx->outer)
	{
	  if (gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET)
	    {
	      if (is_gimple_omp (stmt)
		  && is_gimple_omp_oacc (stmt)
		  && is_gimple_omp (ctx->stmt))
		{
		  error_at (gimple_location (stmt),
			    "OpenACC construct inside of non-OpenACC region");
		  return false;
		}
	      continue;
	    }

	  const char *stmt_name, *ctx_stmt_name;
	  switch (gimple_omp_target_kind (stmt))
	    {
	    case GF_OMP_TARGET_KIND_REGION: stmt_name = "target"; break;
	    case GF_OMP_TARGET_KIND_DATA: stmt_name = "target data"; break;
	    case GF_OMP_TARGET_KIND_UPDATE: stmt_name = "target update"; break;
	    case GF_OMP_TARGET_KIND_ENTER_DATA:
	      stmt_name = "target enter data"; break;
	    case GF_OMP_TARGET_KIND_EXIT_DATA:
	      stmt_name = "target exit data"; break;
	    case GF_OMP_TARGET_KIND_OACC_PARALLEL: stmt_name = "parallel"; break;
	    case GF_OMP_TARGET_KIND_OACC_KERNELS: stmt_name = "kernels"; break;
	    case GF_OMP_TARGET_KIND_OACC_SERIAL: stmt_name = "serial"; break;
	    case GF_OMP_TARGET_KIND_OACC_DATA: stmt_name = "data"; break;
	    case GF_OMP_TARGET_KIND_OACC_UPDATE: stmt_name = "update"; break;
	    case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
	      stmt_name = "enter data"; break;
	    case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
	      stmt_name = "exit data"; break;
	    case GF_OMP_TARGET_KIND_OACC_DECLARE: stmt_name = "declare"; break;
	    case GF_OMP_TARGET_KIND_OACC_HOST_DATA: stmt_name = "host_data";
	      break;
	    case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
	    case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
	    case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
	      /* OpenACC 'kernels' decomposed parts.  */
	      stmt_name = "kernels"; break;
	    default: gcc_unreachable ();
	    }
	  switch (gimple_omp_target_kind (ctx->stmt))
	    {
	    case GF_OMP_TARGET_KIND_REGION: ctx_stmt_name = "target"; break;
	    case GF_OMP_TARGET_KIND_DATA: ctx_stmt_name = "target data"; break;
	    case GF_OMP_TARGET_KIND_OACC_PARALLEL:
	      ctx_stmt_name = "parallel"; break;
	    case GF_OMP_TARGET_KIND_OACC_KERNELS:
	      ctx_stmt_name = "kernels"; break;
	    case GF_OMP_TARGET_KIND_OACC_SERIAL:
	      ctx_stmt_name = "serial"; break;
	    case GF_OMP_TARGET_KIND_OACC_DATA: ctx_stmt_name = "data"; break;
	    case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
	      ctx_stmt_name = "host_data"; break;
	    case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
	    case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
	    case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
	      /* OpenACC 'kernels' decomposed parts.  */
	      ctx_stmt_name = "kernels"; break;
	    default: gcc_unreachable ();
	    }

	  /* OpenACC/OpenMP mismatch?  */
	  if (is_gimple_omp_oacc (stmt)
	      != is_gimple_omp_oacc (ctx->stmt))
	    {
	      error_at (gimple_location (stmt),
			"%s %qs construct inside of %s %qs region",
			(is_gimple_omp_oacc (stmt)
			 ? "OpenACC" : "OpenMP"), stmt_name,
			(is_gimple_omp_oacc (ctx->stmt)
			 ? "OpenACC" : "OpenMP"), ctx_stmt_name);
	      return false;
	    }
	  if (is_gimple_omp_offloaded (ctx->stmt))
	    {
	      /* No GIMPLE_OMP_TARGET inside offloaded OpenACC CTX.  */
	      if (is_gimple_omp_oacc (ctx->stmt))
		{
		  error_at (gimple_location (stmt),
			    "%qs construct inside of %qs region",
			    stmt_name, ctx_stmt_name);
		  return false;
		}
	      else
		{
		  warning_at (gimple_location (stmt), 0,
			      "%qs construct inside of %qs region",
			      stmt_name, ctx_stmt_name);
		}
	    }
	}
      break;
    default:
      break;
    }
  return true;
}


/* Helper function scan_omp.

   Callback for walk_tree or operators in walk_gimple_stmt used to
   scan for OMP directives in TP.  */

static tree
scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
{
  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
  omp_context *ctx = (omp_context *) wi->info;
  tree t = *tp;

  switch (TREE_CODE (t))
    {
    case VAR_DECL:
    case PARM_DECL:
    case LABEL_DECL:
    case RESULT_DECL:
      if (ctx)
	{
	  tree repl = remap_decl (t, &ctx->cb);
	  gcc_checking_assert (TREE_CODE (repl) != ERROR_MARK);
	  *tp = repl;
	}
      break;

    default:
      if (ctx && TYPE_P (t))
	*tp = remap_type (t, &ctx->cb);
      else if (!DECL_P (t))
	{
	  *walk_subtrees = 1;
	  if (ctx)
	    {
	      tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
	      if (tem != TREE_TYPE (t))
		{
		  if (TREE_CODE (t) == INTEGER_CST)
		    *tp = wide_int_to_tree (tem, wi::to_wide (t));
		  else
		    TREE_TYPE (t) = tem;
		}
	    }
	}
      break;
    }

  return NULL_TREE;
}

/* Return true if FNDECL is a setjmp or a longjmp.  */

static bool
setjmp_or_longjmp_p (const_tree fndecl)
{
  if (fndecl_built_in_p (fndecl, BUILT_IN_SETJMP)
      || fndecl_built_in_p (fndecl, BUILT_IN_LONGJMP))
    return true;

  tree declname = DECL_NAME (fndecl);
  if (!declname
      || (DECL_CONTEXT (fndecl) != NULL_TREE
          && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL)
      || !TREE_PUBLIC (fndecl))
    return false;

  const char *name = IDENTIFIER_POINTER (declname);
  return !strcmp (name, "setjmp") || !strcmp (name, "longjmp");
}

/* Return true if FNDECL is an omp_* runtime API call.  */

static bool
omp_runtime_api_call (const_tree fndecl)
{
  tree declname = DECL_NAME (fndecl);
  if (!declname
      || (DECL_CONTEXT (fndecl) != NULL_TREE
          && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL)
      || !TREE_PUBLIC (fndecl))
    return false;

  const char *name = IDENTIFIER_POINTER (declname);
  if (!startswith (name, "omp_"))
    return false;

  static const char *omp_runtime_apis[] =
    {
      /* This array has 3 sections.  First omp_* calls that don't
	 have any suffixes.  */
      "aligned_alloc",
      "aligned_calloc",
      "alloc",
      "calloc",
      "free",
      "realloc",
      "target_alloc",
      "target_associate_ptr",
      "target_disassociate_ptr",
      "target_free",
      "target_is_present",
      "target_memcpy",
      "target_memcpy_rect",
      NULL,
      /* Now omp_* calls that are available as omp_* and omp_*_.  */
      "capture_affinity",
      "destroy_allocator",
      "destroy_lock",
      "destroy_nest_lock",
      "display_affinity",
      "fulfill_event",
      "get_active_level",
      "get_affinity_format",
      "get_cancellation",
      "get_default_allocator",
      "get_default_device",
      "get_device_num",
      "get_dynamic",
      "get_initial_device",
      "get_level",
      "get_max_active_levels",
      "get_max_task_priority",
      "get_max_teams",
      "get_max_threads",
      "get_nested",
      "get_num_devices",
      "get_num_places",
      "get_num_procs",
      "get_num_teams",
      "get_num_threads",
      "get_partition_num_places",
      "get_place_num",
      "get_proc_bind",
      "get_supported_active_levels",
      "get_team_num",
      "get_teams_thread_limit",
      "get_thread_limit",
      "get_thread_num",
      "get_wtick",
      "get_wtime",
      "in_final",
      "in_parallel",
      "init_lock",
      "init_nest_lock",
      "is_initial_device",
      "pause_resource",
      "pause_resource_all",
      "set_affinity_format",
      "set_default_allocator",
      "set_lock",
      "set_nest_lock",
      "test_lock",
      "test_nest_lock",
      "unset_lock",
      "unset_nest_lock",
      NULL,
      /* And finally calls available as omp_*, omp_*_ and omp_*_8_.  */
      "display_env",
      "get_ancestor_thread_num",
      "init_allocator",
      "get_partition_place_nums",
      "get_place_num_procs",
      "get_place_proc_ids",
      "get_schedule",
      "get_team_size",
      "set_default_device",
      "set_dynamic",
      "set_max_active_levels",
      "set_nested",
      "set_num_teams",
      "set_num_threads",
      "set_schedule",
      "set_teams_thread_limit"
    };

  int mode = 0;
  for (unsigned i = 0; i < ARRAY_SIZE (omp_runtime_apis); i++)
    {
      if (omp_runtime_apis[i] == NULL)
	{
	  mode++;
	  continue;
	}
      size_t len = strlen (omp_runtime_apis[i]);
      if (strncmp (name + 4, omp_runtime_apis[i], len) == 0
	  && (name[4 + len] == '\0'
	      || (mode > 0
		  && name[4 + len] == '_'
		  && (name[4 + len + 1] == '\0'
		      || (mode > 1
			  && strcmp (name + 4 + len + 1, "8_") == 0)))))
	return true;
    }
  return false;
}

/* Helper function for scan_omp.

   Callback for walk_gimple_stmt used to scan for OMP directives in
   the current statement in GSI.  */

static tree
scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
		 struct walk_stmt_info *wi)
{
  gimple *stmt = gsi_stmt (*gsi);
  omp_context *ctx = (omp_context *) wi->info;

  if (gimple_has_location (stmt))
    input_location = gimple_location (stmt);

  /* Check the nesting restrictions.  */
  bool remove = false;
  if (is_gimple_omp (stmt))
    remove = !check_omp_nesting_restrictions (stmt, ctx);
  else if (is_gimple_call (stmt))
    {
      tree fndecl = gimple_call_fndecl (stmt);
      if (fndecl)
	{
	  if (ctx
	      && gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
	      && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
	      && setjmp_or_longjmp_p (fndecl)
	      && !ctx->loop_p)
	    {
	      remove = true;
	      error_at (gimple_location (stmt),
			"setjmp/longjmp inside %<simd%> construct");
	    }
	  else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
	    switch (DECL_FUNCTION_CODE (fndecl))
	      {
	      case BUILT_IN_GOMP_BARRIER:
	      case BUILT_IN_GOMP_CANCEL:
	      case BUILT_IN_GOMP_CANCELLATION_POINT:
	      case BUILT_IN_GOMP_TASKYIELD:
	      case BUILT_IN_GOMP_TASKWAIT:
	      case BUILT_IN_GOMP_TASKGROUP_START:
	      case BUILT_IN_GOMP_TASKGROUP_END:
		remove = !check_omp_nesting_restrictions (stmt, ctx);
		break;
	      default:
		break;
	      }
	  else if (ctx)
	    {
	      omp_context *octx = ctx;
	      if (gimple_code (ctx->stmt) == GIMPLE_OMP_SCAN && ctx->outer)
		octx = ctx->outer;
	      if (octx->order_concurrent && omp_runtime_api_call (fndecl))
		{
		  remove = true;
		  error_at (gimple_location (stmt),
			    "OpenMP runtime API call %qD in a region with "
			    "%<order(concurrent)%> clause", fndecl);
		}
	      if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
		  && (gimple_omp_target_kind (ctx->stmt)
		      == GF_OMP_TARGET_KIND_REGION))
		{
		  tree tgt_clauses = gimple_omp_target_clauses (ctx->stmt);
		  tree c = omp_find_clause (tgt_clauses, OMP_CLAUSE_DEVICE);
		  if (c && OMP_CLAUSE_DEVICE_ANCESTOR (c))
		    error_at (gimple_location (stmt),
			      "OpenMP runtime API call %qD in a region with "
			      "%<device(ancestor)%> clause", fndecl);
		}
	    }
	}
    }
  if (remove)
    {
      stmt = gimple_build_nop ();
      gsi_replace (gsi, stmt, false);
    }

  *handled_ops_p = true;

  switch (gimple_code (stmt))
    {
    case GIMPLE_OMP_PARALLEL:
      taskreg_nesting_level++;
      scan_omp_parallel (gsi, ctx);
      taskreg_nesting_level--;
      break;

    case GIMPLE_OMP_TASK:
      taskreg_nesting_level++;
      scan_omp_task (gsi, ctx);
      taskreg_nesting_level--;
      break;

    case GIMPLE_OMP_FOR:
      if ((gimple_omp_for_kind (as_a <gomp_for *> (stmt))
	   == GF_OMP_FOR_KIND_SIMD)
	  && gimple_omp_for_combined_into_p (stmt)
	  && gimple_code (ctx->stmt) != GIMPLE_OMP_SCAN)
	{
	  tree clauses = gimple_omp_for_clauses (as_a <gomp_for *> (stmt));
	  tree c = omp_find_clause (clauses, OMP_CLAUSE_REDUCTION);
	  if (c && OMP_CLAUSE_REDUCTION_INSCAN (c) && !seen_error ())
	    {
	      scan_omp_simd_scan (gsi, as_a <gomp_for *> (stmt), ctx);
	      break;
	    }
	}
      if ((gimple_omp_for_kind (as_a <gomp_for *> (stmt))
	   == GF_OMP_FOR_KIND_SIMD)
	  && omp_maybe_offloaded_ctx (ctx)
	  && omp_max_simt_vf ()
	  && gimple_omp_for_collapse (stmt) == 1)
	scan_omp_simd (gsi, as_a <gomp_for *> (stmt), ctx);
      else
	scan_omp_for (as_a <gomp_for *> (stmt), ctx);
      break;

    case GIMPLE_OMP_SCOPE:
      ctx = new_omp_context (stmt, ctx);
      scan_sharing_clauses (gimple_omp_scope_clauses (stmt), ctx);
      scan_omp (gimple_omp_body_ptr (stmt), ctx);
      break;

    case GIMPLE_OMP_SECTIONS:
      scan_omp_sections (as_a <gomp_sections *> (stmt), ctx);
      break;

    case GIMPLE_OMP_SINGLE:
      scan_omp_single (as_a <gomp_single *> (stmt), ctx);
      break;

    case GIMPLE_OMP_SCAN:
      if (tree clauses = gimple_omp_scan_clauses (as_a <gomp_scan *> (stmt)))
	{
	  if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_INCLUSIVE)
	    ctx->scan_inclusive = true;
	  else if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_EXCLUSIVE)
	    ctx->scan_exclusive = true;
	}
      /* FALLTHRU */
    case GIMPLE_OMP_SECTION:
    case GIMPLE_OMP_MASTER:
    case GIMPLE_OMP_ORDERED:
    case GIMPLE_OMP_CRITICAL:
      ctx = new_omp_context (stmt, ctx);
      scan_omp (gimple_omp_body_ptr (stmt), ctx);
      break;

    case GIMPLE_OMP_MASKED:
      ctx = new_omp_context (stmt, ctx);
      scan_sharing_clauses (gimple_omp_masked_clauses (stmt), ctx);
      scan_omp (gimple_omp_body_ptr (stmt), ctx);
      break;

    case GIMPLE_OMP_TASKGROUP:
      ctx = new_omp_context (stmt, ctx);
      scan_sharing_clauses (gimple_omp_taskgroup_clauses (stmt), ctx);
      scan_omp (gimple_omp_body_ptr (stmt), ctx);
      break;

    case GIMPLE_OMP_TARGET:
      if (is_gimple_omp_offloaded (stmt))
	{
	  taskreg_nesting_level++;
	  scan_omp_target (as_a <gomp_target *> (stmt), ctx);
	  taskreg_nesting_level--;
	}
      else
	scan_omp_target (as_a <gomp_target *> (stmt), ctx);
      break;

    case GIMPLE_OMP_TEAMS:
      if (gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
	{
	  taskreg_nesting_level++;
	  scan_omp_teams (as_a <gomp_teams *> (stmt), ctx);
	  taskreg_nesting_level--;
	}
      else
	scan_omp_teams (as_a <gomp_teams *> (stmt), ctx);
      break;

    case GIMPLE_BIND:
      {
	tree var;

	*handled_ops_p = false;
	if (ctx)
	  for (var = gimple_bind_vars (as_a <gbind *> (stmt));
	       var ;
	       var = DECL_CHAIN (var))
	    insert_decl_map (&ctx->cb, var, var);
      }
      break;
    default:
      *handled_ops_p = false;
      break;
    }

  return NULL_TREE;
}


/* Scan all the statements starting at the current statement.  CTX
   contains context information about the OMP directives and
   clauses found during the scan.  */

static void
scan_omp (gimple_seq *body_p, omp_context *ctx)
{
  location_t saved_location;
  struct walk_stmt_info wi;

  memset (&wi, 0, sizeof (wi));
  wi.info = ctx;
  wi.want_locations = true;

  saved_location = input_location;
  walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
  input_location = saved_location;
}

/* Re-gimplification and code generation routines.  */

/* Remove omp_member_access_dummy_var variables from gimple_bind_vars
   of BIND if in a method.  */

static void
maybe_remove_omp_member_access_dummy_vars (gbind *bind)
{
  if (DECL_ARGUMENTS (current_function_decl)
      && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl))
      && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl)))
	  == POINTER_TYPE))
    {
      tree vars = gimple_bind_vars (bind);
      for (tree *pvar = &vars; *pvar; )
	if (omp_member_access_dummy_var (*pvar))
	  *pvar = DECL_CHAIN (*pvar);
	else
	  pvar = &DECL_CHAIN (*pvar);
      gimple_bind_set_vars (bind, vars);
    }
}

/* Remove omp_member_access_dummy_var variables from BLOCK_VARS of
   block and its subblocks.  */

static void
remove_member_access_dummy_vars (tree block)
{
  for (tree *pvar = &BLOCK_VARS (block); *pvar; )
    if (omp_member_access_dummy_var (*pvar))
      *pvar = DECL_CHAIN (*pvar);
    else
      pvar = &DECL_CHAIN (*pvar);

  for (block = BLOCK_SUBBLOCKS (block); block; block = BLOCK_CHAIN (block))
    remove_member_access_dummy_vars (block);
}

/* If a context was created for STMT when it was scanned, return it.  */

static omp_context *
maybe_lookup_ctx (gimple *stmt)
{
  splay_tree_node n;
  n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
  return n ? (omp_context *) n->value : NULL;
}


/* Find the mapping for DECL in CTX or the immediately enclosing
   context that has a mapping for DECL.

   If CTX is a nested parallel directive, we may have to use the decl
   mappings created in CTX's parent context.  Suppose that we have the
   following parallel nesting (variable UIDs showed for clarity):

	iD.1562 = 0;
     	#omp parallel shared(iD.1562)		-> outer parallel
	  iD.1562 = iD.1562 + 1;

	  #omp parallel shared (iD.1562)	-> inner parallel
	     iD.1562 = iD.1562 - 1;

   Each parallel structure will create a distinct .omp_data_s structure
   for copying iD.1562 in/out of the directive:

  	outer parallel		.omp_data_s.1.i -> iD.1562
	inner parallel		.omp_data_s.2.i -> iD.1562

   A shared variable mapping will produce a copy-out operation before
   the parallel directive and a copy-in operation after it.  So, in
   this case we would have:

  	iD.1562 = 0;
	.omp_data_o.1.i = iD.1562;
	#omp parallel shared(iD.1562)		-> outer parallel
	  .omp_data_i.1 = &.omp_data_o.1
	  .omp_data_i.1->i = .omp_data_i.1->i + 1;

	  .omp_data_o.2.i = iD.1562;		-> **
	  #omp parallel shared(iD.1562)		-> inner parallel
	    .omp_data_i.2 = &.omp_data_o.2
	    .omp_data_i.2->i = .omp_data_i.2->i - 1;


    ** This is a problem.  The symbol iD.1562 cannot be referenced
       inside the body of the outer parallel region.  But since we are
       emitting this copy operation while expanding the inner parallel
       directive, we need to access the CTX structure of the outer
       parallel directive to get the correct mapping:

	  .omp_data_o.2.i = .omp_data_i.1->i

    Since there may be other workshare or parallel directives enclosing
    the parallel directive, it may be necessary to walk up the context
    parent chain.  This is not a problem in general because nested
    parallelism happens only rarely.  */

static tree
lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
{
  tree t;
  omp_context *up;

  for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
    t = maybe_lookup_decl (decl, up);

  gcc_assert (!ctx->is_nested || t || is_global_var (decl));

  return t ? t : decl;
}


/* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
   in outer contexts.  */

static tree
maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
{
  tree t = NULL;
  omp_context *up;

  for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
    t = maybe_lookup_decl (decl, up);

  return t ? t : decl;
}


/* Construct the initialization value for reduction operation OP.  */

tree
omp_reduction_init_op (location_t loc, enum tree_code op, tree type)
{
  switch (op)
    {
    case PLUS_EXPR:
    case MINUS_EXPR:
    case BIT_IOR_EXPR:
    case BIT_XOR_EXPR:
    case TRUTH_OR_EXPR:
    case TRUTH_ORIF_EXPR:
    case TRUTH_XOR_EXPR:
    case NE_EXPR:
      return build_zero_cst (type);

    case MULT_EXPR:
    case TRUTH_AND_EXPR:
    case TRUTH_ANDIF_EXPR:
    case EQ_EXPR:
      return fold_convert_loc (loc, type, integer_one_node);

    case BIT_AND_EXPR:
      return fold_convert_loc (loc, type, integer_minus_one_node);

    case MAX_EXPR:
      if (SCALAR_FLOAT_TYPE_P (type))
	{
	  REAL_VALUE_TYPE max, min;
	  if (HONOR_INFINITIES (type))
	    {
	      real_inf (&max);
	      real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
	    }
	  else
	    real_maxval (&min, 1, TYPE_MODE (type));
	  return build_real (type, min);
	}
      else if (POINTER_TYPE_P (type))
	{
	  wide_int min
	    = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
	  return wide_int_to_tree (type, min);
	}
      else
	{
	  gcc_assert (INTEGRAL_TYPE_P (type));
	  return TYPE_MIN_VALUE (type);
	}

    case MIN_EXPR:
      if (SCALAR_FLOAT_TYPE_P (type))
	{
	  REAL_VALUE_TYPE max;
	  if (HONOR_INFINITIES (type))
	    real_inf (&max);
	  else
	    real_maxval (&max, 0, TYPE_MODE (type));
	  return build_real (type, max);
	}
      else if (POINTER_TYPE_P (type))
	{
	  wide_int max
	    = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
	  return wide_int_to_tree (type, max);
	}
      else
	{
	  gcc_assert (INTEGRAL_TYPE_P (type));
	  return TYPE_MAX_VALUE (type);
	}

    default:
      gcc_unreachable ();
    }
}

/* Construct the initialization value for reduction CLAUSE.  */

tree
omp_reduction_init (tree clause, tree type)
{
  return omp_reduction_init_op (OMP_CLAUSE_LOCATION (clause),
				OMP_CLAUSE_REDUCTION_CODE (clause), type);
}

/* Return alignment to be assumed for var in CLAUSE, which should be
   OMP_CLAUSE_ALIGNED.  */

static tree
omp_clause_aligned_alignment (tree clause)
{
  if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
    return OMP_CLAUSE_ALIGNED_ALIGNMENT (clause);

  /* Otherwise return implementation defined alignment.  */
  unsigned int al = 1;
  opt_scalar_mode mode_iter;
  auto_vector_modes modes;
  targetm.vectorize.autovectorize_vector_modes (&modes, true);
  static enum mode_class classes[]
    = { MODE_INT, MODE_VECTOR_INT, MODE_FLOAT, MODE_VECTOR_FLOAT };
  for (int i = 0; i < 4; i += 2)
    /* The for loop above dictates that we only walk through scalar classes.  */
    FOR_EACH_MODE_IN_CLASS (mode_iter, classes[i])
      {
	scalar_mode mode = mode_iter.require ();
	machine_mode vmode = targetm.vectorize.preferred_simd_mode (mode);
	if (GET_MODE_CLASS (vmode) != classes[i + 1])
	  continue;
	machine_mode alt_vmode;
	for (unsigned int j = 0; j < modes.length (); ++j)
	  if (related_vector_mode (modes[j], mode).exists (&alt_vmode)
	      && known_ge (GET_MODE_SIZE (alt_vmode), GET_MODE_SIZE (vmode)))
	    vmode = alt_vmode;

	tree type = lang_hooks.types.type_for_mode (mode, 1);
	if (type == NULL_TREE || TYPE_MODE (type) != mode)
	  continue;
	type = build_vector_type_for_mode (type, vmode);
	if (TYPE_MODE (type) != vmode)
	  continue;
	if (TYPE_ALIGN_UNIT (type) > al)
	  al = TYPE_ALIGN_UNIT (type);
      }
  return build_int_cst (integer_type_node, al);
}


/* This structure is part of the interface between lower_rec_simd_input_clauses
   and lower_rec_input_clauses.  */

class omplow_simd_context {
public:
  omplow_simd_context () { memset (this, 0, sizeof (*this)); }
  tree idx;
  tree lane;
  tree lastlane;
  vec<tree, va_heap> simt_eargs;
  gimple_seq simt_dlist;
  poly_uint64_pod max_vf;
  bool is_simt;
};

/* Helper function of lower_rec_input_clauses, used for #pragma omp simd
   privatization.  */

static bool
lower_rec_simd_input_clauses (tree new_var, omp_context *ctx,
			      omplow_simd_context *sctx, tree &ivar,
			      tree &lvar, tree *rvar = NULL,
			      tree *rvar2 = NULL)
{
  if (known_eq (sctx->max_vf, 0U))
    {
      sctx->max_vf = sctx->is_simt ? omp_max_simt_vf () : omp_max_vf ();
      if (maybe_gt (sctx->max_vf, 1U))
	{
	  tree c = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
				    OMP_CLAUSE_SAFELEN);
	  if (c)
	    {
	      poly_uint64 safe_len;
	      if (!poly_int_tree_p (OMP_CLAUSE_SAFELEN_EXPR (c), &safe_len)
		  || maybe_lt (safe_len, 1U))
		sctx->max_vf = 1;
	      else
		sctx->max_vf = lower_bound (sctx->max_vf, safe_len);
	    }
	}
      if (sctx->is_simt && !known_eq (sctx->max_vf, 1U))
	{
	  for (tree c = gimple_omp_for_clauses (ctx->stmt); c;
	       c = OMP_CLAUSE_CHAIN (c))
	    {
	      if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
		continue;

	      if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
		{
		  /* UDR reductions are not supported yet for SIMT, disable
		     SIMT.  */
		  sctx->max_vf = 1;
		  break;
		}

	      if (truth_value_p (OMP_CLAUSE_REDUCTION_CODE (c))
		  && !INTEGRAL_TYPE_P (TREE_TYPE (new_var)))
		{
		  /* Doing boolean operations on non-integral types is
		     for conformance only, it's not worth supporting this
		     for SIMT.  */
		  sctx->max_vf = 1;
		  break;
	      }
	    }
	}
      if (maybe_gt (sctx->max_vf, 1U))
	{
	  sctx->idx = create_tmp_var (unsigned_type_node);
	  sctx->lane = create_tmp_var (unsigned_type_node);
	}
    }
  if (known_eq (sctx->max_vf, 1U))
    return false;

  if (sctx->is_simt)
    {
      if (is_gimple_reg (new_var))
	{
	  ivar = lvar = new_var;
	  return true;
	}
      tree type = TREE_TYPE (new_var), ptype = build_pointer_type (type);
      ivar = lvar = create_tmp_var (type);
      TREE_ADDRESSABLE (ivar) = 1;
      DECL_ATTRIBUTES (ivar) = tree_cons (get_identifier ("omp simt private"),
					  NULL, DECL_ATTRIBUTES (ivar));
      sctx->simt_eargs.safe_push (build1 (ADDR_EXPR, ptype, ivar));
      tree clobber = build_clobber (type);
      gimple *g = gimple_build_assign (ivar, clobber);
      gimple_seq_add_stmt (&sctx->simt_dlist, g);
    }
  else
    {
      tree atype = build_array_type_nelts (TREE_TYPE (new_var), sctx->max_vf);
      tree avar = create_tmp_var_raw (atype);
      if (TREE_ADDRESSABLE (new_var))
	TREE_ADDRESSABLE (avar) = 1;
      DECL_ATTRIBUTES (avar)
	= tree_cons (get_identifier ("omp simd array"), NULL,
		     DECL_ATTRIBUTES (avar));
      gimple_add_tmp_var (avar);
      tree iavar = avar;
      if (rvar && !ctx->for_simd_scan_phase)
	{
	  /* For inscan reductions, create another array temporary,
	     which will hold the reduced value.  */
	  iavar = create_tmp_var_raw (atype);
	  if (TREE_ADDRESSABLE (new_var))
	    TREE_ADDRESSABLE (iavar) = 1;
	  DECL_ATTRIBUTES (iavar)
	    = tree_cons (get_identifier ("omp simd array"), NULL,
			 tree_cons (get_identifier ("omp simd inscan"), NULL,
				    DECL_ATTRIBUTES (iavar)));
	  gimple_add_tmp_var (iavar);
	  ctx->cb.decl_map->put (avar, iavar);
	  if (sctx->lastlane == NULL_TREE)
	    sctx->lastlane = create_tmp_var (unsigned_type_node);
	  *rvar = build4 (ARRAY_REF, TREE_TYPE (new_var), iavar,
			  sctx->lastlane, NULL_TREE, NULL_TREE);
	  TREE_THIS_NOTRAP (*rvar) = 1;

	  if (ctx->scan_exclusive)
	    {
	      /* And for exclusive scan yet another one, which will
		 hold the value during the scan phase.  */
	      tree savar = create_tmp_var_raw (atype);
	      if (TREE_ADDRESSABLE (new_var))
		TREE_ADDRESSABLE (savar) = 1;
	      DECL_ATTRIBUTES (savar)
		= tree_cons (get_identifier ("omp simd array"), NULL,
			     tree_cons (get_identifier ("omp simd inscan "
							"exclusive"), NULL,
					DECL_ATTRIBUTES (savar)));
	      gimple_add_tmp_var (savar);
	      ctx->cb.decl_map->put (iavar, savar);
	      *rvar2 = build4 (ARRAY_REF, TREE_TYPE (new_var), savar,
			       sctx->idx, NULL_TREE, NULL_TREE);
	      TREE_THIS_NOTRAP (*rvar2) = 1;
	    }
	}
      ivar = build4 (ARRAY_REF, TREE_TYPE (new_var), iavar, sctx->idx,
		     NULL_TREE, NULL_TREE);
      lvar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, sctx->lane,
		     NULL_TREE, NULL_TREE);
      TREE_THIS_NOTRAP (ivar) = 1;
      TREE_THIS_NOTRAP (lvar) = 1;
    }
  if (DECL_P (new_var))
    {
      SET_DECL_VALUE_EXPR (new_var, lvar);
      DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    }
  return true;
}

/* Helper function of lower_rec_input_clauses.  For a reference
   in simd reduction, add an underlying variable it will reference.  */

static void
handle_simd_reference (location_t loc, tree new_vard, gimple_seq *ilist)
{
  tree z = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
  if (TREE_CONSTANT (z))
    {
      z = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_vard)),
			      get_name (new_vard));
      gimple_add_tmp_var (z);
      TREE_ADDRESSABLE (z) = 1;
      z = build_fold_addr_expr_loc (loc, z);
      gimplify_assign (new_vard, z, ilist);
    }
}

/* Helper function for lower_rec_input_clauses.  Emit into ilist sequence
   code to emit (type) (tskred_temp[idx]).  */

static tree
task_reduction_read (gimple_seq *ilist, tree tskred_temp, tree type,
		     unsigned idx)
{
  unsigned HOST_WIDE_INT sz
    = tree_to_uhwi (TYPE_SIZE_UNIT (pointer_sized_int_node));
  tree r = build2 (MEM_REF, pointer_sized_int_node,
		   tskred_temp, build_int_cst (TREE_TYPE (tskred_temp),
					       idx * sz));
  tree v = create_tmp_var (pointer_sized_int_node);
  gimple *g = gimple_build_assign (v, r);
  gimple_seq_add_stmt (ilist, g);
  if (!useless_type_conversion_p (type, pointer_sized_int_node))
    {
      v = create_tmp_var (type);
      g = gimple_build_assign (v, NOP_EXPR, gimple_assign_lhs (g));
      gimple_seq_add_stmt (ilist, g);
    }
  return v;
}

/* Lower early initialization of privatized variable NEW_VAR
   if it needs an allocator (has allocate clause).  */

static bool
lower_private_allocate (tree var, tree new_var, tree &allocator,
			tree &allocate_ptr, gimple_seq *ilist,
			omp_context *ctx, bool is_ref, tree size)
{
  if (allocator)
    return false;
  gcc_assert (allocate_ptr == NULL_TREE);
  if (ctx->allocate_map
      && (DECL_P (new_var) || (TYPE_P (new_var) && size)))
    if (tree *allocatorp = ctx->allocate_map->get (var))
      allocator = *allocatorp;
  if (allocator == NULL_TREE)
    return false;
  if (!is_ref && omp_privatize_by_reference (var))
    {
      allocator = NULL_TREE;
      return false;
    }

  unsigned HOST_WIDE_INT ialign = 0;
  if (TREE_CODE (allocator) == TREE_LIST)
    {
      ialign = tree_to_uhwi (TREE_VALUE (allocator));
      allocator = TREE_PURPOSE (allocator);
    }
  if (TREE_CODE (allocator) != INTEGER_CST)
    allocator = build_outer_var_ref (allocator, ctx);
  allocator = fold_convert (pointer_sized_int_node, allocator);
  if (TREE_CODE (allocator) != INTEGER_CST)
    {
      tree var = create_tmp_var (TREE_TYPE (allocator));
      gimplify_assign (var, allocator, ilist);
      allocator = var;
    }

  tree ptr_type, align, sz = size;
  if (TYPE_P (new_var))
    {
      ptr_type = build_pointer_type (new_var);
      ialign = MAX (ialign, TYPE_ALIGN_UNIT (new_var));
    }
  else if (is_ref)
    {
      ptr_type = build_pointer_type (TREE_TYPE (TREE_TYPE (new_var)));
      ialign = MAX (ialign, TYPE_ALIGN_UNIT (TREE_TYPE (ptr_type)));
    }
  else
    {
      ptr_type = build_pointer_type (TREE_TYPE (new_var));
      ialign = MAX (ialign, DECL_ALIGN_UNIT (new_var));
      if (sz == NULL_TREE)
	sz = fold_convert (size_type_node, DECL_SIZE_UNIT (new_var));
    }
  align = build_int_cst (size_type_node, ialign);
  if (TREE_CODE (sz) != INTEGER_CST)
    {
      tree szvar = create_tmp_var (size_type_node);
      gimplify_assign (szvar, sz, ilist);
      sz = szvar;
    }
  allocate_ptr = create_tmp_var (ptr_type);
  tree a = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
  gimple *g = gimple_build_call (a, 3, align, sz, allocator);
  gimple_call_set_lhs (g, allocate_ptr);
  gimple_seq_add_stmt (ilist, g);
  if (!is_ref)
    {
      tree x = build_simple_mem_ref (allocate_ptr);
      TREE_THIS_NOTRAP (x) = 1;
      SET_DECL_VALUE_EXPR (new_var, x);
      DECL_HAS_VALUE_EXPR_P (new_var) = 1;
    }
  return true;
}

/* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
   from the receiver (aka child) side and initializers for REFERENCE_TYPE
   private variables.  Initialization statements go in ILIST, while calls
   to destructors go in DLIST.  */

static void
lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
			 omp_context *ctx, struct omp_for_data *fd)
{
  tree c, copyin_seq, x, ptr;
  bool copyin_by_ref = false;
  bool lastprivate_firstprivate = false;
  bool reduction_omp_orig_ref = false;
  int pass;
  bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
		  && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD);
  omplow_simd_context sctx = omplow_simd_context ();
  tree simt_lane = NULL_TREE, simtrec = NULL_TREE;
  tree ivar = NULL_TREE, lvar = NULL_TREE, uid = NULL_TREE;
  gimple_seq llist[4] = { };
  tree nonconst_simd_if = NULL_TREE;

  copyin_seq = NULL;
  sctx.is_simt = is_simd && omp_find_clause (clauses, OMP_CLAUSE__SIMT_);

  /* Set max_vf=1 (which will later enforce safelen=1) in simd loops
     with data sharing clauses referencing variable sized vars.  That
     is unnecessarily hard to support and very unlikely to result in
     vectorized code anyway.  */
  if (is_simd)
    for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
      switch (OMP_CLAUSE_CODE (c))
	{
	case OMP_CLAUSE_LINEAR:
	  if (OMP_CLAUSE_LINEAR_ARRAY (c))
	    sctx.max_vf = 1;
	  /* FALLTHRU */
	case OMP_CLAUSE_PRIVATE:
	case OMP_CLAUSE_FIRSTPRIVATE:
	case OMP_CLAUSE_LASTPRIVATE:
	  if (is_variable_sized (OMP_CLAUSE_DECL (c)))
	    sctx.max_vf = 1;
	  else if (omp_privatize_by_reference (OMP_CLAUSE_DECL (c)))
	    {
	      tree rtype = TREE_TYPE (TREE_TYPE (OMP_CLAUSE_DECL (c)));
	      if (!TREE_CONSTANT (TYPE_SIZE_UNIT (rtype)))
		sctx.max_vf = 1;
	    }
	  break;
	case OMP_CLAUSE_REDUCTION:
	case OMP_CLAUSE_IN_REDUCTION:
	  if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
	      || is_variable_sized (OMP_CLAUSE_DECL (c)))
	    sctx.max_vf = 1;
	  else if (omp_privatize_by_reference (OMP_CLAUSE_DECL (c)))
	    {
	      tree rtype = TREE_TYPE (TREE_TYPE (OMP_CLAUSE_DECL (c)));
	      if (!TREE_CONSTANT (TYPE_SIZE_UNIT (rtype)))
		sctx.max_vf = 1;
	    }
	  break;
	case OMP_CLAUSE_IF:
	  if (integer_zerop (OMP_CLAUSE_IF_EXPR (c)))
	    sctx.max_vf = 1;
	  else if (TREE_CODE (OMP_CLAUSE_IF_EXPR (c)) != INTEGER_CST)
	    nonconst_simd_if = OMP_CLAUSE_IF_EXPR (c);
	  break;
        case OMP_CLAUSE_SIMDLEN:
	  if (integer_onep (OMP_CLAUSE_SIMDLEN_EXPR (c)))
	    sctx.max_vf = 1;
	  break;
	case OMP_CLAUSE__CONDTEMP_:
	  /* FIXME: lastprivate(conditional:) not handled for SIMT yet.  */
	  if (sctx.is_simt)
	    sctx.max_vf = 1;
	  break;
	default:
	  continue;
	}

  /* Add a placeholder for simduid.  */
  if (sctx.is_simt && maybe_ne (sctx.max_vf, 1U))
    sctx.simt_eargs.safe_push (NULL_TREE);

  unsigned task_reduction_cnt = 0;
  unsigned task_reduction_cntorig = 0;
  unsigned task_reduction_cnt_full = 0;
  unsigned task_reduction_cntorig_full = 0;
  unsigned task_reduction_other_cnt = 0;
  tree tskred_atype = NULL_TREE, tskred_avar = NULL_TREE;
  tree tskred_base = NULL_TREE, tskred_temp = NULL_TREE;
  /* Do all the fixed sized types in the first pass, and the variable sized
     types in the second pass.  This makes sure that the scalar arguments to
     the variable sized types are processed before we use them in the
     variable sized operations.  For task reductions we use 4 passes, in the
     first two we ignore them, in the third one gather arguments for
     GOMP_task_reduction_remap call and in the last pass actually handle
     the task reductions.  */
  for (pass = 0; pass < ((task_reduction_cnt || task_reduction_other_cnt)
			 ? 4 : 2); ++pass)
    {
      if (pass == 2 && task_reduction_cnt)
	{
	  tskred_atype
	    = build_array_type_nelts (ptr_type_node, task_reduction_cnt
						     + task_reduction_cntorig);
	  tskred_avar = create_tmp_var_raw (tskred_atype);
	  gimple_add_tmp_var (tskred_avar);
	  TREE_ADDRESSABLE (tskred_avar) = 1;
	  task_reduction_cnt_full = task_reduction_cnt;
	  task_reduction_cntorig_full = task_reduction_cntorig;
	}
      else if (pass == 3 && task_reduction_cnt)
	{
	  x = builtin_decl_explicit (BUILT_IN_GOMP_TASK_REDUCTION_REMAP);
	  gimple *g
	    = gimple_build_call (x, 3, size_int (task_reduction_cnt),
				 size_int (task_reduction_cntorig),
				 build_fold_addr_expr (tskred_avar));
	  gimple_seq_add_stmt (ilist, g);
	}
      if (pass == 3 && task_reduction_other_cnt)
	{
	  /* For reduction clauses, build
	     tskred_base = (void *) tskred_temp[2]
			   + omp_get_thread_num () * tskred_temp[1]
	     or if tskred_temp[1] is known to be constant, that constant
	     directly.  This is the start of the private reduction copy block
	     for the current thread.  */
	  tree v = create_tmp_var (integer_type_node);
	  x = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
	  gimple *g = gimple_build_call (x, 0);
	  gimple_call_set_lhs (g, v);
	  gimple_seq_add_stmt (ilist, g);
	  c = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
	  tskred_temp = OMP_CLAUSE_DECL (c);
	  if (is_taskreg_ctx (ctx))
	    tskred_temp = lookup_decl (tskred_temp, ctx);
	  tree v2 = create_tmp_var (sizetype);
	  g = gimple_build_assign (v2, NOP_EXPR, v);
	  gimple_seq_add_stmt (ilist, g);
	  if (ctx->task_reductions[0])
	    v = fold_convert (sizetype, ctx->task_reductions[0]);
	  else
	    v = task_reduction_read (ilist, tskred_temp, sizetype, 1);
	  tree v3 = create_tmp_var (sizetype);
	  g = gimple_build_assign (v3, MULT_EXPR, v2, v);
	  gimple_seq_add_stmt (ilist, g);
	  v = task_reduction_read (ilist, tskred_temp, ptr_type_node, 2);
	  tskred_base = create_tmp_var (ptr_type_node);
	  g = gimple_build_assign (tskred_base, POINTER_PLUS_EXPR, v, v3);
	  gimple_seq_add_stmt (ilist, g);
	}
      task_reduction_cnt = 0;
      task_reduction_cntorig = 0;
      task_reduction_other_cnt = 0;
      for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
	{
	  enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
	  tree var, new_var;
	  bool by_ref;
	  location_t clause_loc = OMP_CLAUSE_LOCATION (c);
	  bool task_reduction_p = false;
	  bool task_reduction_needs_orig_p = false;
	  tree cond = NULL_TREE;
	  tree allocator, allocate_ptr;

	  switch (c_kind)
	    {
	    case OMP_CLAUSE_PRIVATE:
	      if (OMP_CLAUSE_PRIVATE_DEBUG (c))
		continue;
	      break;
	    case OMP_CLAUSE_SHARED:
	      /* Ignore shared directives in teams construct inside
		 of target construct.  */
	      if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
		  && !is_host_teams_ctx (ctx))
		continue;
	      if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
		{
		  gcc_assert (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c)
			      || is_global_var (OMP_CLAUSE_DECL (c)));
		  continue;
		}
	    case OMP_CLAUSE_FIRSTPRIVATE:
	    case OMP_CLAUSE_COPYIN:
	      break;
	    case OMP_CLAUSE_LINEAR:
	      if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
		  && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
		lastprivate_firstprivate = true;
	      break;
	    case OMP_CLAUSE_REDUCTION:
	    case OMP_CLAUSE_IN_REDUCTION:
	      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
		  || is_task_ctx (ctx)
		  || OMP_CLAUSE_REDUCTION_TASK (c))
		{
		  task_reduction_p = true;
		  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
		    {
		      task_reduction_other_cnt++;
		      if (pass == 2)
			continue;
		    }
		  else
		    task_reduction_cnt++;
		  if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
		    {
		      var = OMP_CLAUSE_DECL (c);
		      /* If var is a global variable that isn't privatized
			 in outer contexts, we don't need to look up the
			 original address, it is always the address of the
			 global variable itself.  */
		      if (!DECL_P (var)
			  || omp_privatize_by_reference (var)
			  || !is_global_var
				(maybe_lookup_decl_in_outer_ctx (var, ctx)))
			{
			  task_reduction_needs_orig_p = true;
			  if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
			    task_reduction_cntorig++;
			}
		    }
		}
	      else if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
		reduction_omp_orig_ref = true;
	      break;
	    case OMP_CLAUSE__REDUCTEMP_:
	      if (!is_taskreg_ctx (ctx))
		continue;
	      /* FALLTHRU */
	    case OMP_CLAUSE__LOOPTEMP_:
	      /* Handle _looptemp_/_reductemp_ clauses only on
		 parallel/task.  */
	      if (fd)
		continue;
	      break;
	    case OMP_CLAUSE_LASTPRIVATE:
	      if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
		{
		  lastprivate_firstprivate = true;
		  if (pass != 0 || is_taskloop_ctx (ctx))
		    continue;
		}
	      /* Even without corresponding firstprivate, if
		 decl is Fortran allocatable, it needs outer var
		 reference.  */
	      else if (pass == 0
		       && lang_hooks.decls.omp_private_outer_ref
							(OMP_CLAUSE_DECL (c)))
		lastprivate_firstprivate = true;
	      break;
	    case OMP_CLAUSE_ALIGNED:
	      if (pass != 1)
		continue;
	      var = OMP_CLAUSE_DECL (c);
	      if (TREE_CODE (TREE_TYPE (var)) == POINTER_TYPE
		  && !is_global_var (var))
		{
		  new_var = maybe_lookup_decl (var, ctx);
		  if (new_var == NULL_TREE)
		    new_var = maybe_lookup_decl_in_outer_ctx (var, ctx);
		  x = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
		  tree alarg = omp_clause_aligned_alignment (c);
		  alarg = fold_convert_loc (clause_loc, size_type_node, alarg);
		  x = build_call_expr_loc (clause_loc, x, 2, new_var, alarg);
		  x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
		  x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
		  gimplify_and_add (x, ilist);
		}
	      else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
		       && is_global_var (var))
		{
		  tree ptype = build_pointer_type (TREE_TYPE (var)), t, t2;
		  new_var = lookup_decl (var, ctx);
		  t = maybe_lookup_decl_in_outer_ctx (var, ctx);
		  t = build_fold_addr_expr_loc (clause_loc, t);
		  t2 = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
		  tree alarg = omp_clause_aligned_alignment (c);
		  alarg = fold_convert_loc (clause_loc, size_type_node, alarg);
		  t = build_call_expr_loc (clause_loc, t2, 2, t, alarg);
		  t = fold_convert_loc (clause_loc, ptype, t);
		  x = create_tmp_var (ptype);
		  t = build2 (MODIFY_EXPR, ptype, x, t);
		  gimplify_and_add (t, ilist);
		  t = build_simple_mem_ref_loc (clause_loc, x);
		  SET_DECL_VALUE_EXPR (new_var, t);
		  DECL_HAS_VALUE_EXPR_P (new_var) = 1;
		}
	      continue;
	    case OMP_CLAUSE__CONDTEMP_:
	      if (is_parallel_ctx (ctx)
		  || (is_simd && !OMP_CLAUSE__CONDTEMP__ITER (c)))
		break;
	      continue;
	    default:
	      continue;
	    }

	  if (task_reduction_p != (pass >= 2))
	    continue;

	  allocator = NULL_TREE;
	  allocate_ptr = NULL_TREE;
	  new_var = var = OMP_CLAUSE_DECL (c);
	  if ((c_kind == OMP_CLAUSE_REDUCTION
	       || c_kind == OMP_CLAUSE_IN_REDUCTION)
	      && TREE_CODE (var) == MEM_REF)
	    {
	      var = TREE_OPERAND (var, 0);
	      if (TREE_CODE (var) == POINTER_PLUS_EXPR)
		var = TREE_OPERAND (var, 0);
	      if (TREE_CODE (var) == INDIRECT_REF
		  || TREE_CODE (var) == ADDR_EXPR)
		var = TREE_OPERAND (var, 0);
	      if (is_variable_sized (var))
		{
		  gcc_assert (DECL_HAS_VALUE_EXPR_P (var));
		  var = DECL_VALUE_EXPR (var);
		  gcc_assert (TREE_CODE (var) == INDIRECT_REF);
		  var = TREE_OPERAND (var, 0);
		  gcc_assert (DECL_P (var));
		}
	      new_var = var;
	    }
	  if (c_kind == OMP_CLAUSE_IN_REDUCTION && is_omp_target (ctx->stmt))
	    {
	      splay_tree_key key = (splay_tree_key) &DECL_CONTEXT (var);
	      new_var = (tree) splay_tree_lookup (ctx->field_map, key)->value;
	    }
	  else if (c_kind != OMP_CLAUSE_COPYIN)
	    new_var = lookup_decl (var, ctx);

	  if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
	    {
	      if (pass != 0)
		continue;
	    }
	  /* C/C++ array section reductions.  */
	  else if ((c_kind == OMP_CLAUSE_REDUCTION
		    || c_kind == OMP_CLAUSE_IN_REDUCTION)
		   && var != OMP_CLAUSE_DECL (c))
	    {
	      if (pass == 0)
		continue;

	      tree bias = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
	      tree orig_var = TREE_OPERAND (OMP_CLAUSE_DECL (c), 0);

	      if (TREE_CODE (orig_var) == POINTER_PLUS_EXPR)
		{
		  tree b = TREE_OPERAND (orig_var, 1);
		  if (is_omp_target (ctx->stmt))
		    b = NULL_TREE;
		  else
		    b = maybe_lookup_decl (b, ctx);
		  if (b == NULL)
		    {
		      b = TREE_OPERAND (orig_var, 1);
		      b = maybe_lookup_decl_in_outer_ctx (b, ctx);
		    }
		  if (integer_zerop (bias))
		    bias = b;
		  else
		    {
		      bias = fold_convert_loc (clause_loc,
					       TREE_TYPE (b), bias);
		      bias = fold_build2_loc (clause_loc, PLUS_EXPR,
					      TREE_TYPE (b), b, bias);
		    }
		  orig_var = TREE_OPERAND (orig_var, 0);
		}
	      if (pass == 2)
		{
		  tree out = maybe_lookup_decl_in_outer_ctx (var, ctx);
		  if (is_global_var (out)
		      && TREE_CODE (TREE_TYPE (out)) != POINTER_TYPE
		      && (TREE_CODE (TREE_TYPE (out)) != REFERENCE_TYPE
			  || (TREE_CODE (TREE_TYPE (TREE_TYPE (out)))
			      != POINTER_TYPE)))
		    x = var;
		  else if (is_omp_target (ctx->stmt))
		    x = out;
		  else
		    {
		      bool by_ref = use_pointer_for_field (var, NULL);
		      x = build_receiver_ref (var, by_ref, ctx);
		      if (TREE_CODE (TREE_TYPE (var)) == REFERENCE_TYPE
			  && (TREE_CODE (TREE_TYPE (TREE_TYPE (var)))
			      == POINTER_TYPE))
			x = build_fold_addr_expr (x);
		    }
		  if (TREE_CODE (orig_var) == INDIRECT_REF)
		    x = build_simple_mem_ref (x);
		  else if (TREE_CODE (orig_var) == ADDR_EXPR)
		    {
		      if (var == TREE_OPERAND (orig_var, 0))
			x = build_fold_addr_expr (x);
		    }
		  bias = fold_convert (sizetype, bias);
		  x = fold_convert (ptr_type_node, x);
		  x = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
				       TREE_TYPE (x), x, bias);
		  unsigned cnt = task_reduction_cnt - 1;
		  if (!task_reduction_needs_orig_p)
		    cnt += (task_reduction_cntorig_full
			    - task_reduction_cntorig);
		  else
		    cnt = task_reduction_cntorig - 1;
		  tree r = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
				   size_int (cnt), NULL_TREE, NULL_TREE);
		  gimplify_assign (r, x, ilist);
		  continue;
		}

	      if (TREE_CODE (orig_var) == INDIRECT_REF
		  || TREE_CODE (orig_var) == ADDR_EXPR)
		orig_var = TREE_OPERAND (orig_var, 0);
	      tree d = OMP_CLAUSE_DECL (c);
	      tree type = TREE_TYPE (d);
	      gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
	      tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
	      tree sz = v;
	      const char *name = get_name (orig_var);
	      if (pass != 3 && !TREE_CONSTANT (v))
		{
		  tree t;
		  if (is_omp_target (ctx->stmt))
		    t = NULL_TREE;
		  else
		    t = maybe_lookup_decl (v, ctx);
		  if (t)
		    v = t;
		  else
		    v = maybe_lookup_decl_in_outer_ctx (v, ctx);
		  gimplify_expr (&v, ilist, NULL, is_gimple_val, fb_rvalue);
		  t = fold_build2_loc (clause_loc, PLUS_EXPR,
				       TREE_TYPE (v), v,
				       build_int_cst (TREE_TYPE (v), 1));
		  sz = fold_build2_loc (clause_loc, MULT_EXPR,
					TREE_TYPE (v), t,
					TYPE_SIZE_UNIT (TREE_TYPE (type)));
		}
	      if (pass == 3)
		{
		  tree xv = create_tmp_var (ptr_type_node);
		  if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
		    {
		      unsigned cnt = task_reduction_cnt - 1;
		      if (!task_reduction_needs_orig_p)
			cnt += (task_reduction_cntorig_full
				- task_reduction_cntorig);
		      else
			cnt = task_reduction_cntorig - 1;
		      x = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
				  size_int (cnt), NULL_TREE, NULL_TREE);

		      gimple *g = gimple_build_assign (xv, x);
		      gimple_seq_add_stmt (ilist, g);
		    }
		  else
		    {
		      unsigned int idx = *ctx->task_reduction_map->get (c);
		      tree off;
		      if (ctx->task_reductions[1 + idx])
			off = fold_convert (sizetype,
					    ctx->task_reductions[1 + idx]);
		      else
			off = task_reduction_read (ilist, tskred_temp, sizetype,
						   7 + 3 * idx + 1);
		      gimple *g = gimple_build_assign (xv, POINTER_PLUS_EXPR,
						       tskred_base, off);
		      gimple_seq_add_stmt (ilist, g);
		    }
		  x = fold_convert (build_pointer_type (boolean_type_node),
				    xv);
		  if (TREE_CONSTANT (v))
		    x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (x), x,
				     TYPE_SIZE_UNIT (type));
		  else
		    {
		      tree t;
		      if (is_omp_target (ctx->stmt))
			t = NULL_TREE;
		      else
			t = maybe_lookup_decl (v, ctx);
		      if (t)
			v = t;
		      else
			v = maybe_lookup_decl_in_outer_ctx (v, ctx);
		      gimplify_expr (&v, ilist, NULL, is_gimple_val,
				     fb_rvalue);
		      t = fold_build2_loc (clause_loc, PLUS_EXPR,
					   TREE_TYPE (v), v,
					   build_int_cst (TREE_TYPE (v), 1));
		      t = fold_build2_loc (clause_loc, MULT_EXPR,
					   TREE_TYPE (v), t,
					   TYPE_SIZE_UNIT (TREE_TYPE (type)));
		      x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (x), x, t);
		    }
		  cond = create_tmp_var (TREE_TYPE (x));
		  gimplify_assign (cond, x, ilist);
		  x = xv;
		}
	      else if (lower_private_allocate (var, type, allocator,
					       allocate_ptr, ilist, ctx,
					       true,
					       TREE_CONSTANT (v)
					       ? TYPE_SIZE_UNIT (type)
					       : sz))
		x = allocate_ptr;
	      else if (TREE_CONSTANT (v))
		{
		  x = create_tmp_var_raw (type, name);
		  gimple_add_tmp_var (x);
		  TREE_ADDRESSABLE (x) = 1;
		  x = build_fold_addr_expr_loc (clause_loc, x);
		}
	      else
		{
		  tree atmp
		    = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
		  tree al = size_int (TYPE_ALIGN (TREE_TYPE (type)));
		  x = build_call_expr_loc (clause_loc, atmp, 2, sz, al);
		}

	      tree ptype = build_pointer_type (TREE_TYPE (type));
	      x = fold_convert_loc (clause_loc, ptype, x);
	      tree y = create_tmp_var (ptype, name);
	      gimplify_assign (y, x, ilist);
	      x = y;
	      tree yb = y;

	      if (!integer_zerop (bias))
		{
		  bias = fold_convert_loc (clause_loc, pointer_sized_int_node,
					   bias);
		  yb = fold_convert_loc (clause_loc, pointer_sized_int_node,
					 x);
		  yb = fold_build2_loc (clause_loc, MINUS_EXPR,
					pointer_sized_int_node, yb, bias);
		  x = fold_convert_loc (clause_loc, TREE_TYPE (x), yb);
		  yb = create_tmp_var (ptype, name);
		  gimplify_assign (yb, x, ilist);
		  x = yb;
		}

	      d = TREE_OPERAND (d, 0);
	      if (TREE_CODE (d) == POINTER_PLUS_EXPR)
		d = TREE_OPERAND (d, 0);
	      if (TREE_CODE (d) == ADDR_EXPR)
		{
		  if (orig_var != var)
		    {
		      gcc_assert (is_variable_sized (orig_var));
		      x = fold_convert_loc (clause_loc, TREE_TYPE (new_var),
					    x);
		      gimplify_assign (new_var, x, ilist);
		      tree new_orig_var = lookup_decl (orig_var, ctx);
		      tree t = build_fold_indirect_ref (new_var);
		      DECL_IGNORED_P (new_var) = 0;
		      TREE_THIS_NOTRAP (t) = 1;
		      SET_DECL_VALUE_EXPR (new_orig_var, t);
		      DECL_HAS_VALUE_EXPR_P (new_orig_var) = 1;
		    }
		  else
		    {
		      x = build2 (MEM_REF, TREE_TYPE (new_var), x,
				  build_int_cst (ptype, 0));
		      SET_DECL_VALUE_EXPR (new_var, x);
		      DECL_HAS_VALUE_EXPR_P (new_var) = 1;
		    }
		}
	      else
		{
		  gcc_assert (orig_var == var);
		  if (TREE_CODE (d) == INDIRECT_REF)
		    {
		      x = create_tmp_var (ptype, name);
		      TREE_ADDRESSABLE (x) = 1;
		      gimplify_assign (x, yb, ilist);
		      x = build_fold_addr_expr_loc (clause_loc, x);
		    }
		  x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
		  gimplify_assign (new_var, x, ilist);
		}
	      /* GOMP_taskgroup_reduction_register memsets the whole
		 array to zero.  If the initializer is zero, we don't
		 need to initialize it again, just mark it as ever
		 used unconditionally, i.e. cond = true.  */
	      if (cond
		  && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == NULL_TREE
		  && initializer_zerop (omp_reduction_init (c,
							    TREE_TYPE (type))))
		{
		  gimple *g = gimple_build_assign (build_simple_mem_ref (cond),
						   boolean_true_node);
		  gimple_seq_add_stmt (ilist, g);
		  continue;
		}
	      tree end = create_artificial_label (UNKNOWN_LOCATION);
	      if (cond)
		{
		  gimple *g;
		  if (!is_parallel_ctx (ctx))
		    {
		      tree condv = create_tmp_var (boolean_type_node);
		      g = gimple_build_assign (condv,
					       build_simple_mem_ref (cond));
		      gimple_seq_add_stmt (ilist, g);
		      tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
		      g = gimple_build_cond (NE_EXPR, condv,
					     boolean_false_node, end, lab1);
		      gimple_seq_add_stmt (ilist, g);
		      gimple_seq_add_stmt (ilist, gimple_build_label (lab1));
		    }
		  g = gimple_build_assign (build_simple_mem_ref (cond),
					   boolean_true_node);
		  gimple_seq_add_stmt (ilist, g);
		}

	      tree y1 = create_tmp_var (ptype);
	      gimplify_assign (y1, y, ilist);
	      tree i2 = NULL_TREE, y2 = NULL_TREE;
	      tree body2 = NULL_TREE, end2 = NULL_TREE;
	      tree y3 = NULL_TREE, y4 = NULL_TREE;
	      if (task_reduction_needs_orig_p)
		{
		  y3 = create_tmp_var (ptype);
		  tree ref;
		  if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
		    ref = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
				  size_int (task_reduction_cnt_full
					    + task_reduction_cntorig - 1),
				  NULL_TREE, NULL_TREE);
		  else
		    {
		      unsigned int idx = *ctx->task_reduction_map->get (c);
		      ref = task_reduction_read (ilist, tskred_temp, ptype,
						 7 + 3 * idx);
		    }
		  gimplify_assign (y3, ref, ilist);
		}
	      else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) || is_simd)
		{
		  if (pass != 3)
		    {
		      y2 = create_tmp_var (ptype);
		      gimplify_assign (y2, y, ilist);
		    }
		  if (is_simd || OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
		    {
		      tree ref = build_outer_var_ref (var, ctx);
		      /* For ref build_outer_var_ref already performs this.  */
		      if (TREE_CODE (d) == INDIRECT_REF)
			gcc_assert (omp_privatize_by_reference (var));
		      else if (TREE_CODE (d) == ADDR_EXPR)
			ref = build_fold_addr_expr (ref);
		      else if (omp_privatize_by_reference (var))
			ref = build_fold_addr_expr (ref);
		      ref = fold_convert_loc (clause_loc, ptype, ref);
		      if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
			  && OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
			{
			  y3 = create_tmp_var (ptype);
			  gimplify_assign (y3, unshare_expr (ref), ilist);
			}
		      if (is_simd)
			{
			  y4 = create_tmp_var (ptype);
			  gimplify_assign (y4, ref, dlist);
			}
		    }
		}
	      tree i = create_tmp_var (TREE_TYPE (v));
	      gimplify_assign (i, build_int_cst (TREE_TYPE (v), 0), ilist);
	      tree body = create_artificial_label (UNKNOWN_LOCATION);
	      gimple_seq_add_stmt (ilist, gimple_build_label (body));
	      if (y2)
		{
		  i2 = create_tmp_var (TREE_TYPE (v));
		  gimplify_assign (i2, build_int_cst (TREE_TYPE (v), 0), dlist);
		  body2 = create_artificial_label (UNKNOWN_LOCATION);
		  end2 = create_artificial_label (UNKNOWN_LOCATION);
		  gimple_seq_add_stmt (dlist, gimple_build_label (body2));
		}
	      if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
		{
		  tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
		  tree decl_placeholder
		    = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c);
		  SET_DECL_VALUE_EXPR (decl_placeholder,
				       build_simple_mem_ref (y1));
		  DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 1;
		  SET_DECL_VALUE_EXPR (placeholder,
				       y3 ? build_simple_mem_ref (y3)
				       : error_mark_node);
		  DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
		  x = lang_hooks.decls.omp_clause_default_ctor
				(c, build_simple_mem_ref (y1),
				 y3 ? build_simple_mem_ref (y3) : NULL_TREE);
		  if (x)
		    gimplify_and_add (x, ilist);
		  if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
		    {
		      gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
		      lower_omp (&tseq, ctx);
		      gimple_seq_add_seq (ilist, tseq);
		    }
		  OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
		  if (is_simd)
		    {
		      SET_DECL_VALUE_EXPR (decl_placeholder,
					   build_simple_mem_ref (y2));
		      SET_DECL_VALUE_EXPR (placeholder,
					   build_simple_mem_ref (y4));
		      gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
		      lower_omp (&tseq, ctx);
		      gimple_seq_add_seq (dlist, tseq);
		      OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
		    }
		  DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
		  DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 0;
		  if (y2)
		    {
		      x = lang_hooks.decls.omp_clause_dtor
						(c, build_simple_mem_ref (y2));
		      if (x)
			gimplify_and_add (x, dlist);
		    }
		}
	      else
		{
		  x = omp_reduction_init (c, TREE_TYPE (type));
		  enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);

		  /* reduction(-:var) sums up the partial results, so it
		     acts identically to reduction(+:var).  */
		  if (code == MINUS_EXPR)
		    code = PLUS_EXPR;

		  gimplify_assign (build_simple_mem_ref (y1), x, ilist);
		  if (is_simd)
		    {
		      x = build2 (code, TREE_TYPE (type),
				  build_simple_mem_ref (y4),
				  build_simple_mem_ref (y2));
		      gimplify_assign (build_simple_mem_ref (y4), x, dlist);
		    }
		}
	      gimple *g
		= gimple_build_assign (y1, POINTER_PLUS_EXPR, y1,
				       TYPE_SIZE_UNIT (TREE_TYPE (type)));
	      gimple_seq_add_stmt (ilist, g);
	      if (y3)
		{
		  g = gimple_build_assign (y3, POINTER_PLUS_EXPR, y3,
					   TYPE_SIZE_UNIT (TREE_TYPE (type)));
		  gimple_seq_add_stmt (ilist, g);
		}
	      g = gimple_build_assign (i, PLUS_EXPR, i,
				       build_int_cst (TREE_TYPE (i), 1));
	      gimple_seq_add_stmt (ilist, g);
	      g = gimple_build_cond (LE_EXPR, i, v, body, end);
	      gimple_seq_add_stmt (ilist, g);
	      gimple_seq_add_stmt (ilist, gimple_build_label (end));
	      if (y2)
		{
		  g = gimple_build_assign (y2, POINTER_PLUS_EXPR, y2,
					   TYPE_SIZE_UNIT (TREE_TYPE (type)));
		  gimple_seq_add_stmt (dlist, g);
		  if (y4)
		    {
		      g = gimple_build_assign
					(y4, POINTER_PLUS_EXPR, y4,
					 TYPE_SIZE_UNIT (TREE_TYPE (type)));
		      gimple_seq_add_stmt (dlist, g);
		    }
		  g = gimple_build_assign (i2, PLUS_EXPR, i2,
					   build_int_cst (TREE_TYPE (i2), 1));
		  gimple_seq_add_stmt (dlist, g);
		  g = gimple_build_cond (LE_EXPR, i2, v, body2, end2);
		  gimple_seq_add_stmt (dlist, g);
		  gimple_seq_add_stmt (dlist, gimple_build_label (end2));
		}
	      if (allocator)
		{
		  tree f = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
		  g = gimple_build_call (f, 2, allocate_ptr, allocator);
		  gimple_seq_add_stmt (dlist, g);
		}
	      continue;
	    }
	  else if (pass == 2)
	    {
	      tree out = maybe_lookup_decl_in_outer_ctx (var, ctx);
	      if (is_global_var (out))
		x = var;
	      else if (is_omp_target (ctx->stmt))
		x = out;
	      else
		{
		  bool by_ref = use_pointer_for_field (var, ctx);
		  x = build_receiver_ref (var, by_ref, ctx);
		}
	      if (!omp_privatize_by_reference (var))
		x = build_fold_addr_expr (x);
	      x = fold_convert (ptr_type_node, x);
	      unsigned cnt = task_reduction_cnt - 1;
	      if (!task_reduction_needs_orig_p)
		cnt += task_reduction_cntorig_full - task_reduction_cntorig;
	      else
		cnt = task_reduction_cntorig - 1;
	      tree r = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
			       size_int (cnt), NULL_TREE, NULL_TREE);
	      gimplify_assign (r, x, ilist);
	      continue;
	    }
	  else if (pass == 3)
	    {
	      tree type = TREE_TYPE (new_var);
	      if (!omp_privatize_by_reference (var))
		type = build_pointer_type (type);
	      if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
		{
		  unsigned cnt = task_reduction_cnt - 1;
		  if (!task_reduction_needs_orig_p)
		    cnt += (task_reduction_cntorig_full
			    - task_reduction_cntorig);
		  else
		    cnt = task_reduction_cntorig - 1;
		  x = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
			      size_int (cnt), NULL_TREE, NULL_TREE);
		}
	      else
		{
		  unsigned int idx = *ctx->task_reduction_map->get (c);
		  tree off;
		  if (ctx->task_reductions[1 + idx])
		    off = fold_convert (sizetype,
					ctx->task_reductions[1 + idx]);
		  else
		    off = task_reduction_read (ilist, tskred_temp, sizetype,
					       7 + 3 * idx + 1);
		  x = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
				   tskred_base, off);
		}
	      x = fold_convert (type, x);
	      tree t;
	      if (omp_privatize_by_reference (var))
		{
		  gimplify_assign (new_var, x, ilist);
		  t = new_var;
		  new_var = build_simple_mem_ref (new_var);
		}
	      else
		{
		  t = create_tmp_var (type);
		  gimplify_assign (t, x, ilist);
		  SET_DECL_VALUE_EXPR (new_var, build_simple_mem_ref (t));
		  DECL_HAS_VALUE_EXPR_P (new_var) = 1;
		}
	      t = fold_convert (build_pointer_type (boolean_type_node), t);
	      t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t,
			       TYPE_SIZE_UNIT (TREE_TYPE (type)));
	      cond = create_tmp_var (TREE_TYPE (t));
	      gimplify_assign (cond, t, ilist);
	    }
	  else if (is_variable_sized (var))
	    {
	      /* For variable sized types, we need to allocate the
		 actual storage here.  Call alloca and store the
		 result in the pointer decl that we created elsewhere.  */
	      if (pass == 0)
		continue;

	      if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
		{
		  tree tmp;

		  ptr = DECL_VALUE_EXPR (new_var);
		  gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
		  ptr = TREE_OPERAND (ptr, 0);
		  gcc_assert (DECL_P (ptr));
		  x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));

		  if (lower_private_allocate (var, new_var, allocator,
					      allocate_ptr, ilist, ctx,
					      false, x))
		    tmp = allocate_ptr;
		  else
		    {
		      /* void *tmp = __builtin_alloca */
		      tree atmp
			= builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
		      gcall *stmt
			= gimple_build_call (atmp, 2, x,
					     size_int (DECL_ALIGN (var)));
		      cfun->calls_alloca = 1;
		      tmp = create_tmp_var_raw (ptr_type_node);
		      gimple_add_tmp_var (tmp);
		      gimple_call_set_lhs (stmt, tmp);

		      gimple_seq_add_stmt (ilist, stmt);
		    }

		  x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
		  gimplify_assign (ptr, x, ilist);
		}
	    }
	  else if (omp_privatize_by_reference (var)
		   && (c_kind != OMP_CLAUSE_FIRSTPRIVATE
		       || !OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c)))
	    {
	      /* For references that are being privatized for Fortran,
		 allocate new backing storage for the new pointer
		 variable.  This allows us to avoid changing all the
		 code that expects a pointer to something that expects
		 a direct variable.  */
	      if (pass == 0)
		continue;

	      x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
	      if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
		{
		  x = build_receiver_ref (var, false, ctx);
		  if (ctx->allocate_map)
		    if (tree *allocatep = ctx->allocate_map->get (var))
		      {
			allocator = *allocatep;
			if (TREE_CODE (allocator) == TREE_LIST)
			  allocator = TREE_PURPOSE (allocator);
			if (TREE_CODE (allocator) != INTEGER_CST)
			  allocator = build_outer_var_ref (allocator, ctx);
			allocator = fold_convert (pointer_sized_int_node,
						  allocator);
			allocate_ptr = unshare_expr (x);
		      }
		  if (allocator == NULL_TREE)
		    x = build_fold_addr_expr_loc (clause_loc, x);
		}
	      else if (lower_private_allocate (var, new_var, allocator,
					       allocate_ptr,
					       ilist, ctx, true, x))
		x = allocate_ptr;
	      else if (TREE_CONSTANT (x))
		{
		  /* For reduction in SIMD loop, defer adding the
		     initialization of the reference, because if we decide
		     to use SIMD array for it, the initilization could cause
		     expansion ICE.  Ditto for other privatization clauses.  */
		  if (is_simd)
		    x = NULL_TREE;
		  else
		    {
		      x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
					      get_name (var));
		      gimple_add_tmp_var (x);
		      TREE_ADDRESSABLE (x) = 1;
		      x = build_fold_addr_expr_loc (clause_loc, x);
		    }
		}
	      else
		{
		  tree atmp
		    = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
		  tree rtype = TREE_TYPE (TREE_TYPE (new_var));
		  tree al = size_int (TYPE_ALIGN (rtype));
		  x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
		}

	      if (x)
		{
		  x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
		  gimplify_assign (new_var, x, ilist);
		}

	      new_var = build_simple_mem_ref_loc (clause_loc, new_var);
	    }
	  else if ((c_kind == OMP_CLAUSE_REDUCTION
		    || c_kind == OMP_CLAUSE_IN_REDUCTION)
		   && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
	    {
	      if (pass == 0)
		continue;
	    }
	  else if (pass != 0)
	    continue;

	  switch (OMP_CLAUSE_CODE (c))
	    {
	    case OMP_CLAUSE_SHARED:
	      /* Ignore shared directives in teams construct inside
		 target construct.  */
	      if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
		  && !is_host_teams_ctx (ctx))
		continue;
	      /* Shared global vars are just accessed directly.  */
	      if (is_global_var (new_var))
		break;
	      /* For taskloop firstprivate/lastprivate, represented
		 as firstprivate and shared clause on the task, new_var
		 is the firstprivate var.  */
	      if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
		break;
	      /* Set up the DECL_VALUE_EXPR for shared variables now.  This
		 needs to be delayed until after fixup_child_record_type so
		 that we get the correct type during the dereference.  */
	      by_ref = use_pointer_for_field (var, ctx);
	      x = build_receiver_ref (var, by_ref, ctx);
	      SET_DECL_VALUE_EXPR (new_var, x);
	      DECL_HAS_VALUE_EXPR_P (new_var) = 1;

	      /* ??? If VAR is not passed by reference, and the variable
		 hasn't been initialized yet, then we'll get a warning for
		 the store into the omp_data_s structure.  Ideally, we'd be
		 able to notice this and not store anything at all, but
		 we're generating code too early.  Suppress the warning.  */
	      if (!by_ref)
		suppress_warning (var, OPT_Wuninitialized);
	      break;

	    case OMP_CLAUSE__CONDTEMP_:
	      if (is_parallel_ctx (ctx))
		{
		  x = build_receiver_ref (var, false, ctx);
		  SET_DECL_VALUE_EXPR (new_var, x);
		  DECL_HAS_VALUE_EXPR_P (new_var) = 1;
		}
	      else if (is_simd && !OMP_CLAUSE__CONDTEMP__ITER (c))
		{
		  x = build_zero_cst (TREE_TYPE (var));
		  goto do_private;
		}
	      break;

	    case OMP_CLAUSE_LASTPRIVATE:
	      if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
		break;
	      /* FALLTHRU */

	    case OMP_CLAUSE_PRIVATE:
	      if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
		x = build_outer_var_ref (var, ctx);
	      else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
		{
		  if (is_task_ctx (ctx))
		    x = build_receiver_ref (var, false, ctx);
		  else
		    x = build_outer_var_ref (var, ctx, OMP_CLAUSE_PRIVATE);
		}
	      else
		x = NULL;
	    do_private:
	      tree nx;
	      bool copy_ctor;
	      copy_ctor = false;
	      lower_private_allocate (var, new_var, allocator, allocate_ptr,
				      ilist, ctx, false, NULL_TREE);
	      nx = unshare_expr (new_var);
	      if (is_simd
		  && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
		  && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
		copy_ctor = true;
	      if (copy_ctor)
		nx = lang_hooks.decls.omp_clause_copy_ctor (c, nx, x);
	      else
		nx = lang_hooks.decls.omp_clause_default_ctor (c, nx, x);
	      if (is_simd)
		{
		  tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
		  if ((TREE_ADDRESSABLE (new_var) || nx || y
		       || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
			   && (gimple_omp_for_collapse (ctx->stmt) != 1
			       || (gimple_omp_for_index (ctx->stmt, 0)
				   != new_var)))
		       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE__CONDTEMP_
		       || omp_privatize_by_reference (var))
		      && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
						       ivar, lvar))
		    {
		      if (omp_privatize_by_reference (var))
			{
			  gcc_assert (TREE_CODE (new_var) == MEM_REF);
			  tree new_vard = TREE_OPERAND (new_var, 0);
			  gcc_assert (DECL_P (new_vard));
			  SET_DECL_VALUE_EXPR (new_vard,
					       build_fold_addr_expr (lvar));
			  DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
			}

		      if (nx)
			{
			  tree iv = unshare_expr (ivar);
			  if (copy_ctor)
			    x = lang_hooks.decls.omp_clause_copy_ctor (c, iv,
								       x);
			  else
			    x = lang_hooks.decls.omp_clause_default_ctor (c,
									  iv,
									  x);
			}
		      else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__CONDTEMP_)
			{
			  x = build2 (MODIFY_EXPR, TREE_TYPE (ivar),
				      unshare_expr (ivar), x);
			  nx = x;
			}
		      if (nx && x)
			gimplify_and_add (x, &llist[0]);
		      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
			  && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
			{
			  tree v = new_var;
			  if (!DECL_P (v))
			    {
			      gcc_assert (TREE_CODE (v) == MEM_REF);
			      v = TREE_OPERAND (v, 0);
			      gcc_assert (DECL_P (v));
			    }
			  v = *ctx->lastprivate_conditional_map->get (v);
			  tree t = create_tmp_var (TREE_TYPE (v));
			  tree z = build_zero_cst (TREE_TYPE (v));
			  tree orig_v
			    = build_outer_var_ref (var, ctx,
						   OMP_CLAUSE_LASTPRIVATE);
			  gimple_seq_add_stmt (dlist,
					       gimple_build_assign (t, z));
			  gcc_assert (DECL_HAS_VALUE_EXPR_P (v));
			  tree civar = DECL_VALUE_EXPR (v);
			  gcc_assert (TREE_CODE (civar) == ARRAY_REF);
			  civar = unshare_expr (civar);
			  TREE_OPERAND (civar, 1) = sctx.idx;
			  x = build2 (MODIFY_EXPR, TREE_TYPE (t), t,
				      unshare_expr (civar));
			  x = build2 (COMPOUND_EXPR, TREE_TYPE (orig_v), x,
				      build2 (MODIFY_EXPR, TREE_TYPE (orig_v),
					      orig_v, unshare_expr (ivar)));
			  tree cond = build2 (LT_EXPR, boolean_type_node, t,
					      civar);
			  x = build3 (COND_EXPR, void_type_node, cond, x,
				      void_node);
			  gimple_seq tseq = NULL;
			  gimplify_and_add (x, &tseq);
			  if (ctx->outer)
			    lower_omp (&tseq, ctx->outer);
			  gimple_seq_add_seq (&llist[1], tseq);
			}
		      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
			  && ctx->for_simd_scan_phase)
			{
			  x = unshare_expr (ivar);
			  tree orig_v
			    = build_outer_var_ref (var, ctx,
						   OMP_CLAUSE_LASTPRIVATE);
			  x = lang_hooks.decls.omp_clause_assign_op (c, x,
								     orig_v);
			  gimplify_and_add (x, &llist[0]);
			}
		      if (y)
			{
			  y = lang_hooks.decls.omp_clause_dtor (c, ivar);
			  if (y)
			    gimplify_and_add (y, &llist[1]);
			}
		      break;
		    }
		  if (omp_privatize_by_reference (var))
		    {
		      gcc_assert (TREE_CODE (new_var) == MEM_REF);
		      tree new_vard = TREE_OPERAND (new_var, 0);
		      gcc_assert (DECL_P (new_vard));
		      tree type = TREE_TYPE (TREE_TYPE (new_vard));
		      x = TYPE_SIZE_UNIT (type);
		      if (TREE_CONSTANT (x))
			{
			  x = create_tmp_var_raw (type, get_name (var));
			  gimple_add_tmp_var (x);
			  TREE_ADDRESSABLE (x) = 1;
			  x = build_fold_addr_expr_loc (clause_loc, x);
			  x = fold_convert_loc (clause_loc,
						TREE_TYPE (new_vard), x);
			  gimplify_assign (new_vard, x, ilist);
			}
		    }
		}
	      if (nx)
		gimplify_and_add (nx, ilist);
	      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
		  && is_simd
		  && ctx->for_simd_scan_phase)
		{
		  tree orig_v = build_outer_var_ref (var, ctx,
						     OMP_CLAUSE_LASTPRIVATE);
		  x = lang_hooks.decls.omp_clause_assign_op (c, new_var,
							     orig_v);
		  gimplify_and_add (x, ilist);
		}
	      /* FALLTHRU */

	    do_dtor:
	      x = lang_hooks.decls.omp_clause_dtor (c, new_var);
	      if (x)
		gimplify_and_add (x, dlist);
	      if (allocator)
		{
		  if (!is_gimple_val (allocator))
		    {
		      tree avar = create_tmp_var (TREE_TYPE (allocator));
		      gimplify_assign (avar, allocator, dlist);
		      allocator = avar;
		    }
		  if (!is_gimple_val (allocate_ptr))
		    {
		      tree apvar = create_tmp_var (TREE_TYPE (allocate_ptr));
		      gimplify_assign (apvar, allocate_ptr, dlist);
		      allocate_ptr = apvar;
		    }
		  tree f = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
		  gimple *g
		    = gimple_build_call (f, 2, allocate_ptr, allocator);
		  gimple_seq_add_stmt (dlist, g);
		}
	      break;

	    case OMP_CLAUSE_LINEAR:
	      if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
		goto do_firstprivate;
	      if (OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
		x = NULL;
	      else
		x = build_outer_var_ref (var, ctx);
	      goto do_private;

	    case OMP_CLAUSE_FIRSTPRIVATE:
	      if (is_task_ctx (ctx))
		{
		  if ((omp_privatize_by_reference (var)
		       && !OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c))
		      || is_variable_sized (var))
		    goto do_dtor;
		  else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
									  ctx))
			   || use_pointer_for_field (var, NULL))
		    {
		      x = build_receiver_ref (var, false, ctx);
		      if (ctx->allocate_map)
			if (tree *allocatep = ctx->allocate_map->get (var))
			  {
			    allocator = *allocatep;
			    if (TREE_CODE (allocator) == TREE_LIST)
			      allocator = TREE_PURPOSE (allocator);
			    if (TREE_CODE (allocator) != INTEGER_CST)
			      allocator = build_outer_var_ref (allocator, ctx);
			    allocator = fold_convert (pointer_sized_int_node,
						      allocator);
			    allocate_ptr = unshare_expr (x);
			    x = build_simple_mem_ref (x);
			    TREE_THIS_NOTRAP (x) = 1;
			  }
		      SET_DECL_VALUE_EXPR (new_var, x);
		      DECL_HAS_VALUE_EXPR_P (new_var) = 1;
		      goto do_dtor;
		    }
		}
	      if (OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c)
		  && omp_privatize_by_reference (var))
		{
		  x = build_outer_var_ref (var, ctx);
		  gcc_assert (TREE_CODE (x) == MEM_REF
			      && integer_zerop (TREE_OPERAND (x, 1)));
		  x = TREE_OPERAND (x, 0);
		  x = lang_hooks.decls.omp_clause_copy_ctor
						(c, unshare_expr (new_var), x);
		  gimplify_and_add (x, ilist);
		  goto do_dtor;
		}
	    do_firstprivate:
	      lower_private_allocate (var, new_var, allocator, allocate_ptr,
				      ilist, ctx, false, NULL_TREE);
	      x = build_outer_var_ref (var, ctx);
	      if (is_simd)
		{
		  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
		      && gimple_omp_for_combined_into_p (ctx->stmt))
		    {
		      tree t = OMP_CLAUSE_LINEAR_STEP (c);
		      tree stept = TREE_TYPE (t);
		      tree ct = omp_find_clause (clauses,
						 OMP_CLAUSE__LOOPTEMP_);
		      gcc_assert (ct);
		      tree l = OMP_CLAUSE_DECL (ct);
		      tree n1 = fd->loop.n1;
		      tree step = fd->loop.step;
		      tree itype = TREE_TYPE (l);
		      if (POINTER_TYPE_P (itype))
			itype = signed_type_for (itype);
		      l = fold_build2 (MINUS_EXPR, itype, l, n1);
		      if (TYPE_UNSIGNED (itype)
			  && fd->loop.cond_code == GT_EXPR)
			l = fold_build2 (TRUNC_DIV_EXPR, itype,
					 fold_build1 (NEGATE_EXPR, itype, l),
					 fold_build1 (NEGATE_EXPR,
						      itype, step));
		      else
			l = fold_build2 (TRUNC_DIV_EXPR, itype, l, step);
		      t = fold_build2 (MULT_EXPR, stept,
				       fold_convert (stept, l), t);

		      if (OMP_CLAUSE_LINEAR_ARRAY (c))
			{
			  if (omp_privatize_by_reference (var))
			    {
			      gcc_assert (TREE_CODE (new_var) == MEM_REF);
			      tree new_vard = TREE_OPERAND (new_var, 0);
			      gcc_assert (DECL_P (new_vard));
			      tree type = TREE_TYPE (TREE_TYPE (new_vard));
			      nx = TYPE_SIZE_UNIT (type);
			      if (TREE_CONSTANT (nx))
				{
				  nx = create_tmp_var_raw (type,
							   get_name (var));
				  gimple_add_tmp_var (nx);
				  TREE_ADDRESSABLE (nx) = 1;
				  nx = build_fold_addr_expr_loc (clause_loc,
								 nx);
				  nx = fold_convert_loc (clause_loc,
							 TREE_TYPE (new_vard),
							 nx);
				  gimplify_assign (new_vard, nx, ilist);
				}
			    }

			  x = lang_hooks.decls.omp_clause_linear_ctor
							(c, new_var, x, t);
			  gimplify_and_add (x, ilist);
			  goto do_dtor;
			}

		      if (POINTER_TYPE_P (TREE_TYPE (x)))
			x = fold_build2 (POINTER_PLUS_EXPR,
					 TREE_TYPE (x), x, t);
		      else
			x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x, t);
		    }

		  if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
		       || TREE_ADDRESSABLE (new_var)
		       || omp_privatize_by_reference (var))
		      && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
						       ivar, lvar))
		    {
		      if (omp_privatize_by_reference (var))
			{
			  gcc_assert (TREE_CODE (new_var) == MEM_REF);
			  tree new_vard = TREE_OPERAND (new_var, 0);
			  gcc_assert (DECL_P (new_vard));
			  SET_DECL_VALUE_EXPR (new_vard,
					       build_fold_addr_expr (lvar));
			  DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
			}
		      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
			{
			  tree iv = create_tmp_var (TREE_TYPE (new_var));
			  x = lang_hooks.decls.omp_clause_copy_ctor (c, iv, x);
			  gimplify_and_add (x, ilist);
			  gimple_stmt_iterator gsi
			    = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
			  gassign *g
			    = gimple_build_assign (unshare_expr (lvar), iv);
			  gsi_insert_before_without_update (&gsi, g,
							    GSI_SAME_STMT);
			  tree t = OMP_CLAUSE_LINEAR_STEP (c);
			  enum tree_code code = PLUS_EXPR;
			  if (POINTER_TYPE_P (TREE_TYPE (new_var)))
			    code = POINTER_PLUS_EXPR;
			  g = gimple_build_assign (iv, code, iv, t);
			  gsi_insert_before_without_update (&gsi, g,
							    GSI_SAME_STMT);
			  break;
			}
		      x = lang_hooks.decls.omp_clause_copy_ctor
						(c, unshare_expr (ivar), x);
		      gimplify_and_add (x, &llist[0]);
		      x = lang_hooks.decls.omp_clause_dtor (c, ivar);
		      if (x)
			gimplify_and_add (x, &llist[1]);
		      break;
		    }
		  if (omp_privatize_by_reference (var))
		    {
		      gcc_assert (TREE_CODE (new_var) == MEM_REF);
		      tree new_vard = TREE_OPERAND (new_var, 0);
		      gcc_assert (DECL_P (new_vard));
		      tree type = TREE_TYPE (TREE_TYPE (new_vard));
		      nx = TYPE_SIZE_UNIT (type);
		      if (TREE_CONSTANT (nx))
			{
			  nx = create_tmp_var_raw (type, get_name (var));
			  gimple_add_tmp_var (nx);
			  TREE_ADDRESSABLE (nx) = 1;
			  nx = build_fold_addr_expr_loc (clause_loc, nx);
			  nx = fold_convert_loc (clause_loc,
						 TREE_TYPE (new_vard), nx);
			  gimplify_assign (new_vard, nx, ilist);
			}
		    }
		}
	      x = lang_hooks.decls.omp_clause_copy_ctor
						(c, unshare_expr (new_var), x);
	      gimplify_and_add (x, ilist);
	      goto do_dtor;

	    case OMP_CLAUSE__LOOPTEMP_:
	    case OMP_CLAUSE__REDUCTEMP_:
	      gcc_assert (is_taskreg_ctx (ctx));
	      x = build_outer_var_ref (var, ctx);
	      x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
	      gimplify_and_add (x, ilist);
	      break;

	    case OMP_CLAUSE_COPYIN:
	      by_ref = use_pointer_for_field (var, NULL);
	      x = build_receiver_ref (var, by_ref, ctx);
	      x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
	      append_to_statement_list (x, &copyin_seq);
	      copyin_by_ref |= by_ref;
	      break;

	    case OMP_CLAUSE_REDUCTION:
	    case OMP_CLAUSE_IN_REDUCTION:
	      /* OpenACC reductions are initialized using the
		 GOACC_REDUCTION internal function.  */
	      if (is_gimple_omp_oacc (ctx->stmt))
		break;
	      if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
		{
		  tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
		  gimple *tseq;
		  tree ptype = TREE_TYPE (placeholder);
		  if (cond)
		    {
		      x = error_mark_node;
		      if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c)
			  && !task_reduction_needs_orig_p)
			x = var;
		      else if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
			{
			  tree pptype = build_pointer_type (ptype);
			  if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
			    x = build4 (ARRAY_REF, ptr_type_node, tskred_avar,
					size_int (task_reduction_cnt_full
						  + task_reduction_cntorig - 1),
					NULL_TREE, NULL_TREE);
			  else
			    {
			      unsigned int idx
				= *ctx->task_reduction_map->get (c);
			      x = task_reduction_read (ilist, tskred_temp,
						       pptype, 7 + 3 * idx);
			    }
			  x = fold_convert (pptype, x);
			  x = build_simple_mem_ref (x);
			}
		    }
		  else
		    {
		      lower_private_allocate (var, new_var, allocator,
					      allocate_ptr, ilist, ctx, false,
					      NULL_TREE);
		      x = build_outer_var_ref (var, ctx);

		      if (omp_privatize_by_reference (var)
			  && !useless_type_conversion_p (ptype, TREE_TYPE (x)))
			x = build_fold_addr_expr_loc (clause_loc, x);
		    }
		  SET_DECL_VALUE_EXPR (placeholder, x);
		  DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
		  tree new_vard = new_var;
		  if (omp_privatize_by_reference (var))
		    {
		      gcc_assert (TREE_CODE (new_var) == MEM_REF);
		      new_vard = TREE_OPERAND (new_var, 0);
		      gcc_assert (DECL_P (new_vard));
		    }
		  tree rvar = NULL_TREE, *rvarp = NULL, rvar2 = NULL_TREE;
		  if (is_simd
		      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
		      && OMP_CLAUSE_REDUCTION_INSCAN (c))
		    rvarp = &rvar;
		  if (is_simd
		      && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
						       ivar, lvar, rvarp,
						       &rvar2))
		    {
		      if (new_vard == new_var)
			{
			  gcc_assert (DECL_VALUE_EXPR (new_var) == lvar);
			  SET_DECL_VALUE_EXPR (new_var, ivar);
			}
		      else
			{
			  SET_DECL_VALUE_EXPR (new_vard,
					       build_fold_addr_expr (ivar));
			  DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
			}
		      x = lang_hooks.decls.omp_clause_default_ctor
				(c, unshare_expr (ivar),
				 build_outer_var_ref (var, ctx));
		      if (rvarp && ctx->for_simd_scan_phase)
			{
			  if (x)
			    gimplify_and_add (x, &llist[0]);
			  x = lang_hooks.decls.omp_clause_dtor (c, ivar);
			  if (x)
			    gimplify_and_add (x, &llist[1]);
			  break;
			}
		      else if (rvarp)
			{
			  if (x)
			    {
			      gimplify_and_add (x, &llist[0]);

			      tree ivar2 = unshare_expr (lvar);
			      TREE_OPERAND (ivar2, 1) = sctx.idx;
			      x = lang_hooks.decls.omp_clause_default_ctor
				    (c, ivar2, build_outer_var_ref (var, ctx));
			      gimplify_and_add (x, &llist[0]);

			      if (rvar2)
				{
				  x = lang_hooks.decls.omp_clause_default_ctor
					(c, unshare_expr (rvar2),
					 build_outer_var_ref (var, ctx));
				  gimplify_and_add (x, &llist[0]);
				}

			      /* For types that need construction, add another
				 private var which will be default constructed
				 and optionally initialized with
				 OMP_CLAUSE_REDUCTION_GIMPLE_INIT, as in the
				 loop we want to assign this value instead of
				 constructing and destructing it in each
				 iteration.  */
			      tree nv = create_tmp_var_raw (TREE_TYPE (ivar));
			      gimple_add_tmp_var (nv);
			      ctx->cb.decl_map->put (TREE_OPERAND (rvar2
								   ? rvar2
								   : ivar, 0),
						     nv);
			      x = lang_hooks.decls.omp_clause_default_ctor
				    (c, nv, build_outer_var_ref (var, ctx));
			      gimplify_and_add (x, ilist);

			      if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
				{
				  tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
				  x = DECL_VALUE_EXPR (new_vard);
				  tree vexpr = nv;
				  if (new_vard != new_var)
				    vexpr = build_fold_addr_expr (nv);
				  SET_DECL_VALUE_EXPR (new_vard, vexpr);
				  lower_omp (&tseq, ctx);
				  SET_DECL_VALUE_EXPR (new_vard, x);
				  gimple_seq_add_seq (ilist, tseq);
				  OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
				}

			      x = lang_hooks.decls.omp_clause_dtor (c, nv);
			      if (x)
				gimplify_and_add (x, dlist);
			    }

			  tree ref = build_outer_var_ref (var, ctx);
			  x = unshare_expr (ivar);
			  x = lang_hooks.decls.omp_clause_assign_op (c, x,
								     ref);
			  gimplify_and_add (x, &llist[0]);

			  ref = build_outer_var_ref (var, ctx);
			  x = lang_hooks.decls.omp_clause_assign_op (c, ref,
								     rvar);
			  gimplify_and_add (x, &llist[3]);

			  DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
			  if (new_vard == new_var)
			    SET_DECL_VALUE_EXPR (new_var, lvar);
			  else
			    SET_DECL_VALUE_EXPR (new_vard,
						 build_fold_addr_expr (lvar));

			  x = lang_hooks.decls.omp_clause_dtor (c, ivar);
			  if (x)
			    gimplify_and_add (x, &llist[1]);

			  tree ivar2 = unshare_expr (lvar);
			  TREE_OPERAND (ivar2, 1) = sctx.idx;
			  x = lang_hooks.decls.omp_clause_dtor (c, ivar2);
			  if (x)
			    gimplify_and_add (x, &llist[1]);

			  if (rvar2)
			    {
			      x = lang_hooks.decls.omp_clause_dtor (c, rvar2);
			      if (x)
				gimplify_and_add (x, &llist[1]);
			    }
			  break;
			}
		      if (x)
			gimplify_and_add (x, &llist[0]);
		      if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
			{
			  tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
			  lower_omp (&tseq, ctx);
			  gimple_seq_add_seq (&llist[0], tseq);
			}
		      OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
		      tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
		      lower_omp (&tseq, ctx);
		      gimple_seq_add_seq (&llist[1], tseq);
		      OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
		      DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
		      if (new_vard == new_var)
			SET_DECL_VALUE_EXPR (new_var, lvar);
		      else
			SET_DECL_VALUE_EXPR (new_vard,
					     build_fold_addr_expr (lvar));
		      x = lang_hooks.decls.omp_clause_dtor (c, ivar);
		      if (x)
			gimplify_and_add (x, &llist[1]);
		      break;
		    }
		  /* If this is a reference to constant size reduction var
		     with placeholder, we haven't emitted the initializer
		     for it because it is undesirable if SIMD arrays are used.
		     But if they aren't used, we need to emit the deferred
		     initialization now.  */
		  else if (omp_privatize_by_reference (var) && is_simd)
		    handle_simd_reference (clause_loc, new_vard, ilist);

		  tree lab2 = NULL_TREE;
		  if (cond)
		    {
		      gimple *g;
		      if (!is_parallel_ctx (ctx))
			{
			  tree condv = create_tmp_var (boolean_type_node);
			  tree m = build_simple_mem_ref (cond);
			  g = gimple_build_assign (condv, m);
			  gimple_seq_add_stmt (ilist, g);
			  tree lab1
			    = create_artificial_label (UNKNOWN_LOCATION);
			  lab2 = create_artificial_label (UNKNOWN_LOCATION);
			  g = gimple_build_cond (NE_EXPR, condv,
						 boolean_false_node,
						 lab2, lab1);
			  gimple_seq_add_stmt (ilist, g);
			  gimple_seq_add_stmt (ilist,
					       gimple_build_label (lab1));
			}
		      g = gimple_build_assign (build_simple_mem_ref (cond),
					       boolean_true_node);
		      gimple_seq_add_stmt (ilist, g);
		    }
		  x = lang_hooks.decls.omp_clause_default_ctor
				(c, unshare_expr (new_var),
				 cond ? NULL_TREE
				 : build_outer_var_ref (var, ctx));
		  if (x)
		    gimplify_and_add (x, ilist);

		  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
		      && OMP_CLAUSE_REDUCTION_INSCAN (c))
		    {
		      if (ctx->for_simd_scan_phase)
			goto do_dtor;
		      if (x || (!is_simd
				&& OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c)))
			{
			  tree nv = create_tmp_var_raw (TREE_TYPE (new_var));
			  gimple_add_tmp_var (nv);
			  ctx->cb.decl_map->put (new_vard, nv);
			  x = lang_hooks.decls.omp_clause_default_ctor
				(c, nv, build_outer_var_ref (var, ctx));
			  if (x)
			    gimplify_and_add (x, ilist);
			  if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
			    {
			      tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
			      tree vexpr = nv;
			      if (new_vard != new_var)
				vexpr = build_fold_addr_expr (nv);
			      SET_DECL_VALUE_EXPR (new_vard, vexpr);
			      DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
			      lower_omp (&tseq, ctx);
			      SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
			      DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
			      gimple_seq_add_seq (ilist, tseq);
			    }
			  OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
			  if (is_simd && ctx->scan_exclusive)
			    {
			      tree nv2
				= create_tmp_var_raw (TREE_TYPE (new_var));
			      gimple_add_tmp_var (nv2);
			      ctx->cb.decl_map->put (nv, nv2);
			      x = lang_hooks.decls.omp_clause_default_ctor
				    (c, nv2, build_outer_var_ref (var, ctx));
			      gimplify_and_add (x, ilist);
			      x = lang_hooks.decls.omp_clause_dtor (c, nv2);
			      if (x)
				gimplify_and_add (x, dlist);
			    }
			  x = lang_hooks.decls.omp_clause_dtor (c, nv);
			  if (x)
			    gimplify_and_add (x, dlist);
			}
		      else if (is_simd
			       && ctx->scan_exclusive
			       && TREE_ADDRESSABLE (TREE_TYPE (new_var)))
			{
			  tree nv2 = create_tmp_var_raw (TREE_TYPE (new_var));
			  gimple_add_tmp_var (nv2);
			  ctx->cb.decl_map->put (new_vard, nv2);
			  x = lang_hooks.decls.omp_clause_dtor (c, nv2);
			  if (x)
			    gimplify_and_add (x, dlist);
			}
		      DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
		      goto do_dtor;
		    }

		  if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
		    {
		      tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
		      if (c_kind == OMP_CLAUSE_IN_REDUCTION
			  && is_omp_target (ctx->stmt))
			{
			  tree d = maybe_lookup_decl_in_outer_ctx (var, ctx);
			  tree oldv = NULL_TREE;
			  gcc_assert (d);
			  if (DECL_HAS_VALUE_EXPR_P (d))
			    oldv = DECL_VALUE_EXPR (d);
			  SET_DECL_VALUE_EXPR (d, new_vard);
			  DECL_HAS_VALUE_EXPR_P (d) = 1;
			  lower_omp (&tseq, ctx);
			  if (oldv)
			    SET_DECL_VALUE_EXPR (d, oldv);
			  else
			    {
			      SET_DECL_VALUE_EXPR (d, NULL_TREE);
			      DECL_HAS_VALUE_EXPR_P (d) = 0;
			    }
			}
		      else
			lower_omp (&tseq, ctx);
		      gimple_seq_add_seq (ilist, tseq);
		    }
		  OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
		  if (is_simd)
		    {
		      tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
		      lower_omp (&tseq, ctx);
		      gimple_seq_add_seq (dlist, tseq);
		      OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
		    }
		  DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
		  if (cond)
		    {
		      if (lab2)
			gimple_seq_add_stmt (ilist, gimple_build_label (lab2));
		      break;
		    }
		  goto do_dtor;
		}
	      else
		{
		  x = omp_reduction_init (c, TREE_TYPE (new_var));
		  gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
		  enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);

		  if (cond)
		    {
		      gimple *g;
		      tree lab2 = NULL_TREE;
		      /* GOMP_taskgroup_reduction_register memsets the whole
			 array to zero.  If the initializer is zero, we don't
			 need to initialize it again, just mark it as ever
			 used unconditionally, i.e. cond = true.  */
		      if (initializer_zerop (x))
			{
			  g = gimple_build_assign (build_simple_mem_ref (cond),
						   boolean_true_node);
			  gimple_seq_add_stmt (ilist, g);
			  break;
			}

		      /* Otherwise, emit
			 if (!cond) { cond = true; new_var = x; }  */
		      if (!is_parallel_ctx (ctx))
			{
			  tree condv = create_tmp_var (boolean_type_node);
			  tree m = build_simple_mem_ref (cond);
			  g = gimple_build_assign (condv, m);
			  gimple_seq_add_stmt (ilist, g);
			  tree lab1
			    = create_artificial_label (UNKNOWN_LOCATION);
			  lab2 = create_artificial_label (UNKNOWN_LOCATION);
			  g = gimple_build_cond (NE_EXPR, condv,
						 boolean_false_node,
						 lab2, lab1);
			  gimple_seq_add_stmt (ilist, g);
			  gimple_seq_add_stmt (ilist,
					       gimple_build_label (lab1));
			}
		      g = gimple_build_assign (build_simple_mem_ref (cond),
					       boolean_true_node);
		      gimple_seq_add_stmt (ilist, g);
		      gimplify_assign (new_var, x, ilist);
		      if (lab2)
			gimple_seq_add_stmt (ilist, gimple_build_label (lab2));
		      break;
		    }

		  /* reduction(-:var) sums up the partial results, so it
		     acts identically to reduction(+:var).  */
		  if (code == MINUS_EXPR)
		    code = PLUS_EXPR;

		  bool is_truth_op
		    = (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR);
		  tree new_vard = new_var;
		  if (is_simd && omp_privatize_by_reference (var))
		    {
		      gcc_assert (TREE_CODE (new_var) == MEM_REF);
		      new_vard = TREE_OPERAND (new_var, 0);
		      gcc_assert (DECL_P (new_vard));
		    }
		  tree rvar = NULL_TREE, *rvarp = NULL, rvar2 = NULL_TREE;
		  if (is_simd
		      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
		      && OMP_CLAUSE_REDUCTION_INSCAN (c))
		    rvarp = &rvar;
		  if (is_simd
		      && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
						       ivar, lvar, rvarp,
						       &rvar2))
		    {
		      if (new_vard != new_var)
			{
			  SET_DECL_VALUE_EXPR (new_vard,
					       build_fold_addr_expr (lvar));
			  DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
			}

		      tree ref = build_outer_var_ref (var, ctx);

		      if (rvarp)
			{
			  if (ctx->for_simd_scan_phase)
			    break;
			  gimplify_assign (ivar, ref, &llist[0]);
			  ref = build_outer_var_ref (var, ctx);
			  gimplify_assign (ref, rvar, &llist[3]);
			  break;
			}

		      gimplify_assign (unshare_expr (ivar), x, &llist[0]);

		      if (sctx.is_simt)
			{
			  if (!simt_lane)
			    simt_lane = create_tmp_var (unsigned_type_node);
			  x = build_call_expr_internal_loc
			    (UNKNOWN_LOCATION, IFN_GOMP_SIMT_XCHG_BFLY,
			     TREE_TYPE (ivar), 2, ivar, simt_lane);
			  x = build2 (code, TREE_TYPE (ivar), ivar, x);
			  gimplify_assign (ivar, x, &llist[2]);
			}
		      tree ivar2 = ivar;
		      tree ref2 = ref;
		      if (is_truth_op)
			{
			  tree zero = build_zero_cst (TREE_TYPE (ivar));
			  ivar2 = fold_build2_loc (clause_loc, NE_EXPR,
						   boolean_type_node, ivar,
						   zero);
			  ref2 = fold_build2_loc (clause_loc, NE_EXPR,
						  boolean_type_node, ref,
						  zero);
			}
		      x = build2 (code, TREE_TYPE (ref), ref2, ivar2);
		      if (is_truth_op)
			x = fold_convert (TREE_TYPE (ref), x);
		      ref = build_outer_var_ref (var, ctx);
		      gimplify_assign (ref, x, &llist[1]);

		    }
		  else
		    {
		      lower_private_allocate (var, new_var, allocator,
					      allocate_ptr, ilist, ctx,
					      false, NULL_TREE);
		      if (omp_privatize_by_reference (var) && is_simd)
			handle_simd_reference (clause_loc, new_vard, ilist);
		      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
			  && OMP_CLAUSE_REDUCTION_INSCAN (c))
			break;
		      gimplify_assign (new_var, x, ilist);
		      if (is_simd)
			{
			  tree ref = build_outer_var_ref (var, ctx);
			  tree new_var2 = new_var;
			  tree ref2 = ref;
			  if (is_truth_op)
			    {
			      tree zero = build_zero_cst (TREE_TYPE (new_var));
			      new_var2
				= fold_build2_loc (clause_loc, NE_EXPR,
						   boolean_type_node, new_var,
						   zero);
			      ref2 = fold_build2_loc (clause_loc, NE_EXPR,
						      boolean_type_node, ref,
						      zero);
			    }
			  x = build2 (code, TREE_TYPE (ref2), ref2, new_var2);
			  if (is_truth_op)
			    x = fold_convert (TREE_TYPE (new_var), x);
			  ref = build_outer_var_ref (var, ctx);
			  gimplify_assign (ref, x, dlist);
			}
		      if (allocator)
			goto do_dtor;
		    }
		}
	      break;

	    default:
	      gcc_unreachable ();
	    }
	}
    }
  if (tskred_avar)
    {
      tree clobber = build_clobber (TREE_TYPE (tskred_avar));
      gimple_seq_add_stmt (ilist, gimple_build_assign (tskred_avar, clobber));
    }

  if (known_eq (sctx.max_vf, 1U))
    {
      sctx.is_simt = false;
      if (ctx->lastprivate_conditional_map)
	{
	  if (gimple_omp_for_combined_into_p (ctx->stmt))
	    {
	      /* Signal to lower_omp_1 that it should use parent context.  */
	      ctx->combined_into_simd_safelen1 = true;
	      for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
		if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
		    && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
		  {
		    tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
		    omp_context *outer = ctx->outer;
		    if (gimple_code (outer->stmt) == GIMPLE_OMP_SCAN)
		      outer = outer->outer;
		    tree *v = ctx->lastprivate_conditional_map->get (o);
		    tree po = lookup_decl (OMP_CLAUSE_DECL (c), outer);
		    tree *pv = outer->lastprivate_conditional_map->get (po);
		    *v = *pv;
		  }
	    }
	  else
	    {
	      /* When not vectorized, treat lastprivate(conditional:) like
		 normal lastprivate, as there will be just one simd lane
		 writing the privatized variable.  */
	      delete ctx->lastprivate_conditional_map;
	      ctx->lastprivate_conditional_map = NULL;
	    }
	}
    }

  if (nonconst_simd_if)
    {
      if (sctx.lane == NULL_TREE)
	{
	  sctx.idx = create_tmp_var (unsigned_type_node);
	  sctx.lane = create_tmp_var (unsigned_type_node);
	}
      /* FIXME: For now.  */
      sctx.is_simt = false;
    }

  if (sctx.lane || sctx.is_simt)
    {
      uid = create_tmp_var (ptr_type_node, "simduid");
      /* Don't want uninit warnings on simduid, it is always uninitialized,
	 but we use it not for the value, but for the DECL_UID only.  */
      suppress_warning (uid, OPT_Wuninitialized);
      c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_);
      OMP_CLAUSE__SIMDUID__DECL (c) = uid;
      OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
      gimple_omp_for_set_clauses (ctx->stmt, c);
    }
  /* Emit calls denoting privatized variables and initializing a pointer to
     structure that holds private variables as fields after ompdevlow pass.  */
  if (sctx.is_simt)
    {
      sctx.simt_eargs[0] = uid;
      gimple *g
	= gimple_build_call_internal_vec (IFN_GOMP_SIMT_ENTER, sctx.simt_eargs);
      gimple_call_set_lhs (g, uid);
      gimple_seq_add_stmt (ilist, g);
      sctx.simt_eargs.release ();

      simtrec = create_tmp_var (ptr_type_node, ".omp_simt");
      g = gimple_build_call_internal (IFN_GOMP_SIMT_ENTER_ALLOC, 1, uid);
      gimple_call_set_lhs (g, simtrec);
      gimple_seq_add_stmt (ilist, g);
    }
  if (sctx.lane)
    {
      gimple *g = gimple_build_call_internal (IFN_GOMP_SIMD_LANE,
					      2 + (nonconst_simd_if != NULL),
					      uid, integer_zero_node,
					      nonconst_simd_if);
      gimple_call_set_lhs (g, sctx.lane);
      gimple_stmt_iterator gsi = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
      gsi_insert_before_without_update (&gsi, g, GSI_SAME_STMT);
      g = gimple_build_assign (sctx.lane, INTEGER_CST,
			       build_int_cst (unsigned_type_node, 0));
      gimple_seq_add_stmt (ilist, g);
      if (sctx.lastlane)
	{
	  g = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE,
					  2, uid, sctx.lane);
	  gimple_call_set_lhs (g, sctx.lastlane);
	  gimple_seq_add_stmt (dlist, g);
	  gimple_seq_add_seq (dlist, llist[3]);
	}
      /* Emit reductions across SIMT lanes in log_2(simt_vf) steps.  */
      if (llist[2])
	{
	  tree simt_vf = create_tmp_var (unsigned_type_node);
	  g = gimple_build_call_internal (IFN_GOMP_SIMT_VF, 0);
	  gimple_call_set_lhs (g, simt_vf);
	  gimple_seq_add_stmt (dlist, g);

	  tree t = build_int_cst (unsigned_type_node, 1);
	  g = gimple_build_assign (simt_lane, INTEGER_CST, t);
	  gimple_seq_add_stmt (dlist, g);

	  t = build_int_cst (unsigned_type_node, 0);
	  g = gimple_build_assign (sctx.idx, INTEGER_CST, t);
	  gimple_seq_add_stmt (dlist, g);

	  tree body = create_artificial_label (UNKNOWN_LOCATION);
	  tree header = create_artificial_label (UNKNOWN_LOCATION);
	  tree end = create_artificial_label (UNKNOWN_LOCATION);
	  gimple_seq_add_stmt (dlist, gimple_build_goto (header));
	  gimple_seq_add_stmt (dlist, gimple_build_label (body));

	  gimple_seq_add_seq (dlist, llist[2]);

	  g = gimple_build_assign (simt_lane, LSHIFT_EXPR, simt_lane, integer_one_node);
	  gimple_seq_add_stmt (dlist, g);

	  gimple_seq_add_stmt (dlist, gimple_build_label (header));
	  g = gimple_build_cond (LT_EXPR, simt_lane, simt_vf, body, end);
	  gimple_seq_add_stmt (dlist, g);

	  gimple_seq_add_stmt (dlist, gimple_build_label (end));
	}
      for (int i = 0; i < 2; i++)
	if (llist[i])
	  {
	    tree vf = create_tmp_var (unsigned_type_node);
	    g = gimple_build_call_internal (IFN_GOMP_SIMD_VF, 1, uid);
	    gimple_call_set_lhs (g, vf);
	    gimple_seq *seq = i == 0 ? ilist : dlist;
	    gimple_seq_add_stmt (seq, g);
	    tree t = build_int_cst (unsigned_type_node, 0);
	    g = gimple_build_assign (sctx.idx, INTEGER_CST, t);
	    gimple_seq_add_stmt (seq, g);
	    tree body = create_artificial_label (UNKNOWN_LOCATION);
	    tree header = create_artificial_label (UNKNOWN_LOCATION);
	    tree end = create_artificial_label (UNKNOWN_LOCATION);
	    gimple_seq_add_stmt (seq, gimple_build_goto (header));
	    gimple_seq_add_stmt (seq, gimple_build_label (body));
	    gimple_seq_add_seq (seq, llist[i]);
	    t = build_int_cst (unsigned_type_node, 1);
	    g = gimple_build_assign (sctx.idx, PLUS_EXPR, sctx.idx, t);
	    gimple_seq_add_stmt (seq, g);
	    gimple_seq_add_stmt (seq, gimple_build_label (header));
	    g = gimple_build_cond (LT_EXPR, sctx.idx, vf, body, end);
	    gimple_seq_add_stmt (seq, g);
	    gimple_seq_add_stmt (seq, gimple_build_label (end));
	  }
    }
  if (sctx.is_simt)
    {
      gimple_seq_add_seq (dlist, sctx.simt_dlist);
      gimple *g
	= gimple_build_call_internal (IFN_GOMP_SIMT_EXIT, 1, simtrec);
      gimple_seq_add_stmt (dlist, g);
    }

  /* The copyin sequence is not to be executed by the main thread, since
     that would result in self-copies.  Perhaps not visible to scalars,
     but it certainly is to C++ operator=.  */
  if (copyin_seq)
    {
      x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
			   0);
      x = build2 (NE_EXPR, boolean_type_node, x,
		  build_int_cst (TREE_TYPE (x), 0));
      x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
      gimplify_and_add (x, ilist);
    }

  /* If any copyin variable is passed by reference, we must ensure the
     master thread doesn't modify it before it is copied over in all
     threads.  Similarly for variables in both firstprivate and
     lastprivate clauses we need to ensure the lastprivate copying
     happens after firstprivate copying in all threads.  And similarly
     for UDRs if initializer expression refers to omp_orig.  */
  if (copyin_by_ref || lastprivate_firstprivate
      || (reduction_omp_orig_ref
	  && !ctx->scan_inclusive
	  && !ctx->scan_exclusive))
    {
      /* Don't add any barrier for #pragma omp simd or
	 #pragma omp distribute.  */
      if (!is_task_ctx (ctx)
	  && (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
	      || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR))
	gimple_seq_add_stmt (ilist, omp_build_barrier (NULL_TREE));
    }

  /* If max_vf is non-zero, then we can use only a vectorization factor
     up to the max_vf we chose.  So stick it into the safelen clause.  */
  if (maybe_ne (sctx.max_vf, 0U))
    {
      tree c = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
				OMP_CLAUSE_SAFELEN);
      poly_uint64 safe_len;
      if (c == NULL_TREE
	  || (poly_int_tree_p (OMP_CLAUSE_SAFELEN_EXPR (c), &safe_len)
	      && maybe_gt (safe_len, sctx.max_vf)))
	{
	  c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
	  OMP_CLAUSE_SAFELEN_EXPR (c) = build_int_cst (integer_type_node,
						       sctx.max_vf);
	  OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
	  gimple_omp_for_set_clauses (ctx->stmt, c);
	}
    }
}

/* Create temporary variables for lastprivate(conditional:) implementation
   in context CTX with CLAUSES.  */

static void
lower_lastprivate_conditional_clauses (tree *clauses, omp_context *ctx)
{
  tree iter_type = NULL_TREE;
  tree cond_ptr = NULL_TREE;
  tree iter_var = NULL_TREE;
  bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
		  && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD);
  tree next = *clauses;
  for (tree c = *clauses; c; c = OMP_CLAUSE_CHAIN (c))
    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
	&& OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
      {
	if (is_simd)
	  {
	    tree cc = omp_find_clause (next, OMP_CLAUSE__CONDTEMP_);
	    gcc_assert (cc);
	    if (iter_type == NULL_TREE)
	      {
		iter_type = TREE_TYPE (OMP_CLAUSE_DECL (cc));
		iter_var = create_tmp_var_raw (iter_type);
		DECL_CONTEXT (iter_var) = current_function_decl;
		DECL_SEEN_IN_BIND_EXPR_P (iter_var) = 1;
		DECL_CHAIN (iter_var) = ctx->block_vars;
		ctx->block_vars = iter_var;
		tree c3
		  = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
		OMP_CLAUSE__CONDTEMP__ITER (c3) = 1;
		OMP_CLAUSE_DECL (c3) = iter_var;
		OMP_CLAUSE_CHAIN (c3) = *clauses;
		*clauses = c3;
		ctx->lastprivate_conditional_map = new hash_map<tree, tree>;
	      }
	    next = OMP_CLAUSE_CHAIN (cc);
	    tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
	    tree v = lookup_decl (OMP_CLAUSE_DECL (cc), ctx);
	    ctx->lastprivate_conditional_map->put (o, v);
	    continue;
	  }
	if (iter_type == NULL)
	  {
	    if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR)
	      {
		struct omp_for_data fd;
		omp_extract_for_data (as_a <gomp_for *> (ctx->stmt), &fd,
				      NULL);
		iter_type = unsigned_type_for (fd.iter_type);
	      }
	    else if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
	      iter_type = unsigned_type_node;
	    tree c2 = omp_find_clause (*clauses, OMP_CLAUSE__CONDTEMP_);
	    if (c2)
	      {
		cond_ptr
		  = lookup_decl_in_outer_ctx (OMP_CLAUSE_DECL (c2), ctx);
		OMP_CLAUSE_DECL (c2) = cond_ptr;
	      }
	    else
	      {
		cond_ptr = create_tmp_var_raw (build_pointer_type (iter_type));
		DECL_CONTEXT (cond_ptr) = current_function_decl;
		DECL_SEEN_IN_BIND_EXPR_P (cond_ptr) = 1;
		DECL_CHAIN (cond_ptr) = ctx->block_vars;
		ctx->block_vars = cond_ptr;
		c2 = build_omp_clause (UNKNOWN_LOCATION,
				       OMP_CLAUSE__CONDTEMP_);
		OMP_CLAUSE_DECL (c2) = cond_ptr;
		OMP_CLAUSE_CHAIN (c2) = *clauses;
		*clauses = c2;
	      }
	    iter_var = create_tmp_var_raw (iter_type);
	    DECL_CONTEXT (iter_var) = current_function_decl;
	    DECL_SEEN_IN_BIND_EXPR_P (iter_var) = 1;
	    DECL_CHAIN (iter_var) = ctx->block_vars;
	    ctx->block_vars = iter_var;
	    tree c3
	      = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
	    OMP_CLAUSE__CONDTEMP__ITER (c3) = 1;
	    OMP_CLAUSE_DECL (c3) = iter_var;
	    OMP_CLAUSE_CHAIN (c3) = OMP_CLAUSE_CHAIN (c2);
	    OMP_CLAUSE_CHAIN (c2) = c3;
	    ctx->lastprivate_conditional_map = new hash_map<tree, tree>;
	  }
	tree v = create_tmp_var_raw (iter_type);
	DECL_CONTEXT (v) = current_function_decl;
	DECL_SEEN_IN_BIND_EXPR_P (v) = 1;
	DECL_CHAIN (v) = ctx->block_vars;
	ctx->block_vars = v;
	tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
	ctx->lastprivate_conditional_map->put (o, v);
      }
}


/* Generate code to implement the LASTPRIVATE clauses.  This is used for
   both parallel and workshare constructs.  PREDICATE may be NULL if it's
   always true.  BODY_P is the sequence to insert early initialization
   if needed, STMT_LIST is where the non-conditional lastprivate handling
   goes into and CSTMT_LIST is a sequence that needs to be run in a critical
   section.  */

static void
lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p,
			   gimple_seq *stmt_list, gimple_seq *cstmt_list,
			   omp_context *ctx)
{
  tree x, c, label = NULL, orig_clauses = clauses;
  bool par_clauses = false;
  tree simduid = NULL, lastlane = NULL, simtcond = NULL, simtlast = NULL;
  unsigned HOST_WIDE_INT conditional_off = 0;
  gimple_seq post_stmt_list = NULL;

  /* Early exit if there are no lastprivate or linear clauses.  */
  for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
    if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LASTPRIVATE
	|| (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LINEAR
	    && !OMP_CLAUSE_LINEAR_NO_COPYOUT (clauses)))
      break;
  if (clauses == NULL)
    {
      /* If this was a workshare clause, see if it had been combined
	 with its parallel.  In that case, look for the clauses on the
	 parallel statement itself.  */
      if (is_parallel_ctx (ctx))
	return;

      ctx = ctx->outer;
      if (ctx == NULL || !is_parallel_ctx (ctx))
	return;

      clauses = omp_find_clause (gimple_omp_parallel_clauses (ctx->stmt),
				 OMP_CLAUSE_LASTPRIVATE);
      if (clauses == NULL)
	return;
      par_clauses = true;
    }

  bool maybe_simt = false;
  if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
      && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
    {
      maybe_simt = omp_find_clause (orig_clauses, OMP_CLAUSE__SIMT_);
      simduid = omp_find_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
      if (simduid)
	simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
    }

  if (predicate)
    {
      gcond *stmt;
      tree label_true, arm1, arm2;
      enum tree_code pred_code = TREE_CODE (predicate);

      label = create_artificial_label (UNKNOWN_LOCATION);
      label_true = create_artificial_label (UNKNOWN_LOCATION);
      if (TREE_CODE_CLASS (pred_code) == tcc_comparison)
	{
	  arm1 = TREE_OPERAND (predicate, 0);
	  arm2 = TREE_OPERAND (predicate, 1);
	  gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
	  gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
	}
      else
	{
	  arm1 = predicate;
	  gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
	  arm2 = boolean_false_node;
	  pred_code = NE_EXPR;
	}
      if (maybe_simt)
	{
	  c = build2 (pred_code, boolean_type_node, arm1, arm2);
	  c = fold_convert (integer_type_node, c);
	  simtcond = create_tmp_var (integer_type_node);
	  gimplify_assign (simtcond, c, stmt_list);
	  gcall *g = gimple_build_call_internal (IFN_GOMP_SIMT_VOTE_ANY,
						 1, simtcond);
	  c = create_tmp_var (integer_type_node);
	  gimple_call_set_lhs (g, c);
	  gimple_seq_add_stmt (stmt_list, g);
	  stmt = gimple_build_cond (NE_EXPR, c, integer_zero_node,
				    label_true, label);
	}
      else
	stmt = gimple_build_cond (pred_code, arm1, arm2, label_true, label);
      gimple_seq_add_stmt (stmt_list, stmt);
      gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
    }

  tree cond_ptr = NULL_TREE;
  for (c = clauses; c ;)
    {
      tree var, new_var;
      location_t clause_loc = OMP_CLAUSE_LOCATION (c);
      gimple_seq *this_stmt_list = stmt_list;
      tree lab2 = NULL_TREE;

      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
	  && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
	  && ctx->lastprivate_conditional_map
	  && !ctx->combined_into_simd_safelen1)
	{
	  gcc_assert (body_p);
	  if (simduid)
	    goto next;
	  if (cond_ptr == NULL_TREE)
	    {
	      cond_ptr = omp_find_clause (orig_clauses, OMP_CLAUSE__CONDTEMP_);
	      cond_ptr = OMP_CLAUSE_DECL (cond_ptr);
	    }
	  tree type = TREE_TYPE (TREE_TYPE (cond_ptr));
	  tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
	  tree v = *ctx->lastprivate_conditional_map->get (o);
	  gimplify_assign (v, build_zero_cst (type), body_p);
	  this_stmt_list = cstmt_list;
	  tree mem;
	  if (POINTER_TYPE_P (TREE_TYPE (cond_ptr)))
	    {
	      mem = build2 (MEM_REF, type, cond_ptr,
			    build_int_cst (TREE_TYPE (cond_ptr),
					   conditional_off));
	      conditional_off += tree_to_uhwi (TYPE_SIZE_UNIT (type));
	    }
	  else
	    mem = build4 (ARRAY_REF, type, cond_ptr,
			  size_int (conditional_off++), NULL_TREE, NULL_TREE);
	  tree mem2 = copy_node (mem);
	  gimple_seq seq = NULL;
	  mem = force_gimple_operand (mem, &seq, true, NULL_TREE);
	  gimple_seq_add_seq (this_stmt_list, seq);
	  tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
	  lab2 = create_artificial_label (UNKNOWN_LOCATION);
	  gimple *g = gimple_build_cond (GT_EXPR, v, mem, lab1, lab2);
	  gimple_seq_add_stmt (this_stmt_list, g);
	  gimple_seq_add_stmt (this_stmt_list, gimple_build_label (lab1));
	  gimplify_assign (mem2, v, this_stmt_list);
	}
      else if (predicate
	       && ctx->combined_into_simd_safelen1
	       && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
	       && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
	       && ctx->lastprivate_conditional_map)
	this_stmt_list = &post_stmt_list;

      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
	  || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
	      && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
	{
	  var = OMP_CLAUSE_DECL (c);
	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
	      && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
	      && is_taskloop_ctx (ctx))
	    {
	      gcc_checking_assert (ctx->outer && is_task_ctx (ctx->outer));
	      new_var = lookup_decl (var, ctx->outer);
	    }
	  else
	    {
	      new_var = lookup_decl (var, ctx);
	      /* Avoid uninitialized warnings for lastprivate and
		 for linear iterators.  */
	      if (predicate
		  && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
		      || OMP_CLAUSE_LINEAR_NO_COPYIN (c)))
		suppress_warning (new_var, OPT_Wuninitialized);
	    }

	  if (!maybe_simt && simduid && DECL_HAS_VALUE_EXPR_P (new_var))
	    {
	      tree val = DECL_VALUE_EXPR (new_var);
	      if (TREE_CODE (val) == ARRAY_REF
		  && VAR_P (TREE_OPERAND (val, 0))
		  && lookup_attribute ("omp simd array",
				       DECL_ATTRIBUTES (TREE_OPERAND (val,
								      0))))
		{
		  if (lastlane == NULL)
		    {
		      lastlane = create_tmp_var (unsigned_type_node);
		      gcall *g
			= gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE,
						      2, simduid,
						      TREE_OPERAND (val, 1));
		      gimple_call_set_lhs (g, lastlane);
		      gimple_seq_add_stmt (this_stmt_list, g);
		    }
		  new_var = build4 (ARRAY_REF, TREE_TYPE (val),
				    TREE_OPERAND (val, 0), lastlane,
				    NULL_TREE, NULL_TREE);
		  TREE_THIS_NOTRAP (new_var) = 1;
		}
	    }
	  else if (maybe_simt)
	    {
	      tree val = (DECL_HAS_VALUE_EXPR_P (new_var)
			  ? DECL_VALUE_EXPR (new_var)
			  : new_var);
	      if (simtlast == NULL)
		{
		  simtlast = create_tmp_var (unsigned_type_node);
		  gcall *g = gimple_build_call_internal
		    (IFN_GOMP_SIMT_LAST_LANE, 1, simtcond);
		  gimple_call_set_lhs (g, simtlast);
		  gimple_seq_add_stmt (this_stmt_list, g);
		}
	      x = build_call_expr_internal_loc
		(UNKNOWN_LOCATION, IFN_GOMP_SIMT_XCHG_IDX,
		 TREE_TYPE (val), 2, val, simtlast);
	      new_var = unshare_expr (new_var);
	      gimplify_assign (new_var, x, this_stmt_list);
	      new_var = unshare_expr (new_var);
	    }

	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
	      && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
	    {
	      lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
	      gimple_seq_add_seq (this_stmt_list,
				  OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
	      OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
	    }
	  else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
		   && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
	    {
	      lower_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
	      gimple_seq_add_seq (this_stmt_list,
				  OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
	      OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) = NULL;
	    }

	  x = NULL_TREE;
	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
	      && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)
	      && is_taskloop_ctx (ctx))
	    {
	      tree ovar = maybe_lookup_decl_in_outer_ctx (var,
							  ctx->outer->outer);
	      if (is_global_var (ovar))
		x = ovar;
	    }
	  if (!x)
	    x = build_outer_var_ref (var, ctx, OMP_CLAUSE_LASTPRIVATE);
	  if (omp_privatize_by_reference (var))
	    new_var = build_simple_mem_ref_loc (clause_loc, new_var);
	  x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
	  gimplify_and_add (x, this_stmt_list);

	  if (lab2)
	    gimple_seq_add_stmt (this_stmt_list, gimple_build_label (lab2));
	}

     next:
      c = OMP_CLAUSE_CHAIN (c);
      if (c == NULL && !par_clauses)
	{
	  /* If this was a workshare clause, see if it had been combined
	     with its parallel.  In that case, continue looking for the
	     clauses also on the parallel statement itself.  */
	  if (is_parallel_ctx (ctx))
	    break;

	  ctx = ctx->outer;
	  if (ctx == NULL || !is_parallel_ctx (ctx))
	    break;

	  c = omp_find_clause (gimple_omp_parallel_clauses (ctx->stmt),
			       OMP_CLAUSE_LASTPRIVATE);
	  par_clauses = true;
	}
    }

  if (label)
    gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
  gimple_seq_add_seq (stmt_list, post_stmt_list);
}

/* Lower the OpenACC reductions of CLAUSES for compute axis LEVEL
   (which might be a placeholder).  INNER is true if this is an inner
   axis of a multi-axis loop.  FORK and JOIN are (optional) fork and
   join markers.  Generate the before-loop forking sequence in
   FORK_SEQ and the after-loop joining sequence to JOIN_SEQ.  The
   general form of these sequences is

     GOACC_REDUCTION_SETUP
     GOACC_FORK
     GOACC_REDUCTION_INIT
     ...
     GOACC_REDUCTION_FINI
     GOACC_JOIN
     GOACC_REDUCTION_TEARDOWN.  */

static void
lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner,
		       gcall *fork, gcall *private_marker, gcall *join,
		       gimple_seq *fork_seq, gimple_seq *join_seq,
		       omp_context *ctx)
{
  gimple_seq before_fork = NULL;
  gimple_seq after_fork = NULL;
  gimple_seq before_join = NULL;
  gimple_seq after_join = NULL;
  tree init_code = NULL_TREE, fini_code = NULL_TREE,
    setup_code = NULL_TREE, teardown_code = NULL_TREE;
  unsigned offset = 0;

  for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
      {
	/* No 'reduction' clauses on OpenACC 'kernels'.  */
	gcc_checking_assert (!is_oacc_kernels (ctx));
	/* Likewise, on OpenACC 'kernels' decomposed parts.  */
	gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));

	tree orig = OMP_CLAUSE_DECL (c);
	tree var = maybe_lookup_decl (orig, ctx);
	tree ref_to_res = NULL_TREE;
	tree incoming, outgoing, v1, v2, v3;
	bool is_private = false;

	enum tree_code rcode = OMP_CLAUSE_REDUCTION_CODE (c);
	if (rcode == MINUS_EXPR)
	  rcode = PLUS_EXPR;
	else if (rcode == TRUTH_ANDIF_EXPR)
	  rcode = BIT_AND_EXPR;
	else if (rcode == TRUTH_ORIF_EXPR)
	  rcode = BIT_IOR_EXPR;
	tree op = build_int_cst (unsigned_type_node, rcode);

	if (!var)
	  var = orig;

	incoming = outgoing = var;

	if (!inner)
	  {
	    /* See if an outer construct also reduces this variable.  */
	    omp_context *outer = ctx;

	    while (omp_context *probe = outer->outer)
	      {
		enum gimple_code type = gimple_code (probe->stmt);
		tree cls;

		switch (type)
		  {
		  case GIMPLE_OMP_FOR:
		    cls = gimple_omp_for_clauses (probe->stmt);
		    break;

		  case GIMPLE_OMP_TARGET:
		    /* No 'reduction' clauses inside OpenACC 'kernels'
		       regions.  */
		    gcc_checking_assert (!is_oacc_kernels (probe));

		    if (!is_gimple_omp_offloaded (probe->stmt))
		      goto do_lookup;

		    cls = gimple_omp_target_clauses (probe->stmt);
		    break;

		  default:
		    goto do_lookup;
		  }

		outer = probe;
		for (; cls;  cls = OMP_CLAUSE_CHAIN (cls))
		  if (OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_REDUCTION
		      && orig == OMP_CLAUSE_DECL (cls))
		    {
		      incoming = outgoing = lookup_decl (orig, probe);
		      goto has_outer_reduction;
		    }
		  else if ((OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_FIRSTPRIVATE
			    || OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_PRIVATE)
			   && orig == OMP_CLAUSE_DECL (cls))
		    {
		      is_private = true;
		      goto do_lookup;
		    }
	      }

	  do_lookup:
	    /* This is the outermost construct with this reduction,
	       see if there's a mapping for it.  */
	    if (gimple_code (outer->stmt) == GIMPLE_OMP_TARGET
		&& maybe_lookup_field (orig, outer) && !is_private)
	      {
		ref_to_res = build_receiver_ref (orig, false, outer);
		if (omp_privatize_by_reference (orig))
		  ref_to_res = build_simple_mem_ref (ref_to_res);

		tree type = TREE_TYPE (var);
		if (POINTER_TYPE_P (type))
		  type = TREE_TYPE (type);

		outgoing = var;
		incoming = omp_reduction_init_op (loc, rcode, type);
	      }
	    else
	      {
		/* Try to look at enclosing contexts for reduction var,
		   use original if no mapping found.  */
		tree t = NULL_TREE;
		omp_context *c = ctx->outer;
		while (c && !t)
		  {
		    t = maybe_lookup_decl (orig, c);
		    c = c->outer;
		  }
		incoming = outgoing = (t ? t : orig);
	      }

	  has_outer_reduction:;
	  }

	if (!ref_to_res)
	  ref_to_res = integer_zero_node;

	if (omp_privatize_by_reference (orig))
	  {
	    tree type = TREE_TYPE (var);
	    const char *id = IDENTIFIER_POINTER (DECL_NAME (var));

	    if (!inner)
	      {
		tree x = create_tmp_var (TREE_TYPE (type), id);
		gimplify_assign (var, build_fold_addr_expr (x), fork_seq);
	      }

	    v1 = create_tmp_var (type, id);
	    v2 = create_tmp_var (type, id);
	    v3 = create_tmp_var (type, id);

	    gimplify_assign (v1, var, fork_seq);
	    gimplify_assign (v2, var, fork_seq);
	    gimplify_assign (v3, var, fork_seq);

	    var = build_simple_mem_ref (var);
	    v1 = build_simple_mem_ref (v1);
	    v2 = build_simple_mem_ref (v2);
	    v3 = build_simple_mem_ref (v3);
	    outgoing = build_simple_mem_ref (outgoing);

	    if (!TREE_CONSTANT (incoming))
	      incoming = build_simple_mem_ref (incoming);
	  }
	else
	  v1 = v2 = v3 = var;

	/* Determine position in reduction buffer, which may be used
	   by target.  The parser has ensured that this is not a
	   variable-sized type.  */
	fixed_size_mode mode
	  = as_a <fixed_size_mode> (TYPE_MODE (TREE_TYPE (var)));
	unsigned align = GET_MODE_ALIGNMENT (mode) /  BITS_PER_UNIT;
	offset = (offset + align - 1) & ~(align - 1);
	tree off = build_int_cst (sizetype, offset);
	offset += GET_MODE_SIZE (mode);

	if (!init_code)
	  {
	    init_code = build_int_cst (integer_type_node,
				       IFN_GOACC_REDUCTION_INIT);
	    fini_code = build_int_cst (integer_type_node,
				       IFN_GOACC_REDUCTION_FINI);
	    setup_code = build_int_cst (integer_type_node,
					IFN_GOACC_REDUCTION_SETUP);
	    teardown_code = build_int_cst (integer_type_node,
					   IFN_GOACC_REDUCTION_TEARDOWN);
	  }

	tree setup_call
	  = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
					  TREE_TYPE (var), 6, setup_code,
					  unshare_expr (ref_to_res),
					  incoming, level, op, off);
	tree init_call
	  = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
					  TREE_TYPE (var), 6, init_code,
					  unshare_expr (ref_to_res),
					  v1, level, op, off);
	tree fini_call
	  = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
					  TREE_TYPE (var), 6, fini_code,
					  unshare_expr (ref_to_res),
					  v2, level, op, off);
	tree teardown_call
	  = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
					  TREE_TYPE (var), 6, teardown_code,
					  ref_to_res, v3, level, op, off);

	gimplify_assign (v1, setup_call, &before_fork);
	gimplify_assign (v2, init_call, &after_fork);
	gimplify_assign (v3, fini_call, &before_join);
	gimplify_assign (outgoing, teardown_call, &after_join);
      }

  /* Now stitch things together.  */
  gimple_seq_add_seq (fork_seq, before_fork);
  if (private_marker)
    gimple_seq_add_stmt (fork_seq, private_marker);
  if (fork)
    gimple_seq_add_stmt (fork_seq, fork);
  gimple_seq_add_seq (fork_seq, after_fork);

  gimple_seq_add_seq (join_seq, before_join);
  if (join)
    gimple_seq_add_stmt (join_seq, join);
  gimple_seq_add_seq (join_seq, after_join);
}

/* Generate code to implement the REDUCTION clauses, append it
   to STMT_SEQP.  CLIST if non-NULL is a pointer to a sequence
   that should be emitted also inside of the critical section,
   in that case clear *CLIST afterwards, otherwise leave it as is
   and let the caller emit it itself.  */

static void
lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp,
			 gimple_seq *clist, omp_context *ctx)
{
  gimple_seq sub_seq = NULL;
  gimple *stmt;
  tree x, c;
  int count = 0;

  /* OpenACC loop reductions are handled elsewhere.  */
  if (is_gimple_omp_oacc (ctx->stmt))
    return;

  /* SIMD reductions are handled in lower_rec_input_clauses.  */
  if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
      && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
    return;

  /* inscan reductions are handled elsewhere.  */
  if (ctx->scan_inclusive || ctx->scan_exclusive)
    return;

  /* First see if there is exactly one reduction clause.  Use OMP_ATOMIC
     update in that case, otherwise use a lock.  */
  for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
	&& !OMP_CLAUSE_REDUCTION_TASK (c))
      {
	if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
	    || TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
	  {
	    /* Never use OMP_ATOMIC for array reductions or UDRs.  */
	    count = -1;
	    break;
	  }
	count++;
      }

  if (count == 0)
    return;

  for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    {
      tree var, ref, new_var, orig_var;
      enum tree_code code;
      location_t clause_loc = OMP_CLAUSE_LOCATION (c);

      if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
	  || OMP_CLAUSE_REDUCTION_TASK (c))
	continue;

      enum omp_clause_code ccode = OMP_CLAUSE_REDUCTION;
      orig_var = var = OMP_CLAUSE_DECL (c);
      if (TREE_CODE (var) == MEM_REF)
	{
	  var = TREE_OPERAND (var, 0);
	  if (TREE_CODE (var) == POINTER_PLUS_EXPR)
	    var = TREE_OPERAND (var, 0);
	  if (TREE_CODE (var) == ADDR_EXPR)
	    var = TREE_OPERAND (var, 0);
	  else
	    {
	      /* If this is a pointer or referenced based array
		 section, the var could be private in the outer
		 context e.g. on orphaned loop construct.  Pretend this
		 is private variable's outer reference.  */
	      ccode = OMP_CLAUSE_PRIVATE;
	      if (TREE_CODE (var) == INDIRECT_REF)
		var = TREE_OPERAND (var, 0);
	    }
	  orig_var = var;
	  if (is_variable_sized (var))
	    {
	      gcc_assert (DECL_HAS_VALUE_EXPR_P (var));
	      var = DECL_VALUE_EXPR (var);
	      gcc_assert (TREE_CODE (var) == INDIRECT_REF);
	      var = TREE_OPERAND (var, 0);
	      gcc_assert (DECL_P (var));
	    }
	}
      new_var = lookup_decl (var, ctx);
      if (var == OMP_CLAUSE_DECL (c)
	  && omp_privatize_by_reference (var))
	new_var = build_simple_mem_ref_loc (clause_loc, new_var);
      ref = build_outer_var_ref (var, ctx, ccode);
      code = OMP_CLAUSE_REDUCTION_CODE (c);

      /* reduction(-:var) sums up the partial results, so it acts
	 identically to reduction(+:var).  */
      if (code == MINUS_EXPR)
        code = PLUS_EXPR;

      bool is_truth_op = (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR);
      if (count == 1)
	{
	  tree addr = build_fold_addr_expr_loc (clause_loc, ref);

	  addr = save_expr (addr);
	  ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
	  tree new_var2 = new_var;
	  tree ref2 = ref;
	  if (is_truth_op)
	    {
	      tree zero = build_zero_cst (TREE_TYPE (new_var));
	      new_var2 = fold_build2_loc (clause_loc, NE_EXPR,
					  boolean_type_node, new_var, zero);
	      ref2 = fold_build2_loc (clause_loc, NE_EXPR, boolean_type_node,
				      ref, zero);
	    }
	  x = fold_build2_loc (clause_loc, code, TREE_TYPE (new_var2), ref2,
			       new_var2);
	  if (is_truth_op)
	    x = fold_convert (TREE_TYPE (new_var), x);
	  x = build2 (OMP_ATOMIC, void_type_node, addr, x);
	  OMP_ATOMIC_MEMORY_ORDER (x) = OMP_MEMORY_ORDER_RELAXED;
	  gimplify_and_add (x, stmt_seqp);
	  return;
	}
      else if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
	{
	  tree d = OMP_CLAUSE_DECL (c);
	  tree type = TREE_TYPE (d);
	  tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
	  tree i = create_tmp_var (TREE_TYPE (v));
	  tree ptype = build_pointer_type (TREE_TYPE (type));
	  tree bias = TREE_OPERAND (d, 1);
	  d = TREE_OPERAND (d, 0);
	  if (TREE_CODE (d) == POINTER_PLUS_EXPR)
	    {
	      tree b = TREE_OPERAND (d, 1);
	      b = maybe_lookup_decl (b, ctx);
	      if (b == NULL)
		{
		  b = TREE_OPERAND (d, 1);
		  b = maybe_lookup_decl_in_outer_ctx (b, ctx);
		}
	      if (integer_zerop (bias))
		bias = b;
	      else
		{
		  bias = fold_convert_loc (clause_loc, TREE_TYPE (b), bias);
		  bias = fold_build2_loc (clause_loc, PLUS_EXPR,
					  TREE_TYPE (b), b, bias);
		}
	      d = TREE_OPERAND (d, 0);
	    }
	  /* For ref build_outer_var_ref already performs this, so
	     only new_var needs a dereference.  */
	  if (TREE_CODE (d) == INDIRECT_REF)
	    {
	      new_var = build_simple_mem_ref_loc (clause_loc, new_var);
	      gcc_assert (omp_privatize_by_reference (var)
			  && var == orig_var);
	    }
	  else if (TREE_CODE (d) == ADDR_EXPR)
	    {
	      if (orig_var == var)
		{
		  new_var = build_fold_addr_expr (new_var);
		  ref = build_fold_addr_expr (ref);
		}
	    }
	  else
	    {
	      gcc_assert (orig_var == var);
	      if (omp_privatize_by_reference (var))
		ref = build_fold_addr_expr (ref);
	    }
	  if (DECL_P (v))
	    {
	      tree t = maybe_lookup_decl (v, ctx);
	      if (t)
		v = t;
	      else
		v = maybe_lookup_decl_in_outer_ctx (v, ctx);
	      gimplify_expr (&v, stmt_seqp, NULL, is_gimple_val, fb_rvalue);
	    }
	  if (!integer_zerop (bias))
	    {
	      bias = fold_convert_loc (clause_loc, sizetype, bias);
	      new_var = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
					 TREE_TYPE (new_var), new_var,
					 unshare_expr (bias));
	      ref = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
					 TREE_TYPE (ref), ref, bias);
	    }
	  new_var = fold_convert_loc (clause_loc, ptype, new_var);
	  ref = fold_convert_loc (clause_loc, ptype, ref);
	  tree m = create_tmp_var (ptype);
	  gimplify_assign (m, new_var, stmt_seqp);
	  new_var = m;
	  m = create_tmp_var (ptype);
	  gimplify_assign (m, ref, stmt_seqp);
	  ref = m;
	  gimplify_assign (i, build_int_cst (TREE_TYPE (v), 0), stmt_seqp);
	  tree body = create_artificial_label (UNKNOWN_LOCATION);
	  tree end = create_artificial_label (UNKNOWN_LOCATION);
	  gimple_seq_add_stmt (&sub_seq, gimple_build_label (body));
	  tree priv = build_simple_mem_ref_loc (clause_loc, new_var);
	  tree out = build_simple_mem_ref_loc (clause_loc, ref);
	  if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
	    {
	      tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
	      tree decl_placeholder
		= OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c);
	      SET_DECL_VALUE_EXPR (placeholder, out);
	      DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
	      SET_DECL_VALUE_EXPR (decl_placeholder, priv);
	      DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 1;
	      lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
	      gimple_seq_add_seq (&sub_seq,
				  OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
	      OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
	      OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
	      OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) = NULL;
	    }
	  else
	    {
	      tree out2 = out;
	      tree priv2 = priv;
	      if (is_truth_op)
		{
		  tree zero = build_zero_cst (TREE_TYPE (out));
		  out2 = fold_build2_loc (clause_loc, NE_EXPR,
					  boolean_type_node, out, zero);
		  priv2 = fold_build2_loc (clause_loc, NE_EXPR,
					   boolean_type_node, priv, zero);
		}
	      x = build2 (code, TREE_TYPE (out2), out2, priv2);
	      if (is_truth_op)
		x = fold_convert (TREE_TYPE (out), x);
	      out = unshare_expr (out);
	      gimplify_assign (out, x, &sub_seq);
	    }
	  gimple *g = gimple_build_assign (new_var, POINTER_PLUS_EXPR, new_var,
					   TYPE_SIZE_UNIT (TREE_TYPE (type)));
	  gimple_seq_add_stmt (&sub_seq, g);
	  g = gimple_build_assign (ref, POINTER_PLUS_EXPR, ref,
				   TYPE_SIZE_UNIT (TREE_TYPE (type)));
	  gimple_seq_add_stmt (&sub_seq, g);
	  g = gimple_build_assign (i, PLUS_EXPR, i,
				   build_int_cst (TREE_TYPE (i), 1));
	  gimple_seq_add_stmt (&sub_seq, g);
	  g = gimple_build_cond (LE_EXPR, i, v, body, end);
	  gimple_seq_add_stmt (&sub_seq, g);
	  gimple_seq_add_stmt (&sub_seq, gimple_build_label (end));
	}
      else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
	{
	  tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);

	  if (omp_privatize_by_reference (var)
	      && !useless_type_conversion_p (TREE_TYPE (placeholder),
					     TREE_TYPE (ref)))
	    ref = build_fold_addr_expr_loc (clause_loc, ref);
	  SET_DECL_VALUE_EXPR (placeholder, ref);
	  DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
	  lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
	  gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
	  OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
	  OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
	}
      else
	{
	  tree new_var2 = new_var;
	  tree ref2 = ref;
	  if (is_truth_op)
	    {
	      tree zero = build_zero_cst (TREE_TYPE (new_var));
	      new_var2 = fold_build2_loc (clause_loc, NE_EXPR,
					  boolean_type_node, new_var, zero);
	      ref2 = fold_build2_loc (clause_loc, NE_EXPR, boolean_type_node,
				      ref, zero);
	    }
	  x = build2 (code, TREE_TYPE (ref), ref2, new_var2);
	  if (is_truth_op)
	    x = fold_convert (TREE_TYPE (new_var), x);
	  ref = build_outer_var_ref (var, ctx);
	  gimplify_assign (ref, x, &sub_seq);
	}
    }

  stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
			    0);
  gimple_seq_add_stmt (stmt_seqp, stmt);

  gimple_seq_add_seq (stmt_seqp, sub_seq);

  if (clist)
    {
      gimple_seq_add_seq (stmt_seqp, *clist);
      *clist = NULL;
    }

  stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
			    0);
  gimple_seq_add_stmt (stmt_seqp, stmt);
}


/* Generate code to implement the COPYPRIVATE clauses.  */

static void
lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
			    omp_context *ctx)
{
  tree c;

  for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    {
      tree var, new_var, ref, x;
      bool by_ref;
      location_t clause_loc = OMP_CLAUSE_LOCATION (c);

      if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
	continue;

      var = OMP_CLAUSE_DECL (c);
      by_ref = use_pointer_for_field (var, NULL);

      ref = build_sender_ref (var, ctx);
      x = new_var = lookup_decl_in_outer_ctx (var, ctx);
      if (by_ref)
	{
	  x = build_fold_addr_expr_loc (clause_loc, new_var);
	  x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
	}
      gimplify_assign (ref, x, slist);

      ref = build_receiver_ref (var, false, ctx);
      if (by_ref)
	{
	  ref = fold_convert_loc (clause_loc,
				  build_pointer_type (TREE_TYPE (new_var)),
				  ref);
	  ref = build_fold_indirect_ref_loc (clause_loc, ref);
	}
      if (omp_privatize_by_reference (var))
	{
	  ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
	  ref = build_simple_mem_ref_loc (clause_loc, ref);
	  new_var = build_simple_mem_ref_loc (clause_loc, new_var);
	}
      x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
      gimplify_and_add (x, rlist);
    }
}


/* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
   and REDUCTION from the sender (aka parent) side.  */

static void
lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
    		    omp_context *ctx)
{
  tree c, t;
  int ignored_looptemp = 0;
  bool is_taskloop = false;

  /* For taskloop, ignore first two _looptemp_ clauses, those are initialized
     by GOMP_taskloop.  */
  if (is_task_ctx (ctx) && gimple_omp_task_taskloop_p (ctx->stmt))
    {
      ignored_looptemp = 2;
      is_taskloop = true;
    }

  for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    {
      tree val, ref, x, var;
      bool by_ref, do_in = false, do_out = false;
      location_t clause_loc = OMP_CLAUSE_LOCATION (c);

      switch (OMP_CLAUSE_CODE (c))
	{
	case OMP_CLAUSE_PRIVATE:
	  if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
	    break;
	  continue;
	case OMP_CLAUSE_FIRSTPRIVATE:
	case OMP_CLAUSE_COPYIN:
	case OMP_CLAUSE_LASTPRIVATE:
	case OMP_CLAUSE_IN_REDUCTION:
	case OMP_CLAUSE__REDUCTEMP_:
	  break;
	case OMP_CLAUSE_REDUCTION:
	  if (is_task_ctx (ctx) || OMP_CLAUSE_REDUCTION_TASK (c))
	    continue;
	  break;
	case OMP_CLAUSE_SHARED:
	  if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
	    break;
	  continue;
	case OMP_CLAUSE__LOOPTEMP_:
	  if (ignored_looptemp)
	    {
	      ignored_looptemp--;
	      continue;
	    }
	  break;
	default:
	  continue;
	}

      val = OMP_CLAUSE_DECL (c);
      if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
	   || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
	  && TREE_CODE (val) == MEM_REF)
	{
	  val = TREE_OPERAND (val, 0);
	  if (TREE_CODE (val) == POINTER_PLUS_EXPR)
	    val = TREE_OPERAND (val, 0);
	  if (TREE_CODE (val) == INDIRECT_REF
	      || TREE_CODE (val) == ADDR_EXPR)
	    val = TREE_OPERAND (val, 0);
	  if (is_variable_sized (val))
	    continue;
	}

      /* For OMP_CLAUSE_SHARED_FIRSTPRIVATE, look beyond the
	 outer taskloop region.  */
      omp_context *ctx_for_o = ctx;
      if (is_taskloop
	  && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
	  && OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
	ctx_for_o = ctx->outer;

      var = lookup_decl_in_outer_ctx (val, ctx_for_o);

      if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
	  && is_global_var (var)
	  && (val == OMP_CLAUSE_DECL (c)
	      || !is_task_ctx (ctx)
	      || (TREE_CODE (TREE_TYPE (val)) != POINTER_TYPE
		  && (TREE_CODE (TREE_TYPE (val)) != REFERENCE_TYPE
		      || (TREE_CODE (TREE_TYPE (TREE_TYPE (val)))
			  != POINTER_TYPE)))))
	continue;

      t = omp_member_access_dummy_var (var);
      if (t)
	{
	  var = DECL_VALUE_EXPR (var);
	  tree o = maybe_lookup_decl_in_outer_ctx (t, ctx_for_o);
	  if (o != t)
	    var = unshare_and_remap (var, t, o);
	  else
	    var = unshare_expr (var);
	}

      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
	{
	  /* Handle taskloop firstprivate/lastprivate, where the
	     lastprivate on GIMPLE_OMP_TASK is represented as
	     OMP_CLAUSE_SHARED_FIRSTPRIVATE.  */
	  tree f = lookup_sfield ((splay_tree_key) &DECL_UID (val), ctx);
	  x = omp_build_component_ref (ctx->sender_decl, f);
	  if (use_pointer_for_field (val, ctx))
	    var = build_fold_addr_expr (var);
	  gimplify_assign (x, var, ilist);
	  DECL_ABSTRACT_ORIGIN (f) = NULL;
	  continue;
	}

      if (((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
	    && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION)
	   || val == OMP_CLAUSE_DECL (c))
	  && is_variable_sized (val))
	continue;
      by_ref = use_pointer_for_field (val, NULL);

      switch (OMP_CLAUSE_CODE (c))
	{
	case OMP_CLAUSE_FIRSTPRIVATE:
	  if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)
	      && !by_ref
	      && is_task_ctx (ctx))
	    suppress_warning (var);
	  do_in = true;
	  break;

	case OMP_CLAUSE_PRIVATE:
	case OMP_CLAUSE_COPYIN:
	case OMP_CLAUSE__LOOPTEMP_:
	case OMP_CLAUSE__REDUCTEMP_:
	  do_in = true;
	  break;

	case OMP_CLAUSE_LASTPRIVATE:
	  if (by_ref || omp_privatize_by_reference (val))
	    {
	      if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
		continue;
	      do_in = true;
	    }
	  else
	    {
	      do_out = true;
	      if (lang_hooks.decls.omp_private_outer_ref (val))
		do_in = true;
	    }
	  break;

	case OMP_CLAUSE_REDUCTION:
	case OMP_CLAUSE_IN_REDUCTION:
	  do_in = true;
	  if (val == OMP_CLAUSE_DECL (c))
	    {
	      if (is_task_ctx (ctx))
		by_ref = use_pointer_for_field (val, ctx);
	      else
		do_out = !(by_ref || omp_privatize_by_reference (val));
	    }
	  else
	    by_ref = TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE;
	  break;

	default:
	  gcc_unreachable ();
	}

      if (do_in)
	{
	  ref = build_sender_ref (val, ctx);
	  x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
	  gimplify_assign (ref, x, ilist);
	  if (is_task_ctx (ctx))
	    DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
	}

      if (do_out)
	{
	  ref = build_sender_ref (val, ctx);
	  gimplify_assign (var, ref, olist);
	}
    }
}

/* Generate code to implement SHARED from the sender (aka parent)
   side.  This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
   list things that got automatically shared.  */

static void
lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
{
  tree var, ovar, nvar, t, f, x, record_type;

  if (ctx->record_type == NULL)
    return;

  record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
  for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
    {
      ovar = DECL_ABSTRACT_ORIGIN (f);
      if (!ovar || TREE_CODE (ovar) == FIELD_DECL)
	continue;

      nvar = maybe_lookup_decl (ovar, ctx);
      if (!nvar
	  || !DECL_HAS_VALUE_EXPR_P (nvar)
	  || (ctx->allocate_map
	      && ctx->allocate_map->get (ovar)))
	continue;

      /* If CTX is a nested parallel directive.  Find the immediately
	 enclosing parallel or workshare construct that contains a
	 mapping for OVAR.  */
      var = lookup_decl_in_outer_ctx (ovar, ctx);

      t = omp_member_access_dummy_var (var);
      if (t)
	{
	  var = DECL_VALUE_EXPR (var);
	  tree o = maybe_lookup_decl_in_outer_ctx (t, ctx);
	  if (o != t)
	    var = unshare_and_remap (var, t, o);
	  else
	    var = unshare_expr (var);
	}

      if (use_pointer_for_field (ovar, ctx))
	{
	  x = build_sender_ref (ovar, ctx);
	  if (TREE_CODE (TREE_TYPE (f)) == ARRAY_TYPE
	      && TREE_TYPE (f) == TREE_TYPE (ovar))
	    {
	      gcc_assert (is_parallel_ctx (ctx)
			  && DECL_ARTIFICIAL (ovar));
	      /* _condtemp_ clause.  */
	      var = build_constructor (TREE_TYPE (x), NULL);
	    }
	  else
	    var = build_fold_addr_expr (var);
	  gimplify_assign (x, var, ilist);
	}
      else
	{
	  x = build_sender_ref (ovar, ctx);
	  gimplify_assign (x, var, ilist);

	  if (!TREE_READONLY (var)
	      /* We don't need to receive a new reference to a result
	         or parm decl.  In fact we may not store to it as we will
		 invalidate any pending RSO and generate wrong gimple
		 during inlining.  */
	      && !((TREE_CODE (var) == RESULT_DECL
		    || TREE_CODE (var) == PARM_DECL)
		   && DECL_BY_REFERENCE (var)))
	    {
	      x = build_sender_ref (ovar, ctx);
	      gimplify_assign (var, x, olist);
	    }
	}
    }
}

/* Emit an OpenACC head marker call, encapulating the partitioning and
   other information that must be processed by the target compiler.
   Return the maximum number of dimensions the associated loop might
   be partitioned over.  */

static unsigned
lower_oacc_head_mark (location_t loc, tree ddvar, tree clauses,
		      gimple_seq *seq, omp_context *ctx)
{
  unsigned levels = 0;
  unsigned tag = 0;
  tree gang_static = NULL_TREE;
  auto_vec<tree, 5> args;

  args.quick_push (build_int_cst
		   (integer_type_node, IFN_UNIQUE_OACC_HEAD_MARK));
  args.quick_push (ddvar);
  for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    {
      switch (OMP_CLAUSE_CODE (c))
	{
	case OMP_CLAUSE_GANG:
	  tag |= OLF_DIM_GANG;
	  gang_static = OMP_CLAUSE_GANG_STATIC_EXPR (c);
	  /* static:* is represented by -1, and we can ignore it, as
	     scheduling is always static.  */
	  if (gang_static && integer_minus_onep (gang_static))
	    gang_static = NULL_TREE;
	  levels++;
	  break;

	case OMP_CLAUSE_WORKER:
	  tag |= OLF_DIM_WORKER;
	  levels++;
	  break;

	case OMP_CLAUSE_VECTOR:
	  tag |= OLF_DIM_VECTOR;
	  levels++;
	  break;

	case OMP_CLAUSE_SEQ:
	  tag |= OLF_SEQ;
	  break;

	case OMP_CLAUSE_AUTO:
	  tag |= OLF_AUTO;
	  break;

	case OMP_CLAUSE_INDEPENDENT:
	  tag |= OLF_INDEPENDENT;
	  break;

	case OMP_CLAUSE_TILE:
	  tag |= OLF_TILE;
	  break;

	default:
	  continue;
	}
    }

  if (gang_static)
    {
      if (DECL_P (gang_static))
	gang_static = build_outer_var_ref (gang_static, ctx);
      tag |= OLF_GANG_STATIC;
    }

  omp_context *tgt = enclosing_target_ctx (ctx);
  if (!tgt || is_oacc_parallel_or_serial (tgt))
    ;
  else if (is_oacc_kernels (tgt))
    /* Not using this loops handling inside OpenACC 'kernels' regions.  */
    gcc_unreachable ();
  else if (is_oacc_kernels_decomposed_part (tgt))
    ;
  else
    gcc_unreachable ();

  /* In a parallel region, loops are implicitly INDEPENDENT.  */
  if (!tgt || is_oacc_parallel_or_serial (tgt))
    tag |= OLF_INDEPENDENT;

  /* Loops inside OpenACC 'kernels' decomposed parts' regions are expected to
     have an explicit 'seq' or 'independent' clause, and no 'auto' clause.  */
  if (tgt && is_oacc_kernels_decomposed_part (tgt))
    {
      gcc_assert (tag & (OLF_SEQ | OLF_INDEPENDENT));
      gcc_assert (!(tag & OLF_AUTO));
    }

  if (tag & OLF_TILE)
    /* Tiling could use all 3 levels.  */ 
    levels = 3;
  else
    {
      /* A loop lacking SEQ, GANG, WORKER and/or VECTOR could be AUTO.
	 Ensure at least one level, or 2 for possible auto
	 partitioning */
      bool maybe_auto = !(tag & (((GOMP_DIM_MASK (GOMP_DIM_MAX) - 1)
				  << OLF_DIM_BASE) | OLF_SEQ));

      if (levels < 1u + maybe_auto)
	levels = 1u + maybe_auto;
    }

  args.quick_push (build_int_cst (integer_type_node, levels));
  args.quick_push (build_int_cst (integer_type_node, tag));
  if (gang_static)
    args.quick_push (gang_static);

  gcall *call = gimple_build_call_internal_vec (IFN_UNIQUE, args);
  gimple_set_location (call, loc);
  gimple_set_lhs (call, ddvar);
  gimple_seq_add_stmt (seq, call);

  return levels;
}

/* Emit an OpenACC lopp head or tail marker to SEQ.  LEVEL is the
   partitioning level of the enclosed region.  */ 

static void
lower_oacc_loop_marker (location_t loc, tree ddvar, bool head,
			tree tofollow, gimple_seq *seq)
{
  int marker_kind = (head ? IFN_UNIQUE_OACC_HEAD_MARK
		     : IFN_UNIQUE_OACC_TAIL_MARK);
  tree marker = build_int_cst (integer_type_node, marker_kind);
  int nargs = 2 + (tofollow != NULL_TREE);
  gcall *call = gimple_build_call_internal (IFN_UNIQUE, nargs,
					    marker, ddvar, tofollow);
  gimple_set_location (call, loc);
  gimple_set_lhs (call, ddvar);
  gimple_seq_add_stmt (seq, call);
}

/* Generate the before and after OpenACC loop sequences.  CLAUSES are
   the loop clauses, from which we extract reductions.  Initialize
   HEAD and TAIL.  */

static void
lower_oacc_head_tail (location_t loc, tree clauses, gcall *private_marker,
		      gimple_seq *head, gimple_seq *tail, omp_context *ctx)
{
  bool inner = false;
  tree ddvar = create_tmp_var (integer_type_node, ".data_dep");
  gimple_seq_add_stmt (head, gimple_build_assign (ddvar, integer_zero_node));

  unsigned count = lower_oacc_head_mark (loc, ddvar, clauses, head, ctx);

  if (private_marker)
    {
      gimple_set_location (private_marker, loc);
      gimple_call_set_lhs (private_marker, ddvar);
      gimple_call_set_arg (private_marker, 1, ddvar);
    }

  tree fork_kind = build_int_cst (unsigned_type_node, IFN_UNIQUE_OACC_FORK);
  tree join_kind = build_int_cst (unsigned_type_node, IFN_UNIQUE_OACC_JOIN);

  gcc_assert (count);
  for (unsigned done = 1; count; count--, done++)
    {
      gimple_seq fork_seq = NULL;
      gimple_seq join_seq = NULL;

      tree place = build_int_cst (integer_type_node, -1);
      gcall *fork = gimple_build_call_internal (IFN_UNIQUE, 3,
						fork_kind, ddvar, place);
      gimple_set_location (fork, loc);
      gimple_set_lhs (fork, ddvar);

      gcall *join = gimple_build_call_internal (IFN_UNIQUE, 3,
						join_kind, ddvar, place);
      gimple_set_location (join, loc);
      gimple_set_lhs (join, ddvar);

      /* Mark the beginning of this level sequence.  */
      if (inner)
	lower_oacc_loop_marker (loc, ddvar, true,
				build_int_cst (integer_type_node, count),
				&fork_seq);
      lower_oacc_loop_marker (loc, ddvar, false,
			      build_int_cst (integer_type_node, done),
			      &join_seq);

      lower_oacc_reductions (loc, clauses, place, inner,
			     fork, (count == 1) ? private_marker : NULL,
			     join, &fork_seq, &join_seq,  ctx);

      /* Append this level to head. */
      gimple_seq_add_seq (head, fork_seq);
      /* Prepend it to tail.  */
      gimple_seq_add_seq (&join_seq, *tail);
      *tail = join_seq;

      inner = true;
    }

  /* Mark the end of the sequence.  */
  lower_oacc_loop_marker (loc, ddvar, true, NULL_TREE, head);
  lower_oacc_loop_marker (loc, ddvar, false, NULL_TREE, tail);
}

/* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
   catch handler and return it.  This prevents programs from violating the
   structured block semantics with throws.  */

static gimple_seq
maybe_catch_exception (gimple_seq body)
{
  gimple *g;
  tree decl;

  if (!flag_exceptions)
    return body;

  if (lang_hooks.eh_protect_cleanup_actions != NULL)
    decl = lang_hooks.eh_protect_cleanup_actions ();
  else
    decl = builtin_decl_explicit (BUILT_IN_TRAP);

  g = gimple_build_eh_must_not_throw (decl);
  g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
      			GIMPLE_TRY_CATCH);

 return gimple_seq_alloc_with_stmt (g);
}


/* Routines to lower OMP directives into OMP-GIMPLE.  */

/* If ctx is a worksharing context inside of a cancellable parallel
   region and it isn't nowait, add lhs to its GIMPLE_OMP_RETURN
   and conditional branch to parallel's cancel_label to handle
   cancellation in the implicit barrier.  */

static void
maybe_add_implicit_barrier_cancel (omp_context *ctx, gimple *omp_return,
				   gimple_seq *body)
{
  gcc_assert (gimple_code (omp_return) == GIMPLE_OMP_RETURN);
  if (gimple_omp_return_nowait_p (omp_return))
    return;
  for (omp_context *outer = ctx->outer; outer; outer = outer->outer)
    if (gimple_code (outer->stmt) == GIMPLE_OMP_PARALLEL
	&& outer->cancellable)
      {
	tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
	tree c_bool_type = TREE_TYPE (TREE_TYPE (fndecl));
	tree lhs = create_tmp_var (c_bool_type);
	gimple_omp_return_set_lhs (omp_return, lhs);
	tree fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
	gimple *g = gimple_build_cond (NE_EXPR, lhs,
				       fold_convert (c_bool_type,
						     boolean_false_node),
				       outer->cancel_label, fallthru_label);
	gimple_seq_add_stmt (body, g);
	gimple_seq_add_stmt (body, gimple_build_label (fallthru_label));
      }
    else if (gimple_code (outer->stmt) != GIMPLE_OMP_TASKGROUP
	     && gimple_code (outer->stmt) != GIMPLE_OMP_SCOPE)
      return;
}

/* Find the first task_reduction or reduction clause or return NULL
   if there are none.  */

static inline tree
omp_task_reductions_find_first (tree clauses, enum tree_code code,
				enum omp_clause_code ccode)
{
  while (1)
    {
      clauses = omp_find_clause (clauses, ccode);
      if (clauses == NULL_TREE)
	return NULL_TREE;
      if (ccode != OMP_CLAUSE_REDUCTION
	  || code == OMP_TASKLOOP
	  || OMP_CLAUSE_REDUCTION_TASK (clauses))
	return clauses;
      clauses = OMP_CLAUSE_CHAIN (clauses);
    }
}

static void lower_omp_task_reductions (omp_context *, enum tree_code, tree,
				       gimple_seq *, gimple_seq *);

/* Lower the OpenMP sections directive in the current statement in GSI_P.
   CTX is the enclosing OMP context for the current statement.  */

static void
lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
  tree block, control;
  gimple_stmt_iterator tgsi;
  gomp_sections *stmt;
  gimple *t;
  gbind *new_stmt, *bind;
  gimple_seq ilist, dlist, olist, tred_dlist = NULL, clist = NULL, new_body;

  stmt = as_a <gomp_sections *> (gsi_stmt (*gsi_p));

  push_gimplify_context ();

  dlist = NULL;
  ilist = NULL;

  tree rclauses
    = omp_task_reductions_find_first (gimple_omp_sections_clauses (stmt),
				      OMP_SECTIONS, OMP_CLAUSE_REDUCTION);
  tree rtmp = NULL_TREE;
  if (rclauses)
    {
      tree type = build_pointer_type (pointer_sized_int_node);
      tree temp = create_tmp_var (type);
      tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
      OMP_CLAUSE_DECL (c) = temp;
      OMP_CLAUSE_CHAIN (c) = gimple_omp_sections_clauses (stmt);
      gimple_omp_sections_set_clauses (stmt, c);
      lower_omp_task_reductions (ctx, OMP_SECTIONS,
				 gimple_omp_sections_clauses (stmt),
				 &ilist, &tred_dlist);
      rclauses = c;
      rtmp = make_ssa_name (type);
      gimple_seq_add_stmt (&ilist, gimple_build_assign (rtmp, temp));
    }

  tree *clauses_ptr = gimple_omp_sections_clauses_ptr (stmt);
  lower_lastprivate_conditional_clauses (clauses_ptr, ctx);

  lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
      			   &ilist, &dlist, ctx, NULL);

  control = create_tmp_var (unsigned_type_node, ".section");
  gimple_omp_sections_set_control (stmt, control);

  new_body = gimple_omp_body (stmt);
  gimple_omp_set_body (stmt, NULL);
  tgsi = gsi_start (new_body);
  for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
    {
      omp_context *sctx;
      gimple *sec_start;

      sec_start = gsi_stmt (tgsi);
      sctx = maybe_lookup_ctx (sec_start);
      gcc_assert (sctx);

      lower_omp (gimple_omp_body_ptr (sec_start), sctx);
      gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
			    GSI_CONTINUE_LINKING);
      gimple_omp_set_body (sec_start, NULL);

      if (gsi_one_before_end_p (tgsi))
	{
	  gimple_seq l = NULL;
	  lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
				     &ilist, &l, &clist, ctx);
	  gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
	  gimple_omp_section_set_last (sec_start);
	}

      gsi_insert_after (&tgsi, gimple_build_omp_return (false),
			GSI_CONTINUE_LINKING);
    }

  block = make_node (BLOCK);
  bind = gimple_build_bind (NULL, new_body, block);

  olist = NULL;
  lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist,
			   &clist, ctx);
  if (clist)
    {
      tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
      gcall *g = gimple_build_call (fndecl, 0);
      gimple_seq_add_stmt (&olist, g);
      gimple_seq_add_seq (&olist, clist);
      fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
      g = gimple_build_call (fndecl, 0);
      gimple_seq_add_stmt (&olist, g);
    }

  block = make_node (BLOCK);
  new_stmt = gimple_build_bind (NULL, NULL, block);
  gsi_replace (gsi_p, new_stmt, true);

  pop_gimplify_context (new_stmt);
  gimple_bind_append_vars (new_stmt, ctx->block_vars);
  BLOCK_VARS (block) = gimple_bind_vars (bind);
  if (BLOCK_VARS (block))
    TREE_USED (block) = 1;

  new_body = NULL;
  gimple_seq_add_seq (&new_body, ilist);
  gimple_seq_add_stmt (&new_body, stmt);
  gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
  gimple_seq_add_stmt (&new_body, bind);

  t = gimple_build_omp_continue (control, control);
  gimple_seq_add_stmt (&new_body, t);

  gimple_seq_add_seq (&new_body, olist);
  if (ctx->cancellable)
    gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
  gimple_seq_add_seq (&new_body, dlist);

  new_body = maybe_catch_exception (new_body);

  bool nowait = omp_find_clause (gimple_omp_sections_clauses (stmt),
				 OMP_CLAUSE_NOWAIT) != NULL_TREE;
  t = gimple_build_omp_return (nowait);
  gimple_seq_add_stmt (&new_body, t);
  gimple_seq_add_seq (&new_body, tred_dlist);
  maybe_add_implicit_barrier_cancel (ctx, t, &new_body);

  if (rclauses)
    OMP_CLAUSE_DECL (rclauses) = rtmp;

  gimple_bind_set_body (new_stmt, new_body);
}


/* A subroutine of lower_omp_single.  Expand the simple form of
   a GIMPLE_OMP_SINGLE, without a copyprivate clause:

     	if (GOMP_single_start ())
	  BODY;
	[ GOMP_barrier (); ]	-> unless 'nowait' is present.

  FIXME.  It may be better to delay expanding the logic of this until
  pass_expand_omp.  The expanded logic may make the job more difficult
  to a synchronization analysis pass.  */

static void
lower_omp_single_simple (gomp_single *single_stmt, gimple_seq *pre_p)
{
  location_t loc = gimple_location (single_stmt);
  tree tlabel = create_artificial_label (loc);
  tree flabel = create_artificial_label (loc);
  gimple *call, *cond;
  tree lhs, decl;

  decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
  lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)));
  call = gimple_build_call (decl, 0);
  gimple_call_set_lhs (call, lhs);
  gimple_seq_add_stmt (pre_p, call);

  cond = gimple_build_cond (EQ_EXPR, lhs,
			    fold_convert_loc (loc, TREE_TYPE (lhs),
					      boolean_true_node),
			    tlabel, flabel);
  gimple_seq_add_stmt (pre_p, cond);
  gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
  gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
  gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
}


/* A subroutine of lower_omp_single.  Expand the simple form of
   a GIMPLE_OMP_SINGLE, with a copyprivate clause:

	#pragma omp single copyprivate (a, b, c)

   Create a new structure to hold copies of 'a', 'b' and 'c' and emit:

      {
	if ((copyout_p = GOMP_single_copy_start ()) == NULL)
	  {
	    BODY;
	    copyout.a = a;
	    copyout.b = b;
	    copyout.c = c;
	    GOMP_single_copy_end (&copyout);
	  }
	else
	  {
	    a = copyout_p->a;
	    b = copyout_p->b;
	    c = copyout_p->c;
	  }
	GOMP_barrier ();
      }

  FIXME.  It may be better to delay expanding the logic of this until
  pass_expand_omp.  The expanded logic may make the job more difficult
  to a synchronization analysis pass.  */

static void
lower_omp_single_copy (gomp_single *single_stmt, gimple_seq *pre_p,
		       omp_context *ctx)
{
  tree ptr_type, t, l0, l1, l2, bfn_decl;
  gimple_seq copyin_seq;
  location_t loc = gimple_location (single_stmt);

  ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");

  ptr_type = build_pointer_type (ctx->record_type);
  ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");

  l0 = create_artificial_label (loc);
  l1 = create_artificial_label (loc);
  l2 = create_artificial_label (loc);

  bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
  t = build_call_expr_loc (loc, bfn_decl, 0);
  t = fold_convert_loc (loc, ptr_type, t);
  gimplify_assign (ctx->receiver_decl, t, pre_p);

  t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
	      build_int_cst (ptr_type, 0));
  t = build3 (COND_EXPR, void_type_node, t,
	      build_and_jump (&l0), build_and_jump (&l1));
  gimplify_and_add (t, pre_p);

  gimple_seq_add_stmt (pre_p, gimple_build_label (l0));

  gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));

  copyin_seq = NULL;
  lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
			      &copyin_seq, ctx);

  t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
  bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
  t = build_call_expr_loc (loc, bfn_decl, 1, t);
  gimplify_and_add (t, pre_p);

  t = build_and_jump (&l2);
  gimplify_and_add (t, pre_p);

  gimple_seq_add_stmt (pre_p, gimple_build_label (l1));

  gimple_seq_add_seq (pre_p, copyin_seq);

  gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
}


/* Expand code for an OpenMP single directive.  */

static void
lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
  tree block;
  gomp_single *single_stmt = as_a <gomp_single *> (gsi_stmt (*gsi_p));
  gbind *bind;
  gimple_seq bind_body, bind_body_tail = NULL, dlist;

  push_gimplify_context ();

  block = make_node (BLOCK);
  bind = gimple_build_bind (NULL, NULL, block);
  gsi_replace (gsi_p, bind, true);
  bind_body = NULL;
  dlist = NULL;
  lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
			   &bind_body, &dlist, ctx, NULL);
  lower_omp (gimple_omp_body_ptr (single_stmt), ctx);

  gimple_seq_add_stmt (&bind_body, single_stmt);

  if (ctx->record_type)
    lower_omp_single_copy (single_stmt, &bind_body, ctx);
  else
    lower_omp_single_simple (single_stmt, &bind_body);

  gimple_omp_set_body (single_stmt, NULL);

  gimple_seq_add_seq (&bind_body, dlist);

  bind_body = maybe_catch_exception (bind_body);

  bool nowait = omp_find_clause (gimple_omp_single_clauses (single_stmt),
				 OMP_CLAUSE_NOWAIT) != NULL_TREE;
  gimple *g = gimple_build_omp_return (nowait);
  gimple_seq_add_stmt (&bind_body_tail, g);
  maybe_add_implicit_barrier_cancel (ctx, g, &bind_body_tail);
  if (ctx->record_type)
    {
      gimple_stmt_iterator gsi = gsi_start (bind_body_tail);
      tree clobber = build_clobber (ctx->record_type);
      gsi_insert_after (&gsi, gimple_build_assign (ctx->sender_decl,
						   clobber), GSI_SAME_STMT);
    }
  gimple_seq_add_seq (&bind_body, bind_body_tail);
  gimple_bind_set_body (bind, bind_body);

  pop_gimplify_context (bind);

  gimple_bind_append_vars (bind, ctx->block_vars);
  BLOCK_VARS (block) = ctx->block_vars;
  if (BLOCK_VARS (block))
    TREE_USED (block) = 1;
}


/* Lower code for an OMP scope directive.  */

static void
lower_omp_scope (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
  tree block;
  gimple *scope_stmt = gsi_stmt (*gsi_p);
  gbind *bind;
  gimple_seq bind_body, bind_body_tail = NULL, dlist;
  gimple_seq tred_dlist = NULL;

  push_gimplify_context ();

  block = make_node (BLOCK);
  bind = gimple_build_bind (NULL, NULL, block);
  gsi_replace (gsi_p, bind, true);
  bind_body = NULL;
  dlist = NULL;

  tree rclauses
    = omp_task_reductions_find_first (gimple_omp_scope_clauses (scope_stmt),
				      OMP_SCOPE, OMP_CLAUSE_REDUCTION);
  if (rclauses)
    {
      tree type = build_pointer_type (pointer_sized_int_node);
      tree temp = create_tmp_var (type);
      tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
      OMP_CLAUSE_DECL (c) = temp;
      OMP_CLAUSE_CHAIN (c) = gimple_omp_scope_clauses (scope_stmt);
      gimple_omp_scope_set_clauses (scope_stmt, c);
      lower_omp_task_reductions (ctx, OMP_SCOPE,
				 gimple_omp_scope_clauses (scope_stmt),
				 &bind_body, &tred_dlist);
      rclauses = c;
      tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_SCOPE_START);
      gimple *stmt = gimple_build_call (fndecl, 1, temp);
      gimple_seq_add_stmt (&bind_body, stmt);
    }

  lower_rec_input_clauses (gimple_omp_scope_clauses (scope_stmt),
			   &bind_body, &dlist, ctx, NULL);
  lower_omp (gimple_omp_body_ptr (scope_stmt), ctx);

  gimple_seq_add_stmt (&bind_body, scope_stmt);

  gimple_seq_add_seq (&bind_body, gimple_omp_body (scope_stmt));

  gimple_omp_set_body (scope_stmt, NULL);

  gimple_seq clist = NULL;
  lower_reduction_clauses (gimple_omp_scope_clauses (scope_stmt),
			   &bind_body, &clist, ctx);
  if (clist)
    {
      tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
      gcall *g = gimple_build_call (fndecl, 0);
      gimple_seq_add_stmt (&bind_body, g);
      gimple_seq_add_seq (&bind_body, clist);
      fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
      g = gimple_build_call (fndecl, 0);
      gimple_seq_add_stmt (&bind_body, g);
    }

  gimple_seq_add_seq (&bind_body, dlist);

  bind_body = maybe_catch_exception (bind_body);

  bool nowait = omp_find_clause (gimple_omp_scope_clauses (scope_stmt),
				 OMP_CLAUSE_NOWAIT) != NULL_TREE;
  gimple *g = gimple_build_omp_return (nowait);
  gimple_seq_add_stmt (&bind_body_tail, g);
  gimple_seq_add_seq (&bind_body_tail, tred_dlist);
  maybe_add_implicit_barrier_cancel (ctx, g, &bind_body_tail);
  if (ctx->record_type)
    {
      gimple_stmt_iterator gsi = gsi_start (bind_body_tail);
      tree clobber = build_clobber (ctx->record_type);
      gsi_insert_after (&gsi, gimple_build_assign (ctx->sender_decl,
						   clobber), GSI_SAME_STMT);
    }
  gimple_seq_add_seq (&bind_body, bind_body_tail);

  gimple_bind_set_body (bind, bind_body);

  pop_gimplify_context (bind);

  gimple_bind_append_vars (bind, ctx->block_vars);
  BLOCK_VARS (block) = ctx->block_vars;
  if (BLOCK_VARS (block))
    TREE_USED (block) = 1;
}
/* Expand code for an OpenMP master or masked directive.  */

static void
lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
  tree block, lab = NULL, x, bfn_decl;
  gimple *stmt = gsi_stmt (*gsi_p);
  gbind *bind;
  location_t loc = gimple_location (stmt);
  gimple_seq tseq;
  tree filter = integer_zero_node;

  push_gimplify_context ();

  if (gimple_code (stmt) == GIMPLE_OMP_MASKED)
    {
      filter = omp_find_clause (gimple_omp_masked_clauses (stmt),
				OMP_CLAUSE_FILTER);
      if (filter)
	filter = fold_convert (integer_type_node,
			       OMP_CLAUSE_FILTER_EXPR (filter));
      else
	filter = integer_zero_node;
    }
  block = make_node (BLOCK);
  bind = gimple_build_bind (NULL, NULL, block);
  gsi_replace (gsi_p, bind, true);
  gimple_bind_add_stmt (bind, stmt);

  bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
  x = build_call_expr_loc (loc, bfn_decl, 0);
  x = build2 (EQ_EXPR, boolean_type_node, x, filter);
  x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
  tseq = NULL;
  gimplify_and_add (x, &tseq);
  gimple_bind_add_seq (bind, tseq);

  lower_omp (gimple_omp_body_ptr (stmt), ctx);
  gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
  gimple_bind_add_seq (bind, gimple_omp_body (stmt));
  gimple_omp_set_body (stmt, NULL);

  gimple_bind_add_stmt (bind, gimple_build_label (lab));

  gimple_bind_add_stmt (bind, gimple_build_omp_return (true));

  pop_gimplify_context (bind);

  gimple_bind_append_vars (bind, ctx->block_vars);
  BLOCK_VARS (block) = ctx->block_vars;
}

/* Helper function for lower_omp_task_reductions.  For a specific PASS
   find out the current clause it should be processed, or return false
   if all have been processed already.  */

static inline bool
omp_task_reduction_iterate (int pass, enum tree_code code,
			    enum omp_clause_code ccode, tree *c, tree *decl,
			    tree *type, tree *next)
{
  for (; *c; *c = omp_find_clause (OMP_CLAUSE_CHAIN (*c), ccode))
    {
      if (ccode == OMP_CLAUSE_REDUCTION
	  && code != OMP_TASKLOOP
	  && !OMP_CLAUSE_REDUCTION_TASK (*c))
	continue;
      *decl = OMP_CLAUSE_DECL (*c);
      *type = TREE_TYPE (*decl);
      if (TREE_CODE (*decl) == MEM_REF)
	{
	  if (pass != 1)
	    continue;
	}
      else
	{
	  if (omp_privatize_by_reference (*decl))
	    *type = TREE_TYPE (*type);
	  if (pass != (!TREE_CONSTANT (TYPE_SIZE_UNIT (*type))))
	    continue;
	}
      *next = omp_find_clause (OMP_CLAUSE_CHAIN (*c), ccode);
      return true;
    }
  *decl = NULL_TREE;
  *type = NULL_TREE;
  *next = NULL_TREE;
  return false;
}

/* Lower task_reduction and reduction clauses (the latter unless CODE is
   OMP_TASKGROUP only with task modifier).  Register mapping of those in
   START sequence and reducing them and unregister them in the END sequence.  */

static void
lower_omp_task_reductions (omp_context *ctx, enum tree_code code, tree clauses,
			   gimple_seq *start, gimple_seq *end)
{
  enum omp_clause_code ccode
    = (code == OMP_TASKGROUP
       ? OMP_CLAUSE_TASK_REDUCTION : OMP_CLAUSE_REDUCTION);
  tree cancellable = NULL_TREE;
  clauses = omp_task_reductions_find_first (clauses, code, ccode);
  if (clauses == NULL_TREE)
    return;
  if (code == OMP_FOR || code == OMP_SECTIONS || code == OMP_SCOPE)
    {
      for (omp_context *outer = ctx->outer; outer; outer = outer->outer)
	if (gimple_code (outer->stmt) == GIMPLE_OMP_PARALLEL
	    && outer->cancellable)
	  {
	    cancellable = error_mark_node;
	    break;
	  }
	else if (gimple_code (outer->stmt) != GIMPLE_OMP_TASKGROUP
		 && gimple_code (outer->stmt) != GIMPLE_OMP_SCOPE)
	  break;
    }
  tree record_type = lang_hooks.types.make_type (RECORD_TYPE);
  tree *last = &TYPE_FIELDS (record_type);
  unsigned cnt = 0;
  if (cancellable)
    {
      tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
			       ptr_type_node);
      tree ifield = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
				integer_type_node);
      *last = field;
      DECL_CHAIN (field) = ifield;
      last = &DECL_CHAIN (ifield);
      DECL_CONTEXT (field) = record_type;
      if (TYPE_ALIGN (record_type) < DECL_ALIGN (field))
	SET_TYPE_ALIGN (record_type, DECL_ALIGN (field));
      DECL_CONTEXT (ifield) = record_type;
      if (TYPE_ALIGN (record_type) < DECL_ALIGN (ifield))
	SET_TYPE_ALIGN (record_type, DECL_ALIGN (ifield));
    }
  for (int pass = 0; pass < 2; pass++)
    {
      tree decl, type, next;
      for (tree c = clauses;
	   omp_task_reduction_iterate (pass, code, ccode,
				       &c, &decl, &type, &next); c = next)
	{
	  ++cnt;
	  tree new_type = type;
	  if (ctx->outer)
	    new_type = remap_type (type, &ctx->outer->cb);
	  tree field
	    = build_decl (OMP_CLAUSE_LOCATION (c), FIELD_DECL,
			  DECL_P (decl) ? DECL_NAME (decl) : NULL_TREE,
			  new_type);
	  if (DECL_P (decl) && type == TREE_TYPE (decl))
	    {
	      SET_DECL_ALIGN (field, DECL_ALIGN (decl));
	      DECL_USER_ALIGN (field) = DECL_USER_ALIGN (decl);
	      TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (decl);
	    }
	  else
	    SET_DECL_ALIGN (field, TYPE_ALIGN (type));
	  DECL_CONTEXT (field) = record_type;
	  if (TYPE_ALIGN (record_type) < DECL_ALIGN (field))
	    SET_TYPE_ALIGN (record_type, DECL_ALIGN (field));
	  *last = field;
	  last = &DECL_CHAIN (field);
	  tree bfield
	    = build_decl (OMP_CLAUSE_LOCATION (c), FIELD_DECL, NULL_TREE,
			  boolean_type_node);
	  DECL_CONTEXT (bfield) = record_type;
	  if (TYPE_ALIGN (record_type) < DECL_ALIGN (bfield))
	    SET_TYPE_ALIGN (record_type, DECL_ALIGN (bfield));
	  *last = bfield;
	  last = &DECL_CHAIN (bfield);
	}
    }
  *last = NULL_TREE;
  layout_type (record_type);

  /* Build up an array which registers with the runtime all the reductions
     and deregisters them at the end.  Format documented in libgomp/task.c.  */
  tree atype = build_array_type_nelts (pointer_sized_int_node, 7 + cnt * 3);
  tree avar = create_tmp_var_raw (atype);
  gimple_add_tmp_var (avar);
  TREE_ADDRESSABLE (avar) = 1;
  tree r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_zero_node,
		   NULL_TREE, NULL_TREE);
  tree t = build_int_cst (pointer_sized_int_node, cnt);
  gimple_seq_add_stmt (start, gimple_build_assign (r, t));
  gimple_seq seq = NULL;
  tree sz = fold_convert (pointer_sized_int_node,
			  TYPE_SIZE_UNIT (record_type));
  int cachesz = 64;
  sz = fold_build2 (PLUS_EXPR, pointer_sized_int_node, sz,
		    build_int_cst (pointer_sized_int_node, cachesz - 1));
  sz = fold_build2 (BIT_AND_EXPR, pointer_sized_int_node, sz,
		    build_int_cst (pointer_sized_int_node, ~(cachesz - 1)));
  ctx->task_reductions.create (1 + cnt);
  ctx->task_reduction_map = new hash_map<tree, unsigned>;
  ctx->task_reductions.quick_push (TREE_CODE (sz) == INTEGER_CST
				   ? sz : NULL_TREE);
  sz = force_gimple_operand (sz, &seq, true, NULL_TREE);
  gimple_seq_add_seq (start, seq);
  r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_one_node,
	      NULL_TREE, NULL_TREE);
  gimple_seq_add_stmt (start, gimple_build_assign (r, sz));
  r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_int (2),
	      NULL_TREE, NULL_TREE);
  t = build_int_cst (pointer_sized_int_node,
		     MAX (TYPE_ALIGN_UNIT (record_type), (unsigned) cachesz));
  gimple_seq_add_stmt (start, gimple_build_assign (r, t));
  r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_int (3),
	      NULL_TREE, NULL_TREE);
  t = build_int_cst (pointer_sized_int_node, -1);
  gimple_seq_add_stmt (start, gimple_build_assign (r, t));
  r = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_int (4),
	      NULL_TREE, NULL_TREE);
  t = build_int_cst (pointer_sized_int_node, 0);
  gimple_seq_add_stmt (start, gimple_build_assign (r, t));

  /* In end, build a loop that iterates from 0 to < omp_get_num_threads ()
     and for each task reduction checks a bool right after the private variable
     within that thread's chunk; if the bool is clear, it hasn't been
     initialized and thus isn't going to be reduced nor destructed, otherwise
     reduce and destruct it.  */
  tree idx = create_tmp_var (size_type_node);
  gimple_seq_add_stmt (end, gimple_build_assign (idx, size_zero_node));
  tree num_thr_sz = create_tmp_var (size_type_node);
  tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
  tree lab2 = create_artificial_label (UNKNOWN_LOCATION);
  tree lab3 = NULL_TREE, lab7 = NULL_TREE;
  gimple *g;
  if (code == OMP_FOR || code == OMP_SECTIONS || code == OMP_SCOPE)
    {
      /* For worksharing constructs or scope, only perform it in the master
	 thread, with the exception of cancelled implicit barriers - then only
	 handle the current thread.  */
      tree lab4 = create_artificial_label (UNKNOWN_LOCATION);
      t = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
      tree thr_num = create_tmp_var (integer_type_node);
      g = gimple_build_call (t, 0);
      gimple_call_set_lhs (g, thr_num);
      gimple_seq_add_stmt (end, g);
      if (cancellable)
	{
	  tree c;
	  tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
	  tree lab6 = create_artificial_label (UNKNOWN_LOCATION);
	  lab3 = create_artificial_label (UNKNOWN_LOCATION);
	  if (code == OMP_FOR)
	    c = gimple_omp_for_clauses (ctx->stmt);
	  else if (code == OMP_SECTIONS)
	    c = gimple_omp_sections_clauses (ctx->stmt);
	  else /* if (code == OMP_SCOPE) */
	    c = gimple_omp_scope_clauses (ctx->stmt);
	  c = OMP_CLAUSE_DECL (omp_find_clause (c, OMP_CLAUSE__REDUCTEMP_));
	  cancellable = c;
	  g = gimple_build_cond (NE_EXPR, c, build_zero_cst (TREE_TYPE (c)),
				 lab5, lab6);
	  gimple_seq_add_stmt (end, g);
	  gimple_seq_add_stmt (end, gimple_build_label (lab5));
	  g = gimple_build_assign (idx, NOP_EXPR, thr_num);
	  gimple_seq_add_stmt (end, g);
	  g = gimple_build_assign (num_thr_sz, PLUS_EXPR, idx,
				   build_one_cst (TREE_TYPE (idx)));
	  gimple_seq_add_stmt (end, g);
	  gimple_seq_add_stmt (end, gimple_build_goto (lab3));
	  gimple_seq_add_stmt (end, gimple_build_label (lab6));
	}
      g = gimple_build_cond (NE_EXPR, thr_num, integer_zero_node, lab2, lab4);
      gimple_seq_add_stmt (end, g);
      gimple_seq_add_stmt (end, gimple_build_label (lab4));
    }
  if (code != OMP_PARALLEL)
    {
      t = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
      tree num_thr = create_tmp_var (integer_type_node);
      g = gimple_build_call (t, 0);
      gimple_call_set_lhs (g, num_thr);
      gimple_seq_add_stmt (end, g);
      g = gimple_build_assign (num_thr_sz, NOP_EXPR, num_thr);
      gimple_seq_add_stmt (end, g);
      if (cancellable)
	gimple_seq_add_stmt (end, gimple_build_label (lab3));
    }
  else
    {
      tree c = omp_find_clause (gimple_omp_parallel_clauses (ctx->stmt),
				OMP_CLAUSE__REDUCTEMP_);
      t = fold_convert (pointer_sized_int_node, OMP_CLAUSE_DECL (c));
      t = fold_convert (size_type_node, t);
      gimplify_assign (num_thr_sz, t, end);
    }
  t = build4 (ARRAY_REF, pointer_sized_int_node, avar, size_int (2),
	      NULL_TREE, NULL_TREE);
  tree data = create_tmp_var (pointer_sized_int_node);
  gimple_seq_add_stmt (end, gimple_build_assign (data, t));
  if (code == OMP_TASKLOOP)
    {
      lab7 = create_artificial_label (UNKNOWN_LOCATION);
      g = gimple_build_cond (NE_EXPR, data,
			     build_zero_cst (pointer_sized_int_node),
			     lab1, lab7);
      gimple_seq_add_stmt (end, g);
    }
  gimple_seq_add_stmt (end, gimple_build_label (lab1));
  tree ptr;
  if (TREE_CODE (TYPE_SIZE_UNIT (record_type)) == INTEGER_CST)
    ptr = create_tmp_var (build_pointer_type (record_type));
  else
    ptr = create_tmp_var (ptr_type_node);
  gimple_seq_add_stmt (end, gimple_build_assign (ptr, NOP_EXPR, data));

  tree field = TYPE_FIELDS (record_type);
  cnt = 0;
  if (cancellable)
    field = DECL_CHAIN (DECL_CHAIN (field));
  for (int pass = 0; pass < 2; pass++)
    {
      tree decl, type, next;
      for (tree c = clauses;
	   omp_task_reduction_iterate (pass, code, ccode,
				       &c, &decl, &type, &next); c = next)
	{
	  tree var = decl, ref;
	  if (TREE_CODE (decl) == MEM_REF)
	    {
	      var = TREE_OPERAND (var, 0);
	      if (TREE_CODE (var) == POINTER_PLUS_EXPR)
		var = TREE_OPERAND (var, 0);
	      tree v = var;
	      if (TREE_CODE (var) == ADDR_EXPR)
		var = TREE_OPERAND (var, 0);
	      else if (TREE_CODE (var) == INDIRECT_REF)
		var = TREE_OPERAND (var, 0);
	      tree orig_var = var;
	      if (is_variable_sized (var))
		{
		  gcc_assert (DECL_HAS_VALUE_EXPR_P (var));
		  var = DECL_VALUE_EXPR (var);
		  gcc_assert (TREE_CODE (var) == INDIRECT_REF);
		  var = TREE_OPERAND (var, 0);
		  gcc_assert (DECL_P (var));
		}
	      t = ref = maybe_lookup_decl_in_outer_ctx (var, ctx);
	      if (orig_var != var)
		gcc_assert (TREE_CODE (v) == ADDR_EXPR);
	      else if (TREE_CODE (v) == ADDR_EXPR)
		t = build_fold_addr_expr (t);
	      else if (TREE_CODE (v) == INDIRECT_REF)
		t = build_fold_indirect_ref (t);
	      if (TREE_CODE (TREE_OPERAND (decl, 0)) == POINTER_PLUS_EXPR)
		{
		  tree b = TREE_OPERAND (TREE_OPERAND (decl, 0), 1);
		  b = maybe_lookup_decl_in_outer_ctx (b, ctx);
		  t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, b);
		}
	      if (!integer_zerop (TREE_OPERAND (decl, 1)))
		t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t,
				 fold_convert (size_type_node,
					       TREE_OPERAND (decl, 1)));
	    }
	  else
	    {
	      t = ref = maybe_lookup_decl_in_outer_ctx (var, ctx);
	      if (!omp_privatize_by_reference (decl))
		t = build_fold_addr_expr (t);
	    }
	  t = fold_convert (pointer_sized_int_node, t);
	  seq = NULL;
	  t = force_gimple_operand (t, &seq, true, NULL_TREE);
	  gimple_seq_add_seq (start, seq);
	  r = build4 (ARRAY_REF, pointer_sized_int_node, avar,
		      size_int (7 + cnt * 3), NULL_TREE, NULL_TREE);
	  gimple_seq_add_stmt (start, gimple_build_assign (r, t));
	  t = unshare_expr (byte_position (field));
	  t = fold_convert (pointer_sized_int_node, t);
	  ctx->task_reduction_map->put (c, cnt);
	  ctx->task_reductions.quick_push (TREE_CODE (t) == INTEGER_CST
					   ? t : NULL_TREE);
	  seq = NULL;
	  t = force_gimple_operand (t, &seq, true, NULL_TREE);
	  gimple_seq_add_seq (start, seq);
	  r = build4 (ARRAY_REF, pointer_sized_int_node, avar,
		      size_int (7 + cnt * 3 + 1), NULL_TREE, NULL_TREE);
	  gimple_seq_add_stmt (start, gimple_build_assign (r, t));

	  tree bfield = DECL_CHAIN (field);
	  tree cond;
	  if (code == OMP_PARALLEL
	      || code == OMP_FOR
	      || code == OMP_SECTIONS
	      || code == OMP_SCOPE)
	    /* In parallel, worksharing or scope all threads unconditionally
	       initialize all their task reduction private variables.  */
	    cond = boolean_true_node;
	  else if (TREE_TYPE (ptr) == ptr_type_node)
	    {
	      cond = build2 (POINTER_PLUS_EXPR, ptr_type_node, ptr,
			     unshare_expr (byte_position (bfield)));
	      seq = NULL;
	      cond = force_gimple_operand (cond, &seq, true, NULL_TREE);
	      gimple_seq_add_seq (end, seq);
	      tree pbool = build_pointer_type (TREE_TYPE (bfield));
	      cond = build2 (MEM_REF, TREE_TYPE (bfield), cond,
			     build_int_cst (pbool, 0));
	    }
	  else
	    cond = build3 (COMPONENT_REF, TREE_TYPE (bfield),
			   build_simple_mem_ref (ptr), bfield, NULL_TREE);
	  tree lab3 = create_artificial_label (UNKNOWN_LOCATION);
	  tree lab4 = create_artificial_label (UNKNOWN_LOCATION);
	  tree condv = create_tmp_var (boolean_type_node);
	  gimple_seq_add_stmt (end, gimple_build_assign (condv, cond));
	  g = gimple_build_cond (NE_EXPR, condv, boolean_false_node,
				 lab3, lab4);
	  gimple_seq_add_stmt (end, g);
	  gimple_seq_add_stmt (end, gimple_build_label (lab3));
	  if (cancellable && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == NULL_TREE)
	    {
	      /* If this reduction doesn't need destruction and parallel
		 has been cancelled, there is nothing to do for this
		 reduction, so jump around the merge operation.  */
	      tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
	      g = gimple_build_cond (NE_EXPR, cancellable,
				     build_zero_cst (TREE_TYPE (cancellable)),
				     lab4, lab5);
	      gimple_seq_add_stmt (end, g);
	      gimple_seq_add_stmt (end, gimple_build_label (lab5));
	    }

	  tree new_var;
	  if (TREE_TYPE (ptr) == ptr_type_node)
	    {
	      new_var = build2 (POINTER_PLUS_EXPR, ptr_type_node, ptr,
				unshare_expr (byte_position (field)));
	      seq = NULL;
	      new_var = force_gimple_operand (new_var, &seq, true, NULL_TREE);
	      gimple_seq_add_seq (end, seq);
	      tree pbool = build_pointer_type (TREE_TYPE (field));
	      new_var = build2 (MEM_REF, TREE_TYPE (field), new_var,
				build_int_cst (pbool, 0));
	    }
	  else
	    new_var = build3 (COMPONENT_REF, TREE_TYPE (field),
			      build_simple_mem_ref (ptr), field, NULL_TREE);

	  enum tree_code rcode = OMP_CLAUSE_REDUCTION_CODE (c);
	  if (TREE_CODE (decl) != MEM_REF
	      && omp_privatize_by_reference (decl))
	    ref = build_simple_mem_ref (ref);
	  /* reduction(-:var) sums up the partial results, so it acts
	     identically to reduction(+:var).  */
	  if (rcode == MINUS_EXPR)
	    rcode = PLUS_EXPR;
	  if (TREE_CODE (decl) == MEM_REF)
	    {
	      tree type = TREE_TYPE (new_var);
	      tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
	      tree i = create_tmp_var (TREE_TYPE (v));
	      tree ptype = build_pointer_type (TREE_TYPE (type));
	      if (DECL_P (v))
		{
		  v = maybe_lookup_decl_in_outer_ctx (v, ctx);
		  tree vv = create_tmp_var (TREE_TYPE (v));
		  gimplify_assign (vv, v, start);
		  v = vv;
		}
	      ref = build4 (ARRAY_REF, pointer_sized_int_node, avar,
			    size_int (7 + cnt * 3), NULL_TREE, NULL_TREE);
	      new_var = build_fold_addr_expr (new_var);
	      new_var = fold_convert (ptype, new_var);
	      ref = fold_convert (ptype, ref);
	      tree m = create_tmp_var (ptype);
	      gimplify_assign (m, new_var, end);
	      new_var = m;
	      m = create_tmp_var (ptype);
	      gimplify_assign (m, ref, end);
	      ref = m;
	      gimplify_assign (i, build_int_cst (TREE_TYPE (v), 0), end);
	      tree body = create_artificial_label (UNKNOWN_LOCATION);
	      tree endl = create_artificial_label (UNKNOWN_LOCATION);
	      gimple_seq_add_stmt (end, gimple_build_label (body));
	      tree priv = build_simple_mem_ref (new_var);
	      tree out = build_simple_mem_ref (ref);
	      if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
		{
		  tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
		  tree decl_placeholder
		    = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c);
		  tree lab6 = NULL_TREE;
		  if (cancellable)
		    {
		      /* If this reduction needs destruction and parallel
			 has been cancelled, jump around the merge operation
			 to the destruction.  */
		      tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
		      lab6 = create_artificial_label (UNKNOWN_LOCATION);
		      tree zero = build_zero_cst (TREE_TYPE (cancellable));
		      g = gimple_build_cond (NE_EXPR, cancellable, zero,
					     lab6, lab5);
		      gimple_seq_add_stmt (end, g);
		      gimple_seq_add_stmt (end, gimple_build_label (lab5));
		    }
		  SET_DECL_VALUE_EXPR (placeholder, out);
		  DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
		  SET_DECL_VALUE_EXPR (decl_placeholder, priv);
		  DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 1;
		  lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
		  gimple_seq_add_seq (end,
				      OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
		  OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
		  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
		    {
		      OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
		      OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) = NULL;
		    }
		  if (cancellable)
		    gimple_seq_add_stmt (end, gimple_build_label (lab6));
		  tree x = lang_hooks.decls.omp_clause_dtor (c, priv);
		  if (x)
		    {
		      gimple_seq tseq = NULL;
		      gimplify_stmt (&x, &tseq);
		      gimple_seq_add_seq (end, tseq);
		    }
		}
	      else
		{
		  tree x = build2 (rcode, TREE_TYPE (out), out, priv);
		  out = unshare_expr (out);
		  gimplify_assign (out, x, end);
		}
	      gimple *g
		= gimple_build_assign (new_var, POINTER_PLUS_EXPR, new_var,
				       TYPE_SIZE_UNIT (TREE_TYPE (type)));
	      gimple_seq_add_stmt (end, g);
	      g = gimple_build_assign (ref, POINTER_PLUS_EXPR, ref,
				       TYPE_SIZE_UNIT (TREE_TYPE (type)));
	      gimple_seq_add_stmt (end, g);
	      g = gimple_build_assign (i, PLUS_EXPR, i,
				       build_int_cst (TREE_TYPE (i), 1));
	      gimple_seq_add_stmt (end, g);
	      g = gimple_build_cond (LE_EXPR, i, v, body, endl);
	      gimple_seq_add_stmt (end, g);
	      gimple_seq_add_stmt (end, gimple_build_label (endl));
	    }
	  else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
	    {
	      tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
	      tree oldv = NULL_TREE;
	      tree lab6 = NULL_TREE;
	      if (cancellable)
		{
		  /* If this reduction needs destruction and parallel
		     has been cancelled, jump around the merge operation
		     to the destruction.  */
		  tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
		  lab6 = create_artificial_label (UNKNOWN_LOCATION);
		  tree zero = build_zero_cst (TREE_TYPE (cancellable));
		  g = gimple_build_cond (NE_EXPR, cancellable, zero,
					 lab6, lab5);
		  gimple_seq_add_stmt (end, g);
		  gimple_seq_add_stmt (end, gimple_build_label (lab5));
		}
	      if (omp_privatize_by_reference (decl)
		  && !useless_type_conversion_p (TREE_TYPE (placeholder),
						 TREE_TYPE (ref)))
		ref = build_fold_addr_expr_loc (OMP_CLAUSE_LOCATION (c), ref);
	      ref = build_fold_addr_expr_loc (OMP_CLAUSE_LOCATION (c), ref);
	      tree refv = create_tmp_var (TREE_TYPE (ref));
	      gimplify_assign (refv, ref, end);
	      ref = build_simple_mem_ref_loc (OMP_CLAUSE_LOCATION (c), refv);
	      SET_DECL_VALUE_EXPR (placeholder, ref);
	      DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
	      tree d = maybe_lookup_decl (decl, ctx);
	      gcc_assert (d);
	      if (DECL_HAS_VALUE_EXPR_P (d))
		oldv = DECL_VALUE_EXPR (d);
	      if (omp_privatize_by_reference (var))
		{
		  tree v = fold_convert (TREE_TYPE (d),
					 build_fold_addr_expr (new_var));
		  SET_DECL_VALUE_EXPR (d, v);
		}
	      else
		SET_DECL_VALUE_EXPR (d, new_var);
	      DECL_HAS_VALUE_EXPR_P (d) = 1;
	      lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
	      if (oldv)
		SET_DECL_VALUE_EXPR (d, oldv);
	      else
		{
		  SET_DECL_VALUE_EXPR (d, NULL_TREE);
		  DECL_HAS_VALUE_EXPR_P (d) = 0;
		}
	      gimple_seq_add_seq (end, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
	      OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
	      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
		OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
	      if (cancellable)
		gimple_seq_add_stmt (end, gimple_build_label (lab6));
	      tree x = lang_hooks.decls.omp_clause_dtor (c, new_var);
	      if (x)
		{
		  gimple_seq tseq = NULL;
		  gimplify_stmt (&x, &tseq);
		  gimple_seq_add_seq (end, tseq);
		}
	    }
	  else
	    {
	      tree x = build2 (rcode, TREE_TYPE (ref), ref, new_var);
	      ref = unshare_expr (ref);
	      gimplify_assign (ref, x, end);
	    }
	  gimple_seq_add_stmt (end, gimple_build_label (lab4));
	  ++cnt;
	  field = DECL_CHAIN (bfield);
	}
    }

  if (code == OMP_TASKGROUP)
    {
      t = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_REDUCTION_REGISTER);
      g = gimple_build_call (t, 1, build_fold_addr_expr (avar));
      gimple_seq_add_stmt (start, g);
    }
  else
    {
      tree c;
      if (code == OMP_FOR)
	c = gimple_omp_for_clauses (ctx->stmt);
      else if (code == OMP_SECTIONS)
	c = gimple_omp_sections_clauses (ctx->stmt);
      else if (code == OMP_SCOPE)
	c = gimple_omp_scope_clauses (ctx->stmt);
      else
	c = gimple_omp_taskreg_clauses (ctx->stmt);
      c = omp_find_clause (c, OMP_CLAUSE__REDUCTEMP_);
      t = fold_convert (TREE_TYPE (OMP_CLAUSE_DECL (c)),
			build_fold_addr_expr (avar));
      gimplify_assign (OMP_CLAUSE_DECL (c), t, start);
    }

  gimple_seq_add_stmt (end, gimple_build_assign (data, PLUS_EXPR, data, sz));
  gimple_seq_add_stmt (end, gimple_build_assign (idx, PLUS_EXPR, idx,
						 size_one_node));
  g = gimple_build_cond (NE_EXPR, idx, num_thr_sz, lab1, lab2);
  gimple_seq_add_stmt (end, g);
  gimple_seq_add_stmt (end, gimple_build_label (lab2));
  if (code == OMP_FOR || code == OMP_SECTIONS || code == OMP_SCOPE)
    {
      enum built_in_function bfn
	= BUILT_IN_GOMP_WORKSHARE_TASK_REDUCTION_UNREGISTER;
      t = builtin_decl_explicit (bfn);
      tree c_bool_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (t)));
      tree arg;
      if (cancellable)
	{
	  arg = create_tmp_var (c_bool_type);
	  gimple_seq_add_stmt (end, gimple_build_assign (arg, NOP_EXPR,
							 cancellable));
	}
      else
	arg = build_int_cst (c_bool_type, 0);
      g = gimple_build_call (t, 1, arg);
    }
  else
    {
      t = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_REDUCTION_UNREGISTER);
      g = gimple_build_call (t, 1, build_fold_addr_expr (avar));
    }
  gimple_seq_add_stmt (end, g);
  if (lab7)
    gimple_seq_add_stmt (end, gimple_build_label (lab7));
  t = build_constructor (atype, NULL);
  TREE_THIS_VOLATILE (t) = 1;
  gimple_seq_add_stmt (end, gimple_build_assign (avar, t));
}

/* Expand code for an OpenMP taskgroup directive.  */

static void
lower_omp_taskgroup (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
  gimple *stmt = gsi_stmt (*gsi_p);
  gcall *x;
  gbind *bind;
  gimple_seq dseq = NULL;
  tree block = make_node (BLOCK);

  bind = gimple_build_bind (NULL, NULL, block);
  gsi_replace (gsi_p, bind, true);
  gimple_bind_add_stmt (bind, stmt);

  push_gimplify_context ();

  x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_START),
			 0);
  gimple_bind_add_stmt (bind, x);

  lower_omp_task_reductions (ctx, OMP_TASKGROUP,
			     gimple_omp_taskgroup_clauses (stmt),
			     gimple_bind_body_ptr (bind), &dseq);

  lower_omp (gimple_omp_body_ptr (stmt), ctx);
  gimple_bind_add_seq (bind, gimple_omp_body (stmt));
  gimple_omp_set_body (stmt, NULL);

  gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
  gimple_bind_add_seq (bind, dseq);

  pop_gimplify_context (bind);

  gimple_bind_append_vars (bind, ctx->block_vars);
  BLOCK_VARS (block) = ctx->block_vars;
}


/* Fold the OMP_ORDERED_CLAUSES for the OMP_ORDERED in STMT if possible.  */

static void
lower_omp_ordered_clauses (gimple_stmt_iterator *gsi_p, gomp_ordered *ord_stmt,
			   omp_context *ctx)
{
  struct omp_for_data fd;
  if (!ctx->outer || gimple_code (ctx->outer->stmt) != GIMPLE_OMP_FOR)
    return;

  unsigned int len = gimple_omp_for_collapse (ctx->outer->stmt);
  struct omp_for_data_loop *loops = XALLOCAVEC (struct omp_for_data_loop, len);
  omp_extract_for_data (as_a <gomp_for *> (ctx->outer->stmt), &fd, loops);
  if (!fd.ordered)
    return;

  tree *list_p = gimple_omp_ordered_clauses_ptr (ord_stmt);
  tree c = gimple_omp_ordered_clauses (ord_stmt);
  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
      && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
    {
      /* Merge depend clauses from multiple adjacent
	 #pragma omp ordered depend(sink:...) constructs
	 into one #pragma omp ordered depend(sink:...), so that
	 we can optimize them together.  */
      gimple_stmt_iterator gsi = *gsi_p;
      gsi_next (&gsi);
      while (!gsi_end_p (gsi))
	{
	  gimple *stmt = gsi_stmt (gsi);
	  if (is_gimple_debug (stmt)
	      || gimple_code (stmt) == GIMPLE_NOP)
	    {
	      gsi_next (&gsi);
	      continue;
	    }
	  if (gimple_code (stmt) != GIMPLE_OMP_ORDERED)
	    break;
	  gomp_ordered *ord_stmt2 = as_a <gomp_ordered *> (stmt);
	  c = gimple_omp_ordered_clauses (ord_stmt2);
	  if (c == NULL_TREE
	      || OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
	      || OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_SINK)
	    break;
	  while (*list_p)
	    list_p = &OMP_CLAUSE_CHAIN (*list_p);
	  *list_p = c;
	  gsi_remove (&gsi, true);
	}
    }

  /* Canonicalize sink dependence clauses into one folded clause if
     possible.

     The basic algorithm is to create a sink vector whose first
     element is the GCD of all the first elements, and whose remaining
     elements are the minimum of the subsequent columns.

     We ignore dependence vectors whose first element is zero because
     such dependencies are known to be executed by the same thread.

     We take into account the direction of the loop, so a minimum
     becomes a maximum if the loop is iterating forwards.  We also
     ignore sink clauses where the loop direction is unknown, or where
     the offsets are clearly invalid because they are not a multiple
     of the loop increment.

     For example:

	#pragma omp for ordered(2)
	for (i=0; i < N; ++i)
	  for (j=0; j < M; ++j)
	    {
	      #pragma omp ordered \
		depend(sink:i-8,j-2) \
		depend(sink:i,j-1) \	// Completely ignored because i+0.
		depend(sink:i-4,j-3) \
		depend(sink:i-6,j-4)
	      #pragma omp ordered depend(source)
	    }

     Folded clause is:

	depend(sink:-gcd(8,4,6),-min(2,3,4))
	  -or-
	depend(sink:-2,-2)
  */

  /* FIXME: Computing GCD's where the first element is zero is
     non-trivial in the presence of collapsed loops.  Do this later.  */
  if (fd.collapse > 1)
    return;

  wide_int *folded_deps = XALLOCAVEC (wide_int, 2 * len - 1);

  /* wide_int is not a POD so it must be default-constructed.  */
  for (unsigned i = 0; i != 2 * len - 1; ++i)
    new (static_cast<void*>(folded_deps + i)) wide_int ();

  tree folded_dep = NULL_TREE;
  /* TRUE if the first dimension's offset is negative.  */
  bool neg_offset_p = false;

  list_p = gimple_omp_ordered_clauses_ptr (ord_stmt);
  unsigned int i;
  while ((c = *list_p) != NULL)
    {
      bool remove = false;

      gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND);
      if (OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_SINK)
	goto next_ordered_clause;

      tree vec;
      for (vec = OMP_CLAUSE_DECL (c), i = 0;
	   vec && TREE_CODE (vec) == TREE_LIST;
	   vec = TREE_CHAIN (vec), ++i)
	{
	  gcc_assert (i < len);

	  /* omp_extract_for_data has canonicalized the condition.  */
	  gcc_assert (fd.loops[i].cond_code == LT_EXPR
		      || fd.loops[i].cond_code == GT_EXPR);
	  bool forward = fd.loops[i].cond_code == LT_EXPR;
	  bool maybe_lexically_later = true;

	  /* While the committee makes up its mind, bail if we have any
	     non-constant steps.  */
	  if (TREE_CODE (fd.loops[i].step) != INTEGER_CST)
	    goto lower_omp_ordered_ret;

	  tree itype = TREE_TYPE (TREE_VALUE (vec));
	  if (POINTER_TYPE_P (itype))
	    itype = sizetype;
	  wide_int offset = wide_int::from (wi::to_wide (TREE_PURPOSE (vec)),
					    TYPE_PRECISION (itype),
					    TYPE_SIGN (itype));

	  /* Ignore invalid offsets that are not multiples of the step.  */
	  if (!wi::multiple_of_p (wi::abs (offset),
				  wi::abs (wi::to_wide (fd.loops[i].step)),
				  UNSIGNED))
	    {
	      warning_at (OMP_CLAUSE_LOCATION (c), 0,
			  "ignoring sink clause with offset that is not "
			  "a multiple of the loop step");
	      remove = true;
	      goto next_ordered_clause;
	    }

	  /* Calculate the first dimension.  The first dimension of
	     the folded dependency vector is the GCD of the first
	     elements, while ignoring any first elements whose offset
	     is 0.  */
	  if (i == 0)
	    {
	      /* Ignore dependence vectors whose first dimension is 0.  */
	      if (offset == 0)
		{
		  remove = true;
		  goto next_ordered_clause;
		}
	      else
		{
		  if (!TYPE_UNSIGNED (itype) && (forward ^ wi::neg_p (offset)))
		    {
		      error_at (OMP_CLAUSE_LOCATION (c),
				"first offset must be in opposite direction "
				"of loop iterations");
		      goto lower_omp_ordered_ret;
		    }
		  if (forward)
		    offset = -offset;
		  neg_offset_p = forward;
		  /* Initialize the first time around.  */
		  if (folded_dep == NULL_TREE)
		    {
		      folded_dep = c;
		      folded_deps[0] = offset;
		    }
		  else
		    folded_deps[0] = wi::gcd (folded_deps[0],
					      offset, UNSIGNED);
		}
	    }
	  /* Calculate minimum for the remaining dimensions.  */
	  else
	    {
	      folded_deps[len + i - 1] = offset;
	      if (folded_dep == c)
		folded_deps[i] = offset;
	      else if (maybe_lexically_later
		       && !wi::eq_p (folded_deps[i], offset))
		{
		  if (forward ^ wi::gts_p (folded_deps[i], offset))
		    {
		      unsigned int j;
		      folded_dep = c;
		      for (j = 1; j <= i; j++)
			folded_deps[j] = folded_deps[len + j - 1];
		    }
		  else
		    maybe_lexically_later = false;
		}
	    }
	}
      gcc_assert (i == len);

      remove = true;

    next_ordered_clause:
      if (remove)
	*list_p = OMP_CLAUSE_CHAIN (c);
      else
	list_p = &OMP_CLAUSE_CHAIN (c);
    }

  if (folded_dep)
    {
      if (neg_offset_p)
	folded_deps[0] = -folded_deps[0];

      tree itype = TREE_TYPE (TREE_VALUE (OMP_CLAUSE_DECL (folded_dep)));
      if (POINTER_TYPE_P (itype))
	itype = sizetype;

      TREE_PURPOSE (OMP_CLAUSE_DECL (folded_dep))
	= wide_int_to_tree (itype, folded_deps[0]);
      OMP_CLAUSE_CHAIN (folded_dep) = gimple_omp_ordered_clauses (ord_stmt);
      *gimple_omp_ordered_clauses_ptr (ord_stmt) = folded_dep;
    }

 lower_omp_ordered_ret:

  /* Ordered without clauses is #pragma omp threads, while we want
     a nop instead if we remove all clauses.  */
  if (gimple_omp_ordered_clauses (ord_stmt) == NULL_TREE)
    gsi_replace (gsi_p, gimple_build_nop (), true);
}


/* Expand code for an OpenMP ordered directive.  */

static void
lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
  tree block;
  gimple *stmt = gsi_stmt (*gsi_p), *g;
  gomp_ordered *ord_stmt = as_a <gomp_ordered *> (stmt);
  gcall *x;
  gbind *bind;
  bool simd = omp_find_clause (gimple_omp_ordered_clauses (ord_stmt),
			       OMP_CLAUSE_SIMD);
  /* FIXME: this should check presence of OMP_CLAUSE__SIMT_ on the enclosing
     loop.  */
  bool maybe_simt
    = simd && omp_maybe_offloaded_ctx (ctx) && omp_max_simt_vf () > 1;
  bool threads = omp_find_clause (gimple_omp_ordered_clauses (ord_stmt),
				  OMP_CLAUSE_THREADS);

  if (omp_find_clause (gimple_omp_ordered_clauses (ord_stmt),
		       OMP_CLAUSE_DEPEND))
    {
      /* FIXME: This is needs to be moved to the expansion to verify various
	 conditions only testable on cfg with dominators computed, and also
	 all the depend clauses to be merged still might need to be available
	 for the runtime checks.  */
      if (0)
	lower_omp_ordered_clauses (gsi_p, ord_stmt, ctx);
      return;
    }

  push_gimplify_context ();

  block = make_node (BLOCK);
  bind = gimple_build_bind (NULL, NULL, block);
  gsi_replace (gsi_p, bind, true);
  gimple_bind_add_stmt (bind, stmt);

  if (simd)
    {
      x = gimple_build_call_internal (IFN_GOMP_SIMD_ORDERED_START, 1,
				      build_int_cst (NULL_TREE, threads));
      cfun->has_simduid_loops = true;
    }
  else
    x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
			   0);
  gimple_bind_add_stmt (bind, x);

  tree counter = NULL_TREE, test = NULL_TREE, body = NULL_TREE;
  if (maybe_simt)
    {
      counter = create_tmp_var (integer_type_node);
      g = gimple_build_call_internal (IFN_GOMP_SIMT_LANE, 0);
      gimple_call_set_lhs (g, counter);
      gimple_bind_add_stmt (bind, g);

      body = create_artificial_label (UNKNOWN_LOCATION);
      test = create_artificial_label (UNKNOWN_LOCATION);
      gimple_bind_add_stmt (bind, gimple_build_label (body));

      tree simt_pred = create_tmp_var (integer_type_node);
      g = gimple_build_call_internal (IFN_GOMP_SIMT_ORDERED_PRED, 1, counter);
      gimple_call_set_lhs (g, simt_pred);
      gimple_bind_add_stmt (bind, g);

      tree t = create_artificial_label (UNKNOWN_LOCATION);
      g = gimple_build_cond (EQ_EXPR, simt_pred, integer_zero_node, t, test);
      gimple_bind_add_stmt (bind, g);

      gimple_bind_add_stmt (bind, gimple_build_label (t));
    }
  lower_omp (gimple_omp_body_ptr (stmt), ctx);
  gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
  gimple_bind_add_seq (bind, gimple_omp_body (stmt));
  gimple_omp_set_body (stmt, NULL);

  if (maybe_simt)
    {
      gimple_bind_add_stmt (bind, gimple_build_label (test));
      g = gimple_build_assign (counter, MINUS_EXPR, counter, integer_one_node);
      gimple_bind_add_stmt (bind, g);

      tree c = build2 (GE_EXPR, boolean_type_node, counter, integer_zero_node);
      tree nonneg = create_tmp_var (integer_type_node);
      gimple_seq tseq = NULL;
      gimplify_assign (nonneg, fold_convert (integer_type_node, c), &tseq);
      gimple_bind_add_seq (bind, tseq);

      g = gimple_build_call_internal (IFN_GOMP_SIMT_VOTE_ANY, 1, nonneg);
      gimple_call_set_lhs (g, nonneg);
      gimple_bind_add_stmt (bind, g);

      tree end = create_artificial_label (UNKNOWN_LOCATION);
      g = gimple_build_cond (NE_EXPR, nonneg, integer_zero_node, body, end);
      gimple_bind_add_stmt (bind, g);

      gimple_bind_add_stmt (bind, gimple_build_label (end));
    }
  if (simd)
    x = gimple_build_call_internal (IFN_GOMP_SIMD_ORDERED_END, 1,
				    build_int_cst (NULL_TREE, threads));
  else
    x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END),
			   0);
  gimple_bind_add_stmt (bind, x);

  gimple_bind_add_stmt (bind, gimple_build_omp_return (true));

  pop_gimplify_context (bind);

  gimple_bind_append_vars (bind, ctx->block_vars);
  BLOCK_VARS (block) = gimple_bind_vars (bind);
}


/* Expand code for an OpenMP scan directive and the structured block
   before the scan directive.  */

static void
lower_omp_scan (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
  gimple *stmt = gsi_stmt (*gsi_p);
  bool has_clauses
    = gimple_omp_scan_clauses (as_a <gomp_scan *> (stmt)) != NULL;
  tree lane = NULL_TREE;
  gimple_seq before = NULL;
  omp_context *octx = ctx->outer;
  gcc_assert (octx);
  if (octx->scan_exclusive && !has_clauses)
    {
      gimple_stmt_iterator gsi2 = *gsi_p;
      gsi_next (&gsi2);
      gimple *stmt2 = gsi_stmt (gsi2);
      /* For exclusive scan, swap GIMPLE_OMP_SCAN without clauses
	 with following GIMPLE_OMP_SCAN with clauses, so that input_phase,
	 the one with exclusive clause(s), comes first.  */
      if (stmt2
	  && gimple_code (stmt2) == GIMPLE_OMP_SCAN
	  && gimple_omp_scan_clauses (as_a <gomp_scan *> (stmt2)) != NULL)
	{
	  gsi_remove (gsi_p, false);
	  gsi_insert_after (gsi_p, stmt, GSI_SAME_STMT);
	  ctx = maybe_lookup_ctx (stmt2);
	  gcc_assert (ctx);
	  lower_omp_scan (gsi_p, ctx);
	  return;
	}
    }

  bool input_phase = has_clauses ^ octx->scan_inclusive;
  bool is_simd = (gimple_code (octx->stmt) == GIMPLE_OMP_FOR
		  && gimple_omp_for_kind (octx->stmt) == GF_OMP_FOR_KIND_SIMD);
  bool is_for = (gimple_code (octx->stmt) == GIMPLE_OMP_FOR
		 && gimple_omp_for_kind (octx->stmt) == GF_OMP_FOR_KIND_FOR
		 && !gimple_omp_for_combined_p (octx->stmt));
  bool is_for_simd = is_simd && gimple_omp_for_combined_into_p (octx->stmt);
  if (is_for_simd && octx->for_simd_scan_phase)
    is_simd = false;
  if (is_simd)
    if (tree c = omp_find_clause (gimple_omp_for_clauses (octx->stmt),
				  OMP_CLAUSE__SIMDUID_))
      {
	tree uid = OMP_CLAUSE__SIMDUID__DECL (c);
	lane = create_tmp_var (unsigned_type_node);
	tree t = build_int_cst (integer_type_node,
				input_phase ? 1
				: octx->scan_inclusive ? 2 : 3);
	gimple *g
	  = gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 2, uid, t);
	gimple_call_set_lhs (g, lane);
	gimple_seq_add_stmt (&before, g);
      }

  if (is_simd || is_for)
    {
      for (tree c = gimple_omp_for_clauses (octx->stmt);
	   c; c = OMP_CLAUSE_CHAIN (c))
	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
	    && OMP_CLAUSE_REDUCTION_INSCAN (c))
	  {
	    location_t clause_loc = OMP_CLAUSE_LOCATION (c);
	    tree var = OMP_CLAUSE_DECL (c);
	    tree new_var = lookup_decl (var, octx);
	    tree val = new_var;
	    tree var2 = NULL_TREE;
	    tree var3 = NULL_TREE;
	    tree var4 = NULL_TREE;
	    tree lane0 = NULL_TREE;
	    tree new_vard = new_var;
	    if (omp_privatize_by_reference (var))
	      {
		new_var = build_simple_mem_ref_loc (clause_loc, new_var);
		val = new_var;
	      }
	    if (DECL_HAS_VALUE_EXPR_P (new_vard))
	      {
		val = DECL_VALUE_EXPR (new_vard);
		if (new_vard != new_var)
		  {
		    gcc_assert (TREE_CODE (val) == ADDR_EXPR);
		    val = TREE_OPERAND (val, 0);
		  }
		if (TREE_CODE (val) == ARRAY_REF
		    && VAR_P (TREE_OPERAND (val, 0)))
		  {
		    tree v = TREE_OPERAND (val, 0);
		    if (lookup_attribute ("omp simd array",
					  DECL_ATTRIBUTES (v)))
		      {
			val = unshare_expr (val);
			lane0 = TREE_OPERAND (val, 1);
			TREE_OPERAND (val, 1) = lane;
			var2 = lookup_decl (v, octx);
			if (octx->scan_exclusive)
			  var4 = lookup_decl (var2, octx);
			if (input_phase
			    && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
			  var3 = maybe_lookup_decl (var4 ? var4 : var2, octx);
			if (!input_phase)
			  {
			    var2 = build4 (ARRAY_REF, TREE_TYPE (val),
					   var2, lane, NULL_TREE, NULL_TREE);
			    TREE_THIS_NOTRAP (var2) = 1;
			    if (octx->scan_exclusive)
			      {
				var4 = build4 (ARRAY_REF, TREE_TYPE (val),
					       var4, lane, NULL_TREE,
					       NULL_TREE);
				TREE_THIS_NOTRAP (var4) = 1;
			      }
			  }
			else
			  var2 = val;
		      }
		  }
		gcc_assert (var2);
	      }
	    else
	      {
		var2 = build_outer_var_ref (var, octx);
		if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
		  {
		    var3 = maybe_lookup_decl (new_vard, octx);
		    if (var3 == new_vard || var3 == NULL_TREE)
		      var3 = NULL_TREE;
		    else if (is_simd && octx->scan_exclusive && !input_phase)
		      {
			var4 = maybe_lookup_decl (var3, octx);
			if (var4 == var3 || var4 == NULL_TREE)
			  {
			    if (TREE_ADDRESSABLE (TREE_TYPE (new_var)))
			      {
				var4 = var3;
				var3 = NULL_TREE;
			      }
			    else
			      var4 = NULL_TREE;
			  }
		      }
		  }
		if (is_simd
		    && octx->scan_exclusive
		    && !input_phase
		    && var4 == NULL_TREE)
		  var4 = create_tmp_var (TREE_TYPE (val));
	      }
	    if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
	      {
		tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
		if (input_phase)
		  {
		    if (var3)
		      {
			/* If we've added a separate identity element
			   variable, copy it over into val.  */
			tree x = lang_hooks.decls.omp_clause_assign_op (c, val,
									var3);
			gimplify_and_add (x, &before);
		      }
		    else if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
		      {
			/* Otherwise, assign to it the identity element.  */
			gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
			if (is_for)
			  tseq = copy_gimple_seq_and_replace_locals (tseq);
			tree ref = build_outer_var_ref (var, octx);
			tree x = (DECL_HAS_VALUE_EXPR_P (new_vard)
				  ? DECL_VALUE_EXPR (new_vard) : NULL_TREE);
			if (x)
			  {
			    if (new_vard != new_var)
			      val = build_fold_addr_expr_loc (clause_loc, val);
			    SET_DECL_VALUE_EXPR (new_vard, val);
			  }
			SET_DECL_VALUE_EXPR (placeholder, ref);
			DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
			lower_omp (&tseq, octx);
			if (x)
			  SET_DECL_VALUE_EXPR (new_vard, x);
			SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
			DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
			gimple_seq_add_seq (&before, tseq);
			if (is_simd)
			  OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
		      }
		  }
		else if (is_simd)
		  {
		    tree x;
		    if (octx->scan_exclusive)
		      {
			tree v4 = unshare_expr (var4);
			tree v2 = unshare_expr (var2);
			x = lang_hooks.decls.omp_clause_assign_op (c, v4, v2);
			gimplify_and_add (x, &before);
		      }
		    gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
		    x = (DECL_HAS_VALUE_EXPR_P (new_vard)
			 ? DECL_VALUE_EXPR (new_vard) : NULL_TREE);
		    tree vexpr = val;
		    if (x && new_vard != new_var)
		      vexpr = build_fold_addr_expr_loc (clause_loc, val);
		    if (x)
		      SET_DECL_VALUE_EXPR (new_vard, vexpr);
		    SET_DECL_VALUE_EXPR (placeholder, var2);
		    DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
		    lower_omp (&tseq, octx);
		    gimple_seq_add_seq (&before, tseq);
		    OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
		    if (x)
		      SET_DECL_VALUE_EXPR (new_vard, x);
		    SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
		    DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
		    if (octx->scan_inclusive)
		      {
			x = lang_hooks.decls.omp_clause_assign_op (c, val,
								   var2);
			gimplify_and_add (x, &before);
		      }
		    else if (lane0 == NULL_TREE)
		      {
			x = lang_hooks.decls.omp_clause_assign_op (c, val,
								   var4);
			gimplify_and_add (x, &before);
		      }
		  }
	      }
	    else
	      {
		if (input_phase)
		  {
		    /* input phase.  Set val to initializer before
		       the body.  */
		    tree x = omp_reduction_init (c, TREE_TYPE (new_var));
		    gimplify_assign (val, x, &before);
		  }
		else if (is_simd)
		  {
		    /* scan phase.  */
		    enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
		    if (code == MINUS_EXPR)
		      code = PLUS_EXPR;

		    tree x = build2 (code, TREE_TYPE (var2),
				     unshare_expr (var2), unshare_expr (val));
		    if (octx->scan_inclusive)
		      {
			gimplify_assign (unshare_expr (var2), x, &before);
			gimplify_assign (val, var2, &before);
		      }
		    else
		      {
			gimplify_assign (unshare_expr (var4),
					 unshare_expr (var2), &before);
			gimplify_assign (var2, x, &before);
			if (lane0 == NULL_TREE)
			  gimplify_assign (val, var4, &before);
		      }
		  }
	      }
	    if (octx->scan_exclusive && !input_phase && lane0)
	      {
		tree vexpr = unshare_expr (var4);
		TREE_OPERAND (vexpr, 1) = lane0;
		if (new_vard != new_var)
		  vexpr = build_fold_addr_expr_loc (clause_loc, vexpr);
		SET_DECL_VALUE_EXPR (new_vard, vexpr);
	      }
	  }
    }
  if (is_simd && !is_for_simd)
    {
      gsi_insert_seq_after (gsi_p, gimple_omp_body (stmt), GSI_SAME_STMT);
      gsi_insert_seq_after (gsi_p, before, GSI_SAME_STMT);
      gsi_replace (gsi_p, gimple_build_nop (), true);
      return;
    }
  lower_omp (gimple_omp_body_ptr (stmt), octx);
  if (before)
    {
      gimple_stmt_iterator gsi = gsi_start_1 (gimple_omp_body_ptr (stmt));
      gsi_insert_seq_before (&gsi, before, GSI_SAME_STMT);
    }
}


/* Gimplify a GIMPLE_OMP_CRITICAL statement.  This is a relatively simple
   substitution of a couple of function calls.  But in the NAMED case,
   requires that languages coordinate a symbol name.  It is therefore
   best put here in common code.  */

static GTY(()) hash_map<tree, tree> *critical_name_mutexes;

static void
lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
  tree block;
  tree name, lock, unlock;
  gomp_critical *stmt = as_a <gomp_critical *> (gsi_stmt (*gsi_p));
  gbind *bind;
  location_t loc = gimple_location (stmt);
  gimple_seq tbody;

  name = gimple_omp_critical_name (stmt);
  if (name)
    {
      tree decl;

      if (!critical_name_mutexes)
	critical_name_mutexes = hash_map<tree, tree>::create_ggc (10);

      tree *n = critical_name_mutexes->get (name);
      if (n == NULL)
	{
	  char *new_str;

	  decl = create_tmp_var_raw (ptr_type_node);

	  new_str = ACONCAT ((".gomp_critical_user_",
			      IDENTIFIER_POINTER (name), NULL));
	  DECL_NAME (decl) = get_identifier (new_str);
	  TREE_PUBLIC (decl) = 1;
	  TREE_STATIC (decl) = 1;
	  DECL_COMMON (decl) = 1;
	  DECL_ARTIFICIAL (decl) = 1;
	  DECL_IGNORED_P (decl) = 1;

	  varpool_node::finalize_decl (decl);

	  critical_name_mutexes->put (name, decl);
	}
      else
	decl = *n;

      /* If '#pragma omp critical' is inside offloaded region or
	 inside function marked as offloadable, the symbol must be
	 marked as offloadable too.  */
      omp_context *octx;
      if (cgraph_node::get (current_function_decl)->offloadable)
	varpool_node::get_create (decl)->offloadable = 1;
      else
	for (octx = ctx->outer; octx; octx = octx->outer)
	  if (is_gimple_omp_offloaded (octx->stmt))
	    {
	      varpool_node::get_create (decl)->offloadable = 1;
	      break;
	    }

      lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
      lock = build_call_expr_loc (loc, lock, 1,
				  build_fold_addr_expr_loc (loc, decl));

      unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
      unlock = build_call_expr_loc (loc, unlock, 1,
				build_fold_addr_expr_loc (loc, decl));
    }
  else
    {
      lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
      lock = build_call_expr_loc (loc, lock, 0);

      unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
      unlock = build_call_expr_loc (loc, unlock, 0);
    }

  push_gimplify_context ();

  block = make_node (BLOCK);
  bind = gimple_build_bind (NULL, NULL, block);
  gsi_replace (gsi_p, bind, true);
  gimple_bind_add_stmt (bind, stmt);

  tbody = gimple_bind_body (bind);
  gimplify_and_add (lock, &tbody);
  gimple_bind_set_body (bind, tbody);

  lower_omp (gimple_omp_body_ptr (stmt), ctx);
  gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
  gimple_bind_add_seq (bind, gimple_omp_body (stmt));
  gimple_omp_set_body (stmt, NULL);

  tbody = gimple_bind_body (bind);
  gimplify_and_add (unlock, &tbody);
  gimple_bind_set_body (bind, tbody);

  gimple_bind_add_stmt (bind, gimple_build_omp_return (true));

  pop_gimplify_context (bind);
  gimple_bind_append_vars (bind, ctx->block_vars);
  BLOCK_VARS (block) = gimple_bind_vars (bind);
}

/* A subroutine of lower_omp_for.  Generate code to emit the predicate
   for a lastprivate clause.  Given a loop control predicate of (V
   cond N2), we gate the clause on (!(V cond N2)).  The lowered form
   is appended to *DLIST, iterator initialization is appended to
   *BODY_P.  *CLIST is for lastprivate(conditional:) code that needs
   to be emitted in a critical section.  */

static void
lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
			   gimple_seq *dlist, gimple_seq *clist,
			   struct omp_context *ctx)
{
  tree clauses, cond, vinit;
  enum tree_code cond_code;
  gimple_seq stmts;

  cond_code = fd->loop.cond_code;
  cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;

  /* When possible, use a strict equality expression.  This can let VRP
     type optimizations deduce the value and remove a copy.  */
  if (tree_fits_shwi_p (fd->loop.step))
    {
      HOST_WIDE_INT step = tree_to_shwi (fd->loop.step);
      if (step == 1 || step == -1)
	cond_code = EQ_EXPR;
    }

  tree n2 = fd->loop.n2;
  if (fd->collapse > 1
      && TREE_CODE (n2) != INTEGER_CST
      && gimple_omp_for_combined_into_p (fd->for_stmt))
    {
      struct omp_context *taskreg_ctx = NULL;
      if (gimple_code (ctx->outer->stmt) == GIMPLE_OMP_FOR)
	{
	  gomp_for *gfor = as_a <gomp_for *> (ctx->outer->stmt);
	  if (gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_FOR
	      || gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_DISTRIBUTE)
	    {
	      if (gimple_omp_for_combined_into_p (gfor))
		{
		  gcc_assert (ctx->outer->outer
			      && is_parallel_ctx (ctx->outer->outer));
		  taskreg_ctx = ctx->outer->outer;
		}
	      else
		{
		  struct omp_for_data outer_fd;
		  omp_extract_for_data (gfor, &outer_fd, NULL);
		  n2 = fold_convert (TREE_TYPE (n2), outer_fd.loop.n2);
		}
	    }
	  else if (gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_TASKLOOP)
	    taskreg_ctx = ctx->outer->outer;
	}
      else if (is_taskreg_ctx (ctx->outer))
	taskreg_ctx = ctx->outer;
      if (taskreg_ctx)
	{
	  int i;
	  tree taskreg_clauses
	    = gimple_omp_taskreg_clauses (taskreg_ctx->stmt);
	  tree innerc = omp_find_clause (taskreg_clauses,
					 OMP_CLAUSE__LOOPTEMP_);
	  gcc_assert (innerc);
	  int count = fd->collapse;
	  if (fd->non_rect
	      && fd->last_nonrect == fd->first_nonrect + 1)
	    if (tree v = gimple_omp_for_index (fd->for_stmt, fd->last_nonrect))
	      if (!TYPE_UNSIGNED (TREE_TYPE (v)))
		count += 4;
	  for (i = 0; i < count; i++)
	    {
	      innerc = omp_find_clause (OMP_CLAUSE_CHAIN (innerc),
					OMP_CLAUSE__LOOPTEMP_);
	      gcc_assert (innerc);
	    }
	  innerc = omp_find_clause (OMP_CLAUSE_CHAIN (innerc),
				    OMP_CLAUSE__LOOPTEMP_);
	  if (innerc)
	    n2 = fold_convert (TREE_TYPE (n2),
			       lookup_decl (OMP_CLAUSE_DECL (innerc),
					    taskreg_ctx));
	}
    }
  cond = build2 (cond_code, boolean_type_node, fd->loop.v, n2);

  clauses = gimple_omp_for_clauses (fd->for_stmt);
  stmts = NULL;
  lower_lastprivate_clauses (clauses, cond, body_p, &stmts, clist, ctx);
  if (!gimple_seq_empty_p (stmts))
    {
      gimple_seq_add_seq (&stmts, *dlist);
      *dlist = stmts;

      /* Optimize: v = 0; is usually cheaper than v = some_other_constant.  */
      vinit = fd->loop.n1;
      if (cond_code == EQ_EXPR
	  && tree_fits_shwi_p (fd->loop.n2)
	  && ! integer_zerop (fd->loop.n2))
	vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
      else
	vinit = unshare_expr (vinit);

      /* Initialize the iterator variable, so that threads that don't execute
	 any iterations don't execute the lastprivate clauses by accident.  */
      gimplify_assign (fd->loop.v, vinit, body_p);
    }
}

/* OpenACC privatization.

   Or, in other words, *sharing* at the respective OpenACC level of
   parallelism.

   From a correctness perspective, a non-addressable variable can't be accessed
   outside the current thread, so it can go in a (faster than shared memory)
   register -- though that register may need to be broadcast in some
   circumstances.  A variable can only meaningfully be "shared" across workers
   or vector lanes if its address is taken, e.g. by a call to an atomic
   builtin.

   From an optimisation perspective, the answer might be fuzzier: maybe
   sometimes, using shared memory directly would be faster than
   broadcasting.  */

static void
oacc_privatization_begin_diagnose_var (const dump_flags_t l_dump_flags,
				       const location_t loc, const tree c,
				       const tree decl)
{
  const dump_user_location_t d_u_loc
    = dump_user_location_t::from_location_t (loc);
/* PR100695 "Format decoder, quoting in 'dump_printf' etc." */
#if __GNUC__ >= 10
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wformat"
#endif
  dump_printf_loc (l_dump_flags, d_u_loc,
		   "variable %<%T%> ", decl);
#if __GNUC__ >= 10
# pragma GCC diagnostic pop
#endif
  if (c)
    dump_printf (l_dump_flags,
		 "in %qs clause ",
		 omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
  else
    dump_printf (l_dump_flags,
		 "declared in block ");
}

static bool
oacc_privatization_candidate_p (const location_t loc, const tree c,
				const tree decl)
{
  dump_flags_t l_dump_flags = get_openacc_privatization_dump_flags ();

  /* There is some differentiation depending on block vs. clause.  */
  bool block = !c;

  bool res = true;

  if (res && !VAR_P (decl))
    {
      res = false;

      if (dump_enabled_p ())
	{
	  oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
	  dump_printf (l_dump_flags,
		       "potentially has improper OpenACC privatization level: %qs\n",
		       get_tree_code_name (TREE_CODE (decl)));
	}
    }

  if (res && block && TREE_STATIC (decl))
    {
      res = false;

      if (dump_enabled_p ())
	{
	  oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
	  dump_printf (l_dump_flags,
		       "isn%'t candidate for adjusting OpenACC privatization level: %s\n",
		       "static");
	}
    }

  if (res && block && DECL_EXTERNAL (decl))
    {
      res = false;

      if (dump_enabled_p ())
	{
	  oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
	  dump_printf (l_dump_flags,
		       "isn%'t candidate for adjusting OpenACC privatization level: %s\n",
		       "external");
	}
    }

  if (res && !TREE_ADDRESSABLE (decl))
    {
      res = false;

      if (dump_enabled_p ())
	{
	  oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
	  dump_printf (l_dump_flags,
		       "isn%'t candidate for adjusting OpenACC privatization level: %s\n",
		       "not addressable");
	}
    }

  if (res)
    {
      if (dump_enabled_p ())
	{
	  oacc_privatization_begin_diagnose_var (l_dump_flags, loc, c, decl);
	  dump_printf (l_dump_flags,
		       "is candidate for adjusting OpenACC privatization level\n");
	}
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      print_generic_decl (dump_file, decl, dump_flags);
      fprintf (dump_file, "\n");
    }

  return res;
}

/* Scan CLAUSES for candidates for adjusting OpenACC privatization level in
   CTX.  */

static void
oacc_privatization_scan_clause_chain (omp_context *ctx, tree clauses)
{
  for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE)
      {
	tree decl = OMP_CLAUSE_DECL (c);

	if (!oacc_privatization_candidate_p (OMP_CLAUSE_LOCATION (c), c, decl))
	  continue;

	gcc_checking_assert (!ctx->oacc_privatization_candidates.contains (decl));
	ctx->oacc_privatization_candidates.safe_push (decl);
      }
}

/* Scan DECLS for candidates for adjusting OpenACC privatization level in
   CTX.  */

static void
oacc_privatization_scan_decl_chain (omp_context *ctx, tree decls)
{
  for (tree decl = decls; decl; decl = DECL_CHAIN (decl))
    {
      if (!oacc_privatization_candidate_p (gimple_location (ctx->stmt), NULL, decl))
	continue;

      gcc_checking_assert (!ctx->oacc_privatization_candidates.contains (decl));
      ctx->oacc_privatization_candidates.safe_push (decl);
    }
}

/* Callback for walk_gimple_seq.  Find #pragma omp scan statement.  */

static tree
omp_find_scan (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
	       struct walk_stmt_info *wi)
{
  gimple *stmt = gsi_stmt (*gsi_p);

  *handled_ops_p = true;
  switch (gimple_code (stmt))
    {
    WALK_SUBSTMTS;

    case GIMPLE_OMP_FOR:
      if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD
	  && gimple_omp_for_combined_into_p (stmt))
	*handled_ops_p = false;
      break;

    case GIMPLE_OMP_SCAN:
      *(gimple_stmt_iterator *) (wi->info) = *gsi_p;
      return integer_zero_node;
    default:
      break;
    }
  return NULL;
}

/* Helper function for lower_omp_for, add transformations for a worksharing
   loop with scan directives inside of it.
   For worksharing loop not combined with simd, transform:
   #pragma omp for reduction(inscan,+:r) private(i)
   for (i = 0; i < n; i = i + 1)
     {
       {
	 update (r);
       }
       #pragma omp scan inclusive(r)
       {
	 use (r);
       }
     }

   into two worksharing loops + code to merge results:

   num_threads = omp_get_num_threads ();
   thread_num = omp_get_thread_num ();
   if (thread_num == 0) goto <D.2099>; else goto <D.2100>;
   <D.2099>:
   var2 = r;
   goto <D.2101>;
   <D.2100>:
   // For UDRs this is UDR init, or if ctors are needed, copy from
   // var3 that has been constructed to contain the neutral element.
   var2 = 0;
   <D.2101>:
   ivar = 0;
   // The _scantemp_ clauses will arrange for rpriva to be initialized to
   // a shared array with num_threads elements and rprivb to a local array
   // number of elements equal to the number of (contiguous) iterations the
   // current thread will perform.  controlb and controlp variables are
   // temporaries to handle deallocation of rprivb at the end of second
   // GOMP_FOR.
   #pragma omp for _scantemp_(rpriva) _scantemp_(rprivb) _scantemp_(controlb) \
     _scantemp_(controlp) reduction(inscan,+:r) private(i) nowait
   for (i = 0; i < n; i = i + 1)
     {
       {
	 // For UDRs this is UDR init or copy from var3.
	 r = 0;
	 // This is the input phase from user code.
	 update (r);
       }
       {
	 // For UDRs this is UDR merge.
	 var2 = var2 + r;
	 // Rather than handing it over to the user, save to local thread's
	 // array.
	 rprivb[ivar] = var2;
	 // For exclusive scan, the above two statements are swapped.
	 ivar = ivar + 1;
       }
     }
   // And remember the final value from this thread's into the shared
   // rpriva array.
   rpriva[(sizetype) thread_num] = var2;
   // If more than one thread, compute using Work-Efficient prefix sum
   // the inclusive parallel scan of the rpriva array.
   if (num_threads > 1) goto <D.2102>; else goto <D.2103>;
   <D.2102>:
   GOMP_barrier ();
   down = 0;
   k = 1;
   num_threadsu = (unsigned int) num_threads;
   thread_numup1 = (unsigned int) thread_num + 1;
   <D.2108>:
   twok = k << 1;
   if (twok > num_threadsu) goto <D.2110>; else goto <D.2111>;
   <D.2110>:
   down = 4294967295;
   k = k >> 1;
   if (k == num_threadsu) goto <D.2112>; else goto <D.2111>;
   <D.2112>:
   k = k >> 1;
   <D.2111>:
   twok = k << 1;
   cplx = .MUL_OVERFLOW (thread_nump1, twok);
   mul = REALPART_EXPR <cplx>;
   ovf = IMAGPART_EXPR <cplx>;
   if (ovf == 0) goto <D.2116>; else goto <D.2117>;
   <D.2116>:
   andv = k & down;
   andvm1 = andv + 4294967295;
   l = mul + andvm1;
   if (l < num_threadsu) goto <D.2120>; else goto <D.2117>;
   <D.2120>:
   // For UDRs this is UDR merge, performed using var2 variable as temporary,
   // i.e. var2 = rpriva[l - k]; UDR merge (var2, rpriva[l]); rpriva[l] = var2;
   rpriva[l] = rpriva[l - k] + rpriva[l];
   <D.2117>:
   if (down == 0) goto <D.2121>; else goto <D.2122>;
   <D.2121>:
   k = k << 1;
   goto <D.2123>;
   <D.2122>:
   k = k >> 1;
   <D.2123>:
   GOMP_barrier ();
   if (k != 0) goto <D.2108>; else goto <D.2103>;
   <D.2103>:
   if (thread_num == 0) goto <D.2124>; else goto <D.2125>;
   <D.2124>:
   // For UDRs this is UDR init or copy from var3.
   var2 = 0;
   goto <D.2126>;
   <D.2125>:
   var2 = rpriva[thread_num - 1];
   <D.2126>:
   ivar = 0;
   #pragma omp for _scantemp_(controlb) _scantemp_(controlp) \
     reduction(inscan,+:r) private(i)
   for (i = 0; i < n; i = i + 1)
     {
       {
	 // For UDRs, this is r = var2; UDR merge (r, rprivb[ivar]);
	 r = var2 + rprivb[ivar];
       }
       {
	 // This is the scan phase from user code.
	 use (r);
	 // Plus a bump of the iterator.
	 ivar = ivar + 1;
       }
     }  */

static void
lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
		    struct omp_for_data *fd, omp_context *ctx)
{
  bool is_for_simd = gimple_omp_for_combined_p (stmt);
  gcc_assert (ctx->scan_inclusive || ctx->scan_exclusive);

  gimple_seq body = gimple_omp_body (stmt);
  gimple_stmt_iterator input1_gsi = gsi_none ();
  struct walk_stmt_info wi;
  memset (&wi, 0, sizeof (wi));
  wi.val_only = true;
  wi.info = (void *) &input1_gsi;
  walk_gimple_seq_mod (&body, omp_find_scan, NULL, &wi);
  gcc_assert (!gsi_end_p (input1_gsi));

  gimple *input_stmt1 = gsi_stmt (input1_gsi);
  gimple_stmt_iterator gsi = input1_gsi;
  gsi_next (&gsi);
  gimple_stmt_iterator scan1_gsi = gsi;
  gimple *scan_stmt1 = gsi_stmt (gsi);
  gcc_assert (scan_stmt1 && gimple_code (scan_stmt1) == GIMPLE_OMP_SCAN);

  gimple_seq input_body = gimple_omp_body (input_stmt1);
  gimple_seq scan_body = gimple_omp_body (scan_stmt1);
  gimple_omp_set_body (input_stmt1, NULL);
  gimple_omp_set_body (scan_stmt1, NULL);
  gimple_omp_set_body (stmt, NULL);

  gomp_for *new_stmt = as_a <gomp_for *> (gimple_copy (stmt));
  gimple_seq new_body = copy_gimple_seq_and_replace_locals (body);
  gimple_omp_set_body (stmt, body);
  gimple_omp_set_body (input_stmt1, input_body);

  gimple_stmt_iterator input2_gsi = gsi_none ();
  memset (&wi, 0, sizeof (wi));
  wi.val_only = true;
  wi.info = (void *) &input2_gsi;
  walk_gimple_seq_mod (&new_body, omp_find_scan, NULL, &wi);
  gcc_assert (!gsi_end_p (input2_gsi));

  gimple *input_stmt2 = gsi_stmt (input2_gsi);
  gsi = input2_gsi;
  gsi_next (&gsi);
  gimple_stmt_iterator scan2_gsi = gsi;
  gimple *scan_stmt2 = gsi_stmt (gsi);
  gcc_assert (scan_stmt2 && gimple_code (scan_stmt2) == GIMPLE_OMP_SCAN);
  gimple_omp_set_body (scan_stmt2, scan_body);

  gimple_stmt_iterator input3_gsi = gsi_none ();
  gimple_stmt_iterator scan3_gsi = gsi_none ();
  gimple_stmt_iterator input4_gsi = gsi_none ();
  gimple_stmt_iterator scan4_gsi = gsi_none ();
  gimple *input_stmt3 = NULL, *scan_stmt3 = NULL;
  gimple *input_stmt4 = NULL, *scan_stmt4 = NULL;
  omp_context *input_simd_ctx = NULL, *scan_simd_ctx = NULL;
  if (is_for_simd)
    {
      memset (&wi, 0, sizeof (wi));
      wi.val_only = true;
      wi.info = (void *) &input3_gsi;
      walk_gimple_seq_mod (&input_body, omp_find_scan, NULL, &wi);
      gcc_assert (!gsi_end_p (input3_gsi));

      input_stmt3 = gsi_stmt (input3_gsi);
      gsi = input3_gsi;
      gsi_next (&gsi);
      scan3_gsi = gsi;
      scan_stmt3 = gsi_stmt (gsi);
      gcc_assert (scan_stmt3 && gimple_code (scan_stmt3) == GIMPLE_OMP_SCAN);

      memset (&wi, 0, sizeof (wi));
      wi.val_only = true;
      wi.info = (void *) &input4_gsi;
      walk_gimple_seq_mod (&scan_body, omp_find_scan, NULL, &wi);
      gcc_assert (!gsi_end_p (input4_gsi));

      input_stmt4 = gsi_stmt (input4_gsi);
      gsi = input4_gsi;
      gsi_next (&gsi);
      scan4_gsi = gsi;
      scan_stmt4 = gsi_stmt (gsi);
      gcc_assert (scan_stmt4 && gimple_code (scan_stmt4) == GIMPLE_OMP_SCAN);

      input_simd_ctx = maybe_lookup_ctx (input_stmt3)->outer;
      scan_simd_ctx = maybe_lookup_ctx (input_stmt4)->outer;
    }

  tree num_threads = create_tmp_var (integer_type_node);
  tree thread_num = create_tmp_var (integer_type_node);
  tree nthreads_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
  tree threadnum_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
  gimple *g = gimple_build_call (nthreads_decl, 0);
  gimple_call_set_lhs (g, num_threads);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_call (threadnum_decl, 0);
  gimple_call_set_lhs (g, thread_num);
  gimple_seq_add_stmt (body_p, g);

  tree ivar = create_tmp_var (sizetype);
  tree new_clauses1 = NULL_TREE, new_clauses2 = NULL_TREE;
  tree *cp1 = &new_clauses1, *cp2 = &new_clauses2;
  tree k = create_tmp_var (unsigned_type_node);
  tree l = create_tmp_var (unsigned_type_node);

  gimple_seq clist = NULL, mdlist = NULL;
  gimple_seq thr01_list = NULL, thrn1_list = NULL;
  gimple_seq thr02_list = NULL, thrn2_list = NULL;
  gimple_seq scan1_list = NULL, input2_list = NULL;
  gimple_seq last_list = NULL, reduc_list = NULL;
  for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
	&& OMP_CLAUSE_REDUCTION_INSCAN (c))
      {
	location_t clause_loc = OMP_CLAUSE_LOCATION (c);
	tree var = OMP_CLAUSE_DECL (c);
	tree new_var = lookup_decl (var, ctx);
	tree var3 = NULL_TREE;
	tree new_vard = new_var;
	if (omp_privatize_by_reference (var))
	  new_var = build_simple_mem_ref_loc (clause_loc, new_var);
	if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
	  {
	    var3 = maybe_lookup_decl (new_vard, ctx);
	    if (var3 == new_vard)
	      var3 = NULL_TREE;
	  }

	tree ptype = build_pointer_type (TREE_TYPE (new_var));
	tree rpriva = create_tmp_var (ptype);
	tree nc = build_omp_clause (clause_loc, OMP_CLAUSE__SCANTEMP_);
	OMP_CLAUSE_DECL (nc) = rpriva;
	*cp1 = nc;
	cp1 = &OMP_CLAUSE_CHAIN (nc);

	tree rprivb = create_tmp_var (ptype);
	nc = build_omp_clause (clause_loc, OMP_CLAUSE__SCANTEMP_);
	OMP_CLAUSE_DECL (nc) = rprivb;
	OMP_CLAUSE__SCANTEMP__ALLOC (nc) = 1;
	*cp1 = nc;
	cp1 = &OMP_CLAUSE_CHAIN (nc);

	tree var2 = create_tmp_var_raw (TREE_TYPE (new_var));
	if (new_vard != new_var)
	  TREE_ADDRESSABLE (var2) = 1;
	gimple_add_tmp_var (var2);

	tree x = fold_convert_loc (clause_loc, sizetype, thread_num);
	x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, x,
			     TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
	x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rpriva), rpriva, x);
	tree rpriva_ref = build_simple_mem_ref_loc (clause_loc, x);

	x = fold_build2_loc (clause_loc, PLUS_EXPR, integer_type_node,
			     thread_num, integer_minus_one_node);
	x = fold_convert_loc (clause_loc, sizetype, x);
	x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, x,
			     TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
	x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rpriva), rpriva, x);
	tree rprivam1_ref = build_simple_mem_ref_loc (clause_loc, x);

	x = fold_convert_loc (clause_loc, sizetype, l);
	x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, x,
			     TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
	x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rpriva), rpriva, x);
	tree rprival_ref = build_simple_mem_ref_loc (clause_loc, x);

	x = fold_build2_loc (clause_loc, MINUS_EXPR, unsigned_type_node, l, k);
	x = fold_convert_loc (clause_loc, sizetype, x);
	x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, x,
			     TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
	x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rpriva), rpriva, x);
	tree rprivalmk_ref = build_simple_mem_ref_loc (clause_loc, x);

	x = fold_build2_loc (clause_loc, MULT_EXPR, sizetype, ivar,
			     TYPE_SIZE_UNIT (TREE_TYPE (ptype)));
	x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rprivb), rprivb, x);
	tree rprivb_ref = build_simple_mem_ref_loc (clause_loc, x);

	tree var4 = is_for_simd ? new_var : var2;
	tree var5 = NULL_TREE, var6 = NULL_TREE;
	if (is_for_simd)
	  {
	    var5 = lookup_decl (var, input_simd_ctx);
	    var6 = lookup_decl (var, scan_simd_ctx);
	    if (new_vard != new_var)
	      {
		var5 = build_simple_mem_ref_loc (clause_loc, var5);
		var6 = build_simple_mem_ref_loc (clause_loc, var6);
	      }
	  }
	if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
	  {
	    tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
	    tree val = var2;

	    x = lang_hooks.decls.omp_clause_default_ctor
		    (c, var2, build_outer_var_ref (var, ctx));
	    if (x)
	      gimplify_and_add (x, &clist);

	    x = build_outer_var_ref (var, ctx);
	    x = lang_hooks.decls.omp_clause_assign_op (c, unshare_expr (var4),
						       x);
	    gimplify_and_add (x, &thr01_list);

	    tree y = (DECL_HAS_VALUE_EXPR_P (new_vard)
		      ? DECL_VALUE_EXPR (new_vard) : NULL_TREE);
	    if (var3)
	      {
		x = unshare_expr (var4);
		x = lang_hooks.decls.omp_clause_assign_op (c, x, var3);
		gimplify_and_add (x, &thrn1_list);
		x = unshare_expr (var4);
		x = lang_hooks.decls.omp_clause_assign_op (c, x, var3);
		gimplify_and_add (x, &thr02_list);
	      }
	    else if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
	      {
		/* Otherwise, assign to it the identity element.  */
		gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
		tseq = copy_gimple_seq_and_replace_locals (tseq);
		if (!is_for_simd)
		  {
		    if (new_vard != new_var)
		      val = build_fold_addr_expr_loc (clause_loc, val);
		    SET_DECL_VALUE_EXPR (new_vard, val);
		    DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
		  }
		SET_DECL_VALUE_EXPR (placeholder, error_mark_node);
		DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
		lower_omp (&tseq, ctx);
		gimple_seq_add_seq (&thrn1_list, tseq);
		tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
		lower_omp (&tseq, ctx);
		gimple_seq_add_seq (&thr02_list, tseq);
		SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
		DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
		OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
		if (y)
		  SET_DECL_VALUE_EXPR (new_vard, y);
		else
		  {
		    DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
		    SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
		  }
	      }

	    x = unshare_expr (var4);
	    x = lang_hooks.decls.omp_clause_assign_op (c, x, rprivam1_ref);
	    gimplify_and_add (x, &thrn2_list);

	    if (is_for_simd)
	      {
		x = unshare_expr (rprivb_ref);
		x = lang_hooks.decls.omp_clause_assign_op (c, x, var5);
		gimplify_and_add (x, &scan1_list);
	      }
	    else
	      {
		if (ctx->scan_exclusive)
		  {
		    x = unshare_expr (rprivb_ref);
		    x = lang_hooks.decls.omp_clause_assign_op (c, x, var2);
		    gimplify_and_add (x, &scan1_list);
		  }

		gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
		tseq = copy_gimple_seq_and_replace_locals (tseq);
		SET_DECL_VALUE_EXPR (placeholder, var2);
		DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
		lower_omp (&tseq, ctx);
		gimple_seq_add_seq (&scan1_list, tseq);

		if (ctx->scan_inclusive)
		  {
		    x = unshare_expr (rprivb_ref);
		    x = lang_hooks.decls.omp_clause_assign_op (c, x, var2);
		    gimplify_and_add (x, &scan1_list);
		  }
	      }

	    x = unshare_expr (rpriva_ref);
	    x = lang_hooks.decls.omp_clause_assign_op (c, x,
						       unshare_expr (var4));
	    gimplify_and_add (x, &mdlist);

	    x = unshare_expr (is_for_simd ? var6 : new_var);
	    x = lang_hooks.decls.omp_clause_assign_op (c, x, var4);
	    gimplify_and_add (x, &input2_list);

	    val = rprivb_ref;
	    if (new_vard != new_var)
	      val = build_fold_addr_expr_loc (clause_loc, val);

	    gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
	    tseq = copy_gimple_seq_and_replace_locals (tseq);
	    SET_DECL_VALUE_EXPR (new_vard, val);
	    DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
	    if (is_for_simd)
	      {
		SET_DECL_VALUE_EXPR (placeholder, var6);
		DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
	      }
	    else
	      DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
	    lower_omp (&tseq, ctx);
	    if (y)
	      SET_DECL_VALUE_EXPR (new_vard, y);
	    else
	      {
		DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
		SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
	      }
	    if (!is_for_simd)
	      {
		SET_DECL_VALUE_EXPR (placeholder, new_var);
		DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
		lower_omp (&tseq, ctx);
	      }
	    gimple_seq_add_seq (&input2_list, tseq);

	    x = build_outer_var_ref (var, ctx);
	    x = lang_hooks.decls.omp_clause_assign_op (c, x, rpriva_ref);
	    gimplify_and_add (x, &last_list);

	    x = lang_hooks.decls.omp_clause_assign_op (c, var2, rprivalmk_ref);
	    gimplify_and_add (x, &reduc_list);
	    tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
	    tseq = copy_gimple_seq_and_replace_locals (tseq);
	    val = rprival_ref;
	    if (new_vard != new_var)
	      val = build_fold_addr_expr_loc (clause_loc, val);
	    SET_DECL_VALUE_EXPR (new_vard, val);
	    DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
	    SET_DECL_VALUE_EXPR (placeholder, var2);
	    lower_omp (&tseq, ctx);
	    OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
	    SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
	    DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
	    if (y)
	      SET_DECL_VALUE_EXPR (new_vard, y);
	    else
	      {
		DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
		SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
	      }
	    gimple_seq_add_seq (&reduc_list, tseq);
	    x = lang_hooks.decls.omp_clause_assign_op (c, rprival_ref, var2);
	    gimplify_and_add (x, &reduc_list);

	    x = lang_hooks.decls.omp_clause_dtor (c, var2);
	    if (x)
	      gimplify_and_add (x, dlist);
	  }
	else
	  {
	    x = build_outer_var_ref (var, ctx);
	    gimplify_assign (unshare_expr (var4), x, &thr01_list);

	    x = omp_reduction_init (c, TREE_TYPE (new_var));
	    gimplify_assign (unshare_expr (var4), unshare_expr (x),
			     &thrn1_list);
	    gimplify_assign (unshare_expr (var4), x, &thr02_list);

	    gimplify_assign (unshare_expr (var4), rprivam1_ref, &thrn2_list);

	    enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
	    if (code == MINUS_EXPR)
	      code = PLUS_EXPR;

	    if (is_for_simd)
	      gimplify_assign (unshare_expr (rprivb_ref), var5, &scan1_list);
	    else
	      {
		if (ctx->scan_exclusive)
		  gimplify_assign (unshare_expr (rprivb_ref), var2,
				   &scan1_list);
		x = build2 (code, TREE_TYPE (new_var), var2, new_var);
		gimplify_assign (var2, x, &scan1_list);
		if (ctx->scan_inclusive)
		  gimplify_assign (unshare_expr (rprivb_ref), var2,
				   &scan1_list);
	      }

	    gimplify_assign (unshare_expr (rpriva_ref), unshare_expr (var4),
			     &mdlist);

	    x = build2 (code, TREE_TYPE (new_var), var4, rprivb_ref);
	    gimplify_assign (is_for_simd ? var6 : new_var, x, &input2_list);

	    gimplify_assign (build_outer_var_ref (var, ctx), rpriva_ref,
			     &last_list);

	    x = build2 (code, TREE_TYPE (new_var), rprivalmk_ref,
			unshare_expr (rprival_ref));
	    gimplify_assign (rprival_ref, x, &reduc_list);
	  }
      }

  g = gimple_build_assign (ivar, PLUS_EXPR, ivar, size_one_node);
  gimple_seq_add_stmt (&scan1_list, g);
  g = gimple_build_assign (ivar, PLUS_EXPR, ivar, size_one_node);
  gimple_seq_add_stmt (gimple_omp_body_ptr (is_for_simd
					    ? scan_stmt4 : scan_stmt2), g);

  tree controlb = create_tmp_var (boolean_type_node);
  tree controlp = create_tmp_var (ptr_type_node);
  tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SCANTEMP_);
  OMP_CLAUSE_DECL (nc) = controlb;
  OMP_CLAUSE__SCANTEMP__CONTROL (nc) = 1;
  *cp1 = nc;
  cp1 = &OMP_CLAUSE_CHAIN (nc);
  nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SCANTEMP_);
  OMP_CLAUSE_DECL (nc) = controlp;
  OMP_CLAUSE__SCANTEMP__CONTROL (nc) = 1;
  *cp1 = nc;
  cp1 = &OMP_CLAUSE_CHAIN (nc);
  nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SCANTEMP_);
  OMP_CLAUSE_DECL (nc) = controlb;
  OMP_CLAUSE__SCANTEMP__CONTROL (nc) = 1;
  *cp2 = nc;
  cp2 = &OMP_CLAUSE_CHAIN (nc);
  nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SCANTEMP_);
  OMP_CLAUSE_DECL (nc) = controlp;
  OMP_CLAUSE__SCANTEMP__CONTROL (nc) = 1;
  *cp2 = nc;
  cp2 = &OMP_CLAUSE_CHAIN (nc);

  *cp1 = gimple_omp_for_clauses (stmt);
  gimple_omp_for_set_clauses (stmt, new_clauses1);
  *cp2 = gimple_omp_for_clauses (new_stmt);
  gimple_omp_for_set_clauses (new_stmt, new_clauses2);

  if (is_for_simd)
    {
      gimple_seq_add_seq (gimple_omp_body_ptr (scan_stmt3), scan1_list);
      gimple_seq_add_seq (gimple_omp_body_ptr (input_stmt4), input2_list);

      gsi_insert_seq_after (&input3_gsi, gimple_omp_body (input_stmt3),
			    GSI_SAME_STMT);
      gsi_remove (&input3_gsi, true);
      gsi_insert_seq_after (&scan3_gsi, gimple_omp_body (scan_stmt3),
			    GSI_SAME_STMT);
      gsi_remove (&scan3_gsi, true);
      gsi_insert_seq_after (&input4_gsi, gimple_omp_body (input_stmt4),
			    GSI_SAME_STMT);
      gsi_remove (&input4_gsi, true);
      gsi_insert_seq_after (&scan4_gsi, gimple_omp_body (scan_stmt4),
			    GSI_SAME_STMT);
      gsi_remove (&scan4_gsi, true);
    }
  else
    {
      gimple_omp_set_body (scan_stmt1, scan1_list);
      gimple_omp_set_body (input_stmt2, input2_list);
    }

  gsi_insert_seq_after (&input1_gsi, gimple_omp_body (input_stmt1),
			GSI_SAME_STMT);
  gsi_remove (&input1_gsi, true);
  gsi_insert_seq_after (&scan1_gsi, gimple_omp_body (scan_stmt1),
			GSI_SAME_STMT);
  gsi_remove (&scan1_gsi, true);
  gsi_insert_seq_after (&input2_gsi, gimple_omp_body (input_stmt2),
			GSI_SAME_STMT);
  gsi_remove (&input2_gsi, true);
  gsi_insert_seq_after (&scan2_gsi, gimple_omp_body (scan_stmt2),
			GSI_SAME_STMT);
  gsi_remove (&scan2_gsi, true);

  gimple_seq_add_seq (body_p, clist);

  tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
  tree lab2 = create_artificial_label (UNKNOWN_LOCATION);
  tree lab3 = create_artificial_label (UNKNOWN_LOCATION);
  g = gimple_build_cond (EQ_EXPR, thread_num, integer_zero_node, lab1, lab2);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_label (lab1);
  gimple_seq_add_stmt (body_p, g);
  gimple_seq_add_seq (body_p, thr01_list);
  g = gimple_build_goto (lab3);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_label (lab2);
  gimple_seq_add_stmt (body_p, g);
  gimple_seq_add_seq (body_p, thrn1_list);
  g = gimple_build_label (lab3);
  gimple_seq_add_stmt (body_p, g);

  g = gimple_build_assign (ivar, size_zero_node);
  gimple_seq_add_stmt (body_p, g);

  gimple_seq_add_stmt (body_p, stmt);
  gimple_seq_add_seq (body_p, body);
  gimple_seq_add_stmt (body_p, gimple_build_omp_continue (fd->loop.v,
							  fd->loop.v));

  g = gimple_build_omp_return (true);
  gimple_seq_add_stmt (body_p, g);
  gimple_seq_add_seq (body_p, mdlist);

  lab1 = create_artificial_label (UNKNOWN_LOCATION);
  lab2 = create_artificial_label (UNKNOWN_LOCATION);
  g = gimple_build_cond (GT_EXPR, num_threads, integer_one_node, lab1, lab2);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_label (lab1);
  gimple_seq_add_stmt (body_p, g);

  g = omp_build_barrier (NULL);
  gimple_seq_add_stmt (body_p, g);

  tree down = create_tmp_var (unsigned_type_node);
  g = gimple_build_assign (down, build_zero_cst (unsigned_type_node));
  gimple_seq_add_stmt (body_p, g);

  g = gimple_build_assign (k, build_one_cst (unsigned_type_node));
  gimple_seq_add_stmt (body_p, g);

  tree num_threadsu = create_tmp_var (unsigned_type_node);
  g = gimple_build_assign (num_threadsu, NOP_EXPR, num_threads);
  gimple_seq_add_stmt (body_p, g);

  tree thread_numu = create_tmp_var (unsigned_type_node);
  g = gimple_build_assign (thread_numu, NOP_EXPR, thread_num);
  gimple_seq_add_stmt (body_p, g);

  tree thread_nump1 = create_tmp_var (unsigned_type_node);
  g = gimple_build_assign (thread_nump1, PLUS_EXPR, thread_numu,
			   build_int_cst (unsigned_type_node, 1));
  gimple_seq_add_stmt (body_p, g);

  lab3 = create_artificial_label (UNKNOWN_LOCATION);
  g = gimple_build_label (lab3);
  gimple_seq_add_stmt (body_p, g);

  tree twok = create_tmp_var (unsigned_type_node);
  g = gimple_build_assign (twok, LSHIFT_EXPR, k, integer_one_node);
  gimple_seq_add_stmt (body_p, g);

  tree lab4 = create_artificial_label (UNKNOWN_LOCATION);
  tree lab5 = create_artificial_label (UNKNOWN_LOCATION);
  tree lab6 = create_artificial_label (UNKNOWN_LOCATION);
  g = gimple_build_cond (GT_EXPR, twok, num_threadsu, lab4, lab5);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_label (lab4);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_assign (down, build_all_ones_cst (unsigned_type_node));
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_assign (k, RSHIFT_EXPR, k, integer_one_node);
  gimple_seq_add_stmt (body_p, g);

  g = gimple_build_cond (EQ_EXPR, k, num_threadsu, lab6, lab5);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_label (lab6);
  gimple_seq_add_stmt (body_p, g);

  g = gimple_build_assign (k, RSHIFT_EXPR, k, integer_one_node);
  gimple_seq_add_stmt (body_p, g);

  g = gimple_build_label (lab5);
  gimple_seq_add_stmt (body_p, g);

  g = gimple_build_assign (twok, LSHIFT_EXPR, k, integer_one_node);
  gimple_seq_add_stmt (body_p, g);

  tree cplx = create_tmp_var (build_complex_type (unsigned_type_node, false));
  g = gimple_build_call_internal (IFN_MUL_OVERFLOW, 2, thread_nump1, twok);
  gimple_call_set_lhs (g, cplx);
  gimple_seq_add_stmt (body_p, g);
  tree mul = create_tmp_var (unsigned_type_node);
  g = gimple_build_assign (mul, REALPART_EXPR,
			   build1 (REALPART_EXPR, unsigned_type_node, cplx));
  gimple_seq_add_stmt (body_p, g);
  tree ovf = create_tmp_var (unsigned_type_node);
  g = gimple_build_assign (ovf, IMAGPART_EXPR,
			   build1 (IMAGPART_EXPR, unsigned_type_node, cplx));
  gimple_seq_add_stmt (body_p, g);

  tree lab7 = create_artificial_label (UNKNOWN_LOCATION);
  tree lab8 = create_artificial_label (UNKNOWN_LOCATION);
  g = gimple_build_cond (EQ_EXPR, ovf, build_zero_cst (unsigned_type_node),
			 lab7, lab8);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_label (lab7);
  gimple_seq_add_stmt (body_p, g);

  tree andv = create_tmp_var (unsigned_type_node);
  g = gimple_build_assign (andv, BIT_AND_EXPR, k, down);
  gimple_seq_add_stmt (body_p, g);
  tree andvm1 = create_tmp_var (unsigned_type_node);
  g = gimple_build_assign (andvm1, PLUS_EXPR, andv,
			   build_minus_one_cst (unsigned_type_node));
  gimple_seq_add_stmt (body_p, g);

  g = gimple_build_assign (l, PLUS_EXPR, mul, andvm1);
  gimple_seq_add_stmt (body_p, g);

  tree lab9 = create_artificial_label (UNKNOWN_LOCATION);
  g = gimple_build_cond (LT_EXPR, l, num_threadsu, lab9, lab8);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_label (lab9);
  gimple_seq_add_stmt (body_p, g);
  gimple_seq_add_seq (body_p, reduc_list);
  g = gimple_build_label (lab8);
  gimple_seq_add_stmt (body_p, g);

  tree lab10 = create_artificial_label (UNKNOWN_LOCATION);
  tree lab11 = create_artificial_label (UNKNOWN_LOCATION);
  tree lab12 = create_artificial_label (UNKNOWN_LOCATION);
  g = gimple_build_cond (EQ_EXPR, down, build_zero_cst (unsigned_type_node),
			 lab10, lab11);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_label (lab10);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_assign (k, LSHIFT_EXPR, k, integer_one_node);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_goto (lab12);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_label (lab11);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_assign (k, RSHIFT_EXPR, k, integer_one_node);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_label (lab12);
  gimple_seq_add_stmt (body_p, g);

  g = omp_build_barrier (NULL);
  gimple_seq_add_stmt (body_p, g);

  g = gimple_build_cond (NE_EXPR, k, build_zero_cst (unsigned_type_node),
			 lab3, lab2);
  gimple_seq_add_stmt (body_p, g);

  g = gimple_build_label (lab2);
  gimple_seq_add_stmt (body_p, g);

  lab1 = create_artificial_label (UNKNOWN_LOCATION);
  lab2 = create_artificial_label (UNKNOWN_LOCATION);
  lab3 = create_artificial_label (UNKNOWN_LOCATION);
  g = gimple_build_cond (EQ_EXPR, thread_num, integer_zero_node, lab1, lab2);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_label (lab1);
  gimple_seq_add_stmt (body_p, g);
  gimple_seq_add_seq (body_p, thr02_list);
  g = gimple_build_goto (lab3);
  gimple_seq_add_stmt (body_p, g);
  g = gimple_build_label (lab2);
  gimple_seq_add_stmt (body_p, g);
  gimple_seq_add_seq (body_p, thrn2_list);
  g = gimple_build_label (lab3);
  gimple_seq_add_stmt (body_p, g);

  g = gimple_build_assign (ivar, size_zero_node);
  gimple_seq_add_stmt (body_p, g);
  gimple_seq_add_stmt (body_p, new_stmt);
  gimple_seq_add_seq (body_p, new_body);

  gimple_seq new_dlist = NULL;
  lab1 = create_artificial_label (UNKNOWN_LOCATION);
  lab2 = create_artificial_label (UNKNOWN_LOCATION);
  tree num_threadsm1 = create_tmp_var (integer_type_node);
  g = gimple_build_assign (num_threadsm1, PLUS_EXPR, num_threads,
			   integer_minus_one_node);
  gimple_seq_add_stmt (&new_dlist, g);
  g = gimple_build_cond (EQ_EXPR, thread_num, num_threadsm1, lab1, lab2);
  gimple_seq_add_stmt (&new_dlist, g);
  g = gimple_build_label (lab1);
  gimple_seq_add_stmt (&new_dlist, g);
  gimple_seq_add_seq (&new_dlist, last_list);
  g = gimple_build_label (lab2);
  gimple_seq_add_stmt (&new_dlist, g);
  gimple_seq_add_seq (&new_dlist, *dlist);
  *dlist = new_dlist;
}

/* Build an internal UNIQUE function with type IFN_UNIQUE_OACC_PRIVATE listing
   the addresses of variables to be made private at the surrounding
   parallelism level.  Such functions appear in the gimple code stream in two
   forms, e.g. for a partitioned loop:

      .data_dep.6 = .UNIQUE (OACC_HEAD_MARK, .data_dep.6, 1, 68);
      .data_dep.6 = .UNIQUE (OACC_PRIVATE, .data_dep.6, -1, &w);
      .data_dep.6 = .UNIQUE (OACC_FORK, .data_dep.6, -1);
      .data_dep.6 = .UNIQUE (OACC_HEAD_MARK, .data_dep.6);

   or alternatively, OACC_PRIVATE can appear at the top level of a parallel,
   not as part of a HEAD_MARK sequence:

      .UNIQUE (OACC_PRIVATE, 0, 0, &w);

   For such stand-alone appearances, the 3rd argument is always 0, denoting
   gang partitioning.  */

static gcall *
lower_oacc_private_marker (omp_context *ctx)
{
  if (ctx->oacc_privatization_candidates.length () == 0)
    return NULL;

  auto_vec<tree, 5> args;

  args.quick_push (build_int_cst (integer_type_node, IFN_UNIQUE_OACC_PRIVATE));
  args.quick_push (integer_zero_node);
  args.quick_push (integer_minus_one_node);

  int i;
  tree decl;
  FOR_EACH_VEC_ELT (ctx->oacc_privatization_candidates, i, decl)
    {
      for (omp_context *thisctx = ctx; thisctx; thisctx = thisctx->outer)
	{
	  tree inner_decl = maybe_lookup_decl (decl, thisctx);
	  if (inner_decl)
	    {
	      decl = inner_decl;
	      break;
	    }
	}
      gcc_checking_assert (decl);

      tree addr = build_fold_addr_expr (decl);
      args.safe_push (addr);
    }

  return gimple_build_call_internal_vec (IFN_UNIQUE, args);
}

/* Lower code for an OMP loop directive.  */

static void
lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
  tree *rhs_p, block;
  struct omp_for_data fd, *fdp = NULL;
  gomp_for *stmt = as_a <gomp_for *> (gsi_stmt (*gsi_p));
  gbind *new_stmt;
  gimple_seq omp_for_body, body, dlist, tred_ilist = NULL, tred_dlist = NULL;
  gimple_seq cnt_list = NULL, clist = NULL;
  gimple_seq oacc_head = NULL, oacc_tail = NULL;
  size_t i;

  push_gimplify_context ();

  if (is_gimple_omp_oacc (ctx->stmt))
    oacc_privatization_scan_clause_chain (ctx, gimple_omp_for_clauses (stmt));

  lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);

  block = make_node (BLOCK);
  new_stmt = gimple_build_bind (NULL, NULL, block);
  /* Replace at gsi right away, so that 'stmt' is no member
     of a sequence anymore as we're going to add to a different
     one below.  */
  gsi_replace (gsi_p, new_stmt, true);

  /* Move declaration of temporaries in the loop body before we make
     it go away.  */
  omp_for_body = gimple_omp_body (stmt);
  if (!gimple_seq_empty_p (omp_for_body)
      && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
    {
      gbind *inner_bind
	= as_a <gbind *> (gimple_seq_first_stmt (omp_for_body));
      tree vars = gimple_bind_vars (inner_bind);
      if (is_gimple_omp_oacc (ctx->stmt))
	oacc_privatization_scan_decl_chain (ctx, vars);
      gimple_bind_append_vars (new_stmt, vars);
      /* bind_vars/BLOCK_VARS are being moved to new_stmt/block, don't
	 keep them on the inner_bind and it's block.  */
      gimple_bind_set_vars (inner_bind, NULL_TREE);
      if (gimple_bind_block (inner_bind))
	BLOCK_VARS (gimple_bind_block (inner_bind)) = NULL_TREE;
    }

  if (gimple_omp_for_combined_into_p (stmt))
    {
      omp_extract_for_data (stmt, &fd, NULL);
      fdp = &fd;

      /* We need two temporaries with fd.loop.v type (istart/iend)
	 and then (fd.collapse - 1) temporaries with the same
	 type for count2 ... countN-1 vars if not constant.  */
      size_t count = 2;
      tree type = fd.iter_type;
      if (fd.collapse > 1
	  && TREE_CODE (fd.loop.n2) != INTEGER_CST)
	count += fd.collapse - 1;
      size_t count2 = 0;
      tree type2 = NULL_TREE;
      bool taskreg_for
	= (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR
	   || gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_TASKLOOP);
      tree outerc = NULL, *pc = gimple_omp_for_clauses_ptr (stmt);
      tree simtc = NULL;
      tree clauses = *pc;
      if (fd.collapse > 1
	  && fd.non_rect
	  && fd.last_nonrect == fd.first_nonrect + 1
	  && TREE_CODE (fd.loop.n2) != INTEGER_CST)
	if (tree v = gimple_omp_for_index (stmt, fd.last_nonrect))
	  if (!TYPE_UNSIGNED (TREE_TYPE (v)))
	    {
	      v = gimple_omp_for_index (stmt, fd.first_nonrect);
	      type2 = TREE_TYPE (v);
	      count++;
	      count2 = 3;
	    }
      if (taskreg_for)
	outerc
	  = omp_find_clause (gimple_omp_taskreg_clauses (ctx->outer->stmt),
			     OMP_CLAUSE__LOOPTEMP_);
      if (ctx->simt_stmt)
	simtc = omp_find_clause (gimple_omp_for_clauses (ctx->simt_stmt),
				 OMP_CLAUSE__LOOPTEMP_);
      for (i = 0; i < count + count2; i++)
	{
	  tree temp;
	  if (taskreg_for)
	    {
	      gcc_assert (outerc);
	      temp = lookup_decl (OMP_CLAUSE_DECL (outerc), ctx->outer);
	      outerc = omp_find_clause (OMP_CLAUSE_CHAIN (outerc),
					OMP_CLAUSE__LOOPTEMP_);
	    }
	  else
	    {
	      /* If there are 2 adjacent SIMD stmts, one with _simt_
		 clause, another without, make sure they have the same
		 decls in _looptemp_ clauses, because the outer stmt
		 they are combined into will look up just one inner_stmt.  */
	      if (ctx->simt_stmt)
		temp = OMP_CLAUSE_DECL (simtc);
	      else
		temp = create_tmp_var (i >= count ? type2 : type);
	      insert_decl_map (&ctx->outer->cb, temp, temp);
	    }
	  *pc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_);
	  OMP_CLAUSE_DECL (*pc) = temp;
	  pc = &OMP_CLAUSE_CHAIN (*pc);
	  if (ctx->simt_stmt)
	    simtc = omp_find_clause (OMP_CLAUSE_CHAIN (simtc),
				     OMP_CLAUSE__LOOPTEMP_);
	}
      *pc = clauses;
    }

  /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR.  */
  dlist = NULL;
  body = NULL;
  tree rclauses
    = omp_task_reductions_find_first (gimple_omp_for_clauses (stmt), OMP_FOR,
				      OMP_CLAUSE_REDUCTION);
  tree rtmp = NULL_TREE;
  if (rclauses)
    {
      tree type = build_pointer_type (pointer_sized_int_node);
      tree temp = create_tmp_var (type);
      tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__REDUCTEMP_);
      OMP_CLAUSE_DECL (c) = temp;
      OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (stmt);
      gimple_omp_for_set_clauses (stmt, c);
      lower_omp_task_reductions (ctx, OMP_FOR,
				 gimple_omp_for_clauses (stmt),
				 &tred_ilist, &tred_dlist);
      rclauses = c;
      rtmp = make_ssa_name (type);
      gimple_seq_add_stmt (&body, gimple_build_assign (rtmp, temp));
    }

  lower_lastprivate_conditional_clauses (gimple_omp_for_clauses_ptr (stmt),
					 ctx);

  lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx,
			   fdp);
  gimple_seq_add_seq (rclauses ? &tred_ilist : &body,
		      gimple_omp_for_pre_body (stmt));

  lower_omp (gimple_omp_body_ptr (stmt), ctx);

  gcall *private_marker = NULL;
  if (is_gimple_omp_oacc (ctx->stmt)
      && !gimple_seq_empty_p (omp_for_body))
    private_marker = lower_oacc_private_marker (ctx);

  /* Lower the header expressions.  At this point, we can assume that
     the header is of the form:

     	#pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)

     We just need to make sure that VAL1, VAL2 and VAL3 are lowered
     using the .omp_data_s mapping, if needed.  */
  for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
    {
      rhs_p = gimple_omp_for_initial_ptr (stmt, i);
      if (TREE_CODE (*rhs_p) == TREE_VEC)
	{
	  if (!is_gimple_min_invariant (TREE_VEC_ELT (*rhs_p, 1)))
	    TREE_VEC_ELT (*rhs_p, 1)
	      = get_formal_tmp_var (TREE_VEC_ELT (*rhs_p, 1), &cnt_list);
	  if (!is_gimple_min_invariant (TREE_VEC_ELT (*rhs_p, 2)))
	    TREE_VEC_ELT (*rhs_p, 2)
	      = get_formal_tmp_var (TREE_VEC_ELT (*rhs_p, 2), &cnt_list);
	}
      else if (!is_gimple_min_invariant (*rhs_p))
	*rhs_p = get_formal_tmp_var (*rhs_p, &cnt_list);
      else if (TREE_CODE (*rhs_p) == ADDR_EXPR)
	recompute_tree_invariant_for_addr_expr (*rhs_p);

      rhs_p = gimple_omp_for_final_ptr (stmt, i);
      if (TREE_CODE (*rhs_p) == TREE_VEC)
	{
	  if (!is_gimple_min_invariant (TREE_VEC_ELT (*rhs_p, 1)))
	    TREE_VEC_ELT (*rhs_p, 1)
	      = get_formal_tmp_var (TREE_VEC_ELT (*rhs_p, 1), &cnt_list);
	  if (!is_gimple_min_invariant (TREE_VEC_ELT (*rhs_p, 2)))
	    TREE_VEC_ELT (*rhs_p, 2)
	      = get_formal_tmp_var (TREE_VEC_ELT (*rhs_p, 2), &cnt_list);
	}
      else if (!is_gimple_min_invariant (*rhs_p))
	*rhs_p = get_formal_tmp_var (*rhs_p, &cnt_list);
      else if (TREE_CODE (*rhs_p) == ADDR_EXPR)
	recompute_tree_invariant_for_addr_expr (*rhs_p);

      rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
      if (!is_gimple_min_invariant (*rhs_p))
	*rhs_p = get_formal_tmp_var (*rhs_p, &cnt_list);
    }
  if (rclauses)
    gimple_seq_add_seq (&tred_ilist, cnt_list);
  else
    gimple_seq_add_seq (&body, cnt_list);

  /* Once lowered, extract the bounds and clauses.  */
  omp_extract_for_data (stmt, &fd, NULL);

  if (is_gimple_omp_oacc (ctx->stmt)
      && !ctx_in_oacc_kernels_region (ctx))
    lower_oacc_head_tail (gimple_location (stmt),
			  gimple_omp_for_clauses (stmt), private_marker,
			  &oacc_head, &oacc_tail, ctx);

  /* Add OpenACC partitioning and reduction markers just before the loop.  */
  if (oacc_head)
    gimple_seq_add_seq (&body, oacc_head);

  lower_omp_for_lastprivate (&fd, &body, &dlist, &clist, ctx);

  if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR)
    for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
	  && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
	{
	  OMP_CLAUSE_DECL (c) = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
	  if (DECL_P (OMP_CLAUSE_LINEAR_STEP (c)))
	    OMP_CLAUSE_LINEAR_STEP (c)
	      = maybe_lookup_decl_in_outer_ctx (OMP_CLAUSE_LINEAR_STEP (c),
						ctx);
	}

  if ((ctx->scan_inclusive || ctx->scan_exclusive)
      && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR)
    lower_omp_for_scan (&body, &dlist, stmt, &fd, ctx);
  else
    {
      gimple_seq_add_stmt (&body, stmt);
      gimple_seq_add_seq (&body, gimple_omp_body (stmt));
    }

  gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
							 fd.loop.v));

  /* After the loop, add exit clauses.  */
  lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, &clist, ctx);

  if (clist)
    {
      tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
      gcall *g = gimple_build_call (fndecl, 0);
      gimple_seq_add_stmt (&body, g);
      gimple_seq_add_seq (&body, clist);
      fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
      g = gimple_build_call (fndecl, 0);
      gimple_seq_add_stmt (&body, g);
    }

  if (ctx->cancellable)
    gimple_seq_add_stmt (&body, gimple_build_label (ctx->cancel_label));

  gimple_seq_add_seq (&body, dlist);

  if (rclauses)
    {
      gimple_seq_add_seq (&tred_ilist, body);
      body = tred_ilist;
    }

  body = maybe_catch_exception (body);

  /* Region exit marker goes at the end of the loop body.  */
  gimple *g = gimple_build_omp_return (fd.have_nowait);
  gimple_seq_add_stmt (&body, g);

  gimple_seq_add_seq (&body, tred_dlist);

  maybe_add_implicit_barrier_cancel (ctx, g, &body);

  if (rclauses)
    OMP_CLAUSE_DECL (rclauses) = rtmp;

  /* Add OpenACC joining and reduction markers just after the loop.  */
  if (oacc_tail)
    gimple_seq_add_seq (&body, oacc_tail);

  pop_gimplify_context (new_stmt);

  gimple_bind_append_vars (new_stmt, ctx->block_vars);
  maybe_remove_omp_member_access_dummy_vars (new_stmt);
  BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
  if (BLOCK_VARS (block))
    TREE_USED (block) = 1;

  gimple_bind_set_body (new_stmt, body);
  gimple_omp_set_body (stmt, NULL);
  gimple_omp_for_set_pre_body (stmt, NULL);
}

/* Callback for walk_stmts.  Check if the current statement only contains
   GIMPLE_OMP_FOR or GIMPLE_OMP_SECTIONS.  */

static tree
check_combined_parallel (gimple_stmt_iterator *gsi_p,
    			 bool *handled_ops_p,
    			 struct walk_stmt_info *wi)
{
  int *info = (int *) wi->info;
  gimple *stmt = gsi_stmt (*gsi_p);

  *handled_ops_p = true;
  switch (gimple_code (stmt))
    {
    WALK_SUBSTMTS;

    case GIMPLE_DEBUG:
      break;
    case GIMPLE_OMP_FOR:
    case GIMPLE_OMP_SECTIONS:
      *info = *info == 0 ? 1 : -1;
      break;
    default:
      *info = -1;
      break;
    }
  return NULL;
}

struct omp_taskcopy_context
{
  /* This field must be at the beginning, as we do "inheritance": Some
     callback functions for tree-inline.c (e.g., omp_copy_decl)
     receive a copy_body_data pointer that is up-casted to an
     omp_context pointer.  */
  copy_body_data cb;
  omp_context *ctx;
};

static tree
task_copyfn_copy_decl (tree var, copy_body_data *cb)
{
  struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;

  if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
    return create_tmp_var (TREE_TYPE (var));

  return var;
}

static tree
task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
{
  tree name, new_fields = NULL, type, f;

  type = lang_hooks.types.make_type (RECORD_TYPE);
  name = DECL_NAME (TYPE_NAME (orig_type));
  name = build_decl (gimple_location (tcctx->ctx->stmt),
		     TYPE_DECL, name, type);
  TYPE_NAME (type) = name;

  for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
    {
      tree new_f = copy_node (f);
      DECL_CONTEXT (new_f) = type;
      TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
      TREE_CHAIN (new_f) = new_fields;
      walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
      walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
      walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
		 &tcctx->cb, NULL);
      new_fields = new_f;
      tcctx->cb.decl_map->put (f, new_f);
    }
  TYPE_FIELDS (type) = nreverse (new_fields);
  layout_type (type);
  return type;
}

/* Create task copyfn.  */

static void
create_task_copyfn (gomp_task *task_stmt, omp_context *ctx)
{
  struct function *child_cfun;
  tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
  tree record_type, srecord_type, bind, list;
  bool record_needs_remap = false, srecord_needs_remap = false;
  splay_tree_node n;
  struct omp_taskcopy_context tcctx;
  location_t loc = gimple_location (task_stmt);
  size_t looptempno = 0;

  child_fn = gimple_omp_task_copy_fn (task_stmt);
  child_cfun = DECL_STRUCT_FUNCTION (child_fn);
  gcc_assert (child_cfun->cfg == NULL);
  DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();

  /* Reset DECL_CONTEXT on function arguments.  */
  for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
    DECL_CONTEXT (t) = child_fn;

  /* Populate the function.  */
  push_gimplify_context ();
  push_cfun (child_cfun);

  bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
  TREE_SIDE_EFFECTS (bind) = 1;
  list = NULL;
  DECL_SAVED_TREE (child_fn) = bind;
  DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);

  /* Remap src and dst argument types if needed.  */
  record_type = ctx->record_type;
  srecord_type = ctx->srecord_type;
  for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
    if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
      {
	record_needs_remap = true;
	break;
      }
  for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
    if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
      {
	srecord_needs_remap = true;
	break;
      }

  if (record_needs_remap || srecord_needs_remap)
    {
      memset (&tcctx, '\0', sizeof (tcctx));
      tcctx.cb.src_fn = ctx->cb.src_fn;
      tcctx.cb.dst_fn = child_fn;
      tcctx.cb.src_node = cgraph_node::get (tcctx.cb.src_fn);
      gcc_checking_assert (tcctx.cb.src_node);
      tcctx.cb.dst_node = tcctx.cb.src_node;
      tcctx.cb.src_cfun = ctx->cb.src_cfun;
      tcctx.cb.copy_decl = task_copyfn_copy_decl;
      tcctx.cb.eh_lp_nr = 0;
      tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
      tcctx.cb.decl_map = new hash_map<tree, tree>;
      tcctx.ctx = ctx;

      if (record_needs_remap)
	record_type = task_copyfn_remap_type (&tcctx, record_type);
      if (srecord_needs_remap)
	srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
    }
  else
    tcctx.cb.decl_map = NULL;

  arg = DECL_ARGUMENTS (child_fn);
  TREE_TYPE (arg) = build_pointer_type (record_type);
  sarg = DECL_CHAIN (arg);
  TREE_TYPE (sarg) = build_pointer_type (srecord_type);

  /* First pass: initialize temporaries used in record_type and srecord_type
     sizes and field offsets.  */
  if (tcctx.cb.decl_map)
    for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
	{
	  tree *p;

	  decl = OMP_CLAUSE_DECL (c);
	  p = tcctx.cb.decl_map->get (decl);
	  if (p == NULL)
	    continue;
	  n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
	  sf = (tree) n->value;
	  sf = *tcctx.cb.decl_map->get (sf);
	  src = build_simple_mem_ref_loc (loc, sarg);
	  src = omp_build_component_ref (src, sf);
	  t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
	  append_to_statement_list (t, &list);
	}

  /* Second pass: copy shared var pointers and copy construct non-VLA
     firstprivate vars.  */
  for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
    switch (OMP_CLAUSE_CODE (c))
      {
	splay_tree_key key;
      case OMP_CLAUSE_SHARED:
	decl = OMP_CLAUSE_DECL (c);
	key = (splay_tree_key) decl;
	if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
	  key = (splay_tree_key) &DECL_UID (decl);
	n = splay_tree_lookup (ctx->field_map, key);
	if (n == NULL)
	  break;
	f = (tree) n->value;
	if (tcctx.cb.decl_map)
	  f = *tcctx.cb.decl_map->get (f);
	n = splay_tree_lookup (ctx->sfield_map, key);
	sf = (tree) n->value;
	if (tcctx.cb.decl_map)
	  sf = *tcctx.cb.decl_map->get (sf);
	src = build_simple_mem_ref_loc (loc, sarg);
	src = omp_build_component_ref (src, sf);
	dst = build_simple_mem_ref_loc (loc, arg);
	dst = omp_build_component_ref (dst, f);
	t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
	append_to_statement_list (t, &list);
	break;
      case OMP_CLAUSE_REDUCTION:
      case OMP_CLAUSE_IN_REDUCTION:
	decl = OMP_CLAUSE_DECL (c);
	if (TREE_CODE (decl) == MEM_REF)
	  {
	    decl = TREE_OPERAND (decl, 0);
	    if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
	      decl = TREE_OPERAND (decl, 0);
	    if (TREE_CODE (decl) == INDIRECT_REF
		|| TREE_CODE (decl) == ADDR_EXPR)
	      decl = TREE_OPERAND (decl, 0);
	  }
	key = (splay_tree_key) decl;
	n = splay_tree_lookup (ctx->field_map, key);
	if (n == NULL)
	  break;
	f = (tree) n->value;
	if (tcctx.cb.decl_map)
	  f = *tcctx.cb.decl_map->get (f);
	n = splay_tree_lookup (ctx->sfield_map, key);
	sf = (tree) n->value;
	if (tcctx.cb.decl_map)
	  sf = *tcctx.cb.decl_map->get (sf);
	src = build_simple_mem_ref_loc (loc, sarg);
	src = omp_build_component_ref (src, sf);
	if (decl != OMP_CLAUSE_DECL (c)
	    && TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
	    && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
	  src = build_simple_mem_ref_loc (loc, src);
	dst = build_simple_mem_ref_loc (loc, arg);
	dst = omp_build_component_ref (dst, f);
	t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
	append_to_statement_list (t, &list);
	break;
      case OMP_CLAUSE__LOOPTEMP_:
	/* Fields for first two _looptemp_ clauses are initialized by
	   GOMP_taskloop*, the rest are handled like firstprivate.  */
        if (looptempno < 2)
	  {
	    looptempno++;
	    break;
	  }
	/* FALLTHRU */
      case OMP_CLAUSE__REDUCTEMP_:
      case OMP_CLAUSE_FIRSTPRIVATE:
	decl = OMP_CLAUSE_DECL (c);
	if (is_variable_sized (decl))
	  break;
	n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
	if (n == NULL)
	  break;
	f = (tree) n->value;
	if (tcctx.cb.decl_map)
	  f = *tcctx.cb.decl_map->get (f);
	n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
	if (n != NULL)
	  {
	    sf = (tree) n->value;
	    if (tcctx.cb.decl_map)
	      sf = *tcctx.cb.decl_map->get (sf);
	    src = build_simple_mem_ref_loc (loc, sarg);
	    src = omp_build_component_ref (src, sf);
	    if (use_pointer_for_field (decl, NULL)
		|| omp_privatize_by_reference (decl))
	      src = build_simple_mem_ref_loc (loc, src);
	  }
	else
	  src = decl;
	dst = build_simple_mem_ref_loc (loc, arg);
	dst = omp_build_component_ref (dst, f);
	if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
	  t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
	else
	  {
	    if (ctx->allocate_map)
	      if (tree *allocatorp = ctx->allocate_map->get (decl))
		{
		  tree allocator = *allocatorp;
		  HOST_WIDE_INT ialign = 0;
		  if (TREE_CODE (allocator) == TREE_LIST)
		    {
		      ialign = tree_to_uhwi (TREE_VALUE (allocator));
		      allocator = TREE_PURPOSE (allocator);
		    }
		  if (TREE_CODE (allocator) != INTEGER_CST)
		    {
		      n = splay_tree_lookup (ctx->sfield_map,
					     (splay_tree_key) allocator);
		      allocator = (tree) n->value;
		      if (tcctx.cb.decl_map)
			allocator = *tcctx.cb.decl_map->get (allocator);
		      tree a = build_simple_mem_ref_loc (loc, sarg);
		      allocator = omp_build_component_ref (a, allocator);
		    }
		  allocator = fold_convert (pointer_sized_int_node, allocator);
		  tree a = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
		  tree align = build_int_cst (size_type_node,
					      MAX (ialign,
						   DECL_ALIGN_UNIT (decl)));
		  tree sz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (dst)));
		  tree ptr = build_call_expr_loc (loc, a, 3, align, sz,
						  allocator);
		  ptr = fold_convert (TREE_TYPE (dst), ptr);
		  t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, ptr);
		  append_to_statement_list (t, &list);
		  dst = build_simple_mem_ref_loc (loc, dst);
		}
	    t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
	  }
	append_to_statement_list (t, &list);
	break;
      case OMP_CLAUSE_PRIVATE:
	if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
	  break;
	decl = OMP_CLAUSE_DECL (c);
	n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
	f = (tree) n->value;
	if (tcctx.cb.decl_map)
	  f = *tcctx.cb.decl_map->get (f);
	n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
	if (n != NULL)
	  {
	    sf = (tree) n->value;
	    if (tcctx.cb.decl_map)
	      sf = *tcctx.cb.decl_map->get (sf);
	    src = build_simple_mem_ref_loc (loc, sarg);
	    src = omp_build_component_ref (src, sf);
	    if (use_pointer_for_field (decl, NULL))
	      src = build_simple_mem_ref_loc (loc, src);
	  }
	else
	  src = decl;
	dst = build_simple_mem_ref_loc (loc, arg);
	dst = omp_build_component_ref (dst, f);
	t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
	append_to_statement_list (t, &list);
	break;
      default:
	break;
      }

  /* Last pass: handle VLA firstprivates.  */
  if (tcctx.cb.decl_map)
    for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
	{
	  tree ind, ptr, df;

	  decl = OMP_CLAUSE_DECL (c);
	  if (!is_variable_sized (decl))
	    continue;
	  n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
	  if (n == NULL)
	    continue;
	  f = (tree) n->value;
	  f = *tcctx.cb.decl_map->get (f);
	  gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
	  ind = DECL_VALUE_EXPR (decl);
	  gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
	  gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
	  n = splay_tree_lookup (ctx->sfield_map,
				 (splay_tree_key) TREE_OPERAND (ind, 0));
	  sf = (tree) n->value;
	  sf = *tcctx.cb.decl_map->get (sf);
	  src = build_simple_mem_ref_loc (loc, sarg);
	  src = omp_build_component_ref (src, sf);
	  src = build_simple_mem_ref_loc (loc, src);
	  dst = build_simple_mem_ref_loc (loc, arg);
	  dst = omp_build_component_ref (dst, f);
	  t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
	  append_to_statement_list (t, &list);
	  n = splay_tree_lookup (ctx->field_map,
				 (splay_tree_key) TREE_OPERAND (ind, 0));
	  df = (tree) n->value;
	  df = *tcctx.cb.decl_map->get (df);
	  ptr = build_simple_mem_ref_loc (loc, arg);
	  ptr = omp_build_component_ref (ptr, df);
	  t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
		      build_fold_addr_expr_loc (loc, dst));
	  append_to_statement_list (t, &list);
	}

  t = build1 (RETURN_EXPR, void_type_node, NULL);
  append_to_statement_list (t, &list);

  if (tcctx.cb.decl_map)
    delete tcctx.cb.decl_map;
  pop_gimplify_context (NULL);
  BIND_EXPR_BODY (bind) = list;
  pop_cfun ();
}

static void
lower_depend_clauses (tree *pclauses, gimple_seq *iseq, gimple_seq *oseq)
{
  tree c, clauses;
  gimple *g;
  size_t cnt[4] = { 0, 0, 0, 0 }, idx = 2, i;

  clauses = omp_find_clause (*pclauses, OMP_CLAUSE_DEPEND);
  gcc_assert (clauses);
  for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
      switch (OMP_CLAUSE_DEPEND_KIND (c))
	{
	case OMP_CLAUSE_DEPEND_LAST:
	  /* Lowering already done at gimplification.  */
	  return;
	case OMP_CLAUSE_DEPEND_IN:
	  cnt[2]++;
	  break;
	case OMP_CLAUSE_DEPEND_OUT:
	case OMP_CLAUSE_DEPEND_INOUT:
	  cnt[0]++;
	  break;
	case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
	  cnt[1]++;
	  break;
	case OMP_CLAUSE_DEPEND_DEPOBJ:
	  cnt[3]++;
	  break;
	case OMP_CLAUSE_DEPEND_SOURCE:
	case OMP_CLAUSE_DEPEND_SINK:
	  /* FALLTHRU */
	default:
	  gcc_unreachable ();
	}
  if (cnt[1] || cnt[3])
    idx = 5;
  size_t total = cnt[0] + cnt[1] + cnt[2] + cnt[3];
  tree type = build_array_type_nelts (ptr_type_node, total + idx);
  tree array = create_tmp_var (type);
  TREE_ADDRESSABLE (array) = 1;
  tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
		   NULL_TREE);
  if (idx == 5)
    {
      g = gimple_build_assign (r, build_int_cst (ptr_type_node, 0));
      gimple_seq_add_stmt (iseq, g);
      r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
		  NULL_TREE);
    }
  g = gimple_build_assign (r, build_int_cst (ptr_type_node, total));
  gimple_seq_add_stmt (iseq, g);
  for (i = 0; i < (idx == 5 ? 3 : 1); i++)
    {
      r = build4 (ARRAY_REF, ptr_type_node, array,
		  size_int (i + 1 + (idx == 5)), NULL_TREE, NULL_TREE);
      g = gimple_build_assign (r, build_int_cst (ptr_type_node, cnt[i]));
      gimple_seq_add_stmt (iseq, g);
    }
  for (i = 0; i < 4; i++)
    {
      if (cnt[i] == 0)
	continue;
      for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
	if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
	  continue;
	else
	  {
	    switch (OMP_CLAUSE_DEPEND_KIND (c))
	      {
	      case OMP_CLAUSE_DEPEND_IN:
		if (i != 2)
		  continue;
		break;
	      case OMP_CLAUSE_DEPEND_OUT:
	      case OMP_CLAUSE_DEPEND_INOUT:
		if (i != 0)
		  continue;
		break;
	      case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
		if (i != 1)
		  continue;
		break;
	      case OMP_CLAUSE_DEPEND_DEPOBJ:
		if (i != 3)
		  continue;
		break;
	      default:
		gcc_unreachable ();
	      }
	    tree t = OMP_CLAUSE_DECL (c);
	    t = fold_convert (ptr_type_node, t);
	    gimplify_expr (&t, iseq, NULL, is_gimple_val, fb_rvalue);
	    r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
			NULL_TREE, NULL_TREE);
	    g = gimple_build_assign (r, t);
	    gimple_seq_add_stmt (iseq, g);
	  }
    }
  c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
  OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
  OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
  OMP_CLAUSE_CHAIN (c) = *pclauses;
  *pclauses = c;
  tree clobber = build_clobber (type);
  g = gimple_build_assign (array, clobber);
  gimple_seq_add_stmt (oseq, g);
}

/* Lower the OpenMP parallel or task directive in the current statement
   in GSI_P.  CTX holds context information for the directive.  */

static void
lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
  tree clauses;
  tree child_fn, t;
  gimple *stmt = gsi_stmt (*gsi_p);
  gbind *par_bind, *bind, *dep_bind = NULL;
  gimple_seq par_body;
  location_t loc = gimple_location (stmt);

  clauses = gimple_omp_taskreg_clauses (stmt);
  if (gimple_code (stmt) == GIMPLE_OMP_TASK
      && gimple_omp_task_taskwait_p (stmt))
    {
      par_bind = NULL;
      par_body = NULL;
    }
  else
    {
      par_bind
	= as_a <gbind *> (gimple_seq_first_stmt (gimple_omp_body (stmt)));
      par_body = gimple_bind_body (par_bind);
    }
  child_fn = ctx->cb.dst_fn;
  if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
      && !gimple_omp_parallel_combined_p (stmt))
    {
      struct walk_stmt_info wi;
      int ws_num = 0;

      memset (&wi, 0, sizeof (wi));
      wi.info = &ws_num;
      wi.val_only = true;
      walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
      if (ws_num == 1)
	gimple_omp_parallel_set_combined_p (stmt, true);
    }
  gimple_seq dep_ilist = NULL;
  gimple_seq dep_olist = NULL;
  if (gimple_code (stmt) == GIMPLE_OMP_TASK
      && omp_find_clause (clauses, OMP_CLAUSE_DEPEND))
    {
      push_gimplify_context ();
      dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
      lower_depend_clauses (gimple_omp_task_clauses_ptr (stmt),
			    &dep_ilist, &dep_olist);
    }

  if (gimple_code (stmt) == GIMPLE_OMP_TASK
      && gimple_omp_task_taskwait_p (stmt))
    {
      if (dep_bind)
	{
	  gsi_replace (gsi_p, dep_bind, true);
	  gimple_bind_add_seq (dep_bind, dep_ilist);
	  gimple_bind_add_stmt (dep_bind, stmt);
	  gimple_bind_add_seq (dep_bind, dep_olist);
	  pop_gimplify_context (dep_bind);
	}
      return;
    }

  if (ctx->srecord_type)
    create_task_copyfn (as_a <gomp_task *> (stmt), ctx);

  gimple_seq tskred_ilist = NULL;
  gimple_seq tskred_olist = NULL;
  if ((is_task_ctx (ctx)
       && gimple_omp_task_taskloop_p (ctx->stmt)
       && omp_find_clause (gimple_omp_task_clauses (ctx->stmt),
			   OMP_CLAUSE_REDUCTION))
      || (is_parallel_ctx (ctx)
	  && omp_find_clause (gimple_omp_parallel_clauses (stmt),
			      OMP_CLAUSE__REDUCTEMP_)))
    {
      if (dep_bind == NULL)
	{
	  push_gimplify_context ();
	  dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
	}
      lower_omp_task_reductions (ctx, is_task_ctx (ctx) ? OMP_TASKLOOP
							: OMP_PARALLEL,
				 gimple_omp_taskreg_clauses (ctx->stmt),
				 &tskred_ilist, &tskred_olist);
    }

  push_gimplify_context ();

  gimple_seq par_olist = NULL;
  gimple_seq par_ilist = NULL;
  gimple_seq par_rlist = NULL;
  lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx, NULL);
  lower_omp (&par_body, ctx);
  if (gimple_code (stmt) != GIMPLE_OMP_TASK)
    lower_reduction_clauses (clauses, &par_rlist, NULL, ctx);

  /* Declare all the variables created by mapping and the variables
     declared in the scope of the parallel body.  */
  record_vars_into (ctx->block_vars, child_fn);
  maybe_remove_omp_member_access_dummy_vars (par_bind);
  record_vars_into (gimple_bind_vars (par_bind), child_fn);

  if (ctx->record_type)
    {
      ctx->sender_decl
	= create_tmp_var (ctx->srecord_type ? ctx->srecord_type
			  : ctx->record_type, ".omp_data_o");
      DECL_NAMELESS (ctx->sender_decl) = 1;
      TREE_ADDRESSABLE (ctx->sender_decl) = 1;
      gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
    }

  gimple_seq olist = NULL;
  gimple_seq ilist = NULL;
  lower_send_clauses (clauses, &ilist, &olist, ctx);
  lower_send_shared_vars (&ilist, &olist, ctx);

  if (ctx->record_type)
    {
      tree clobber = build_clobber (TREE_TYPE (ctx->sender_decl));
      gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
							clobber));
    }

  /* Once all the expansions are done, sequence all the different
     fragments inside gimple_omp_body.  */

  gimple_seq new_body = NULL;

  if (ctx->record_type)
    {
      t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
      /* fixup_child_record_type might have changed receiver_decl's type.  */
      t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
      gimple_seq_add_stmt (&new_body,
	  		   gimple_build_assign (ctx->receiver_decl, t));
    }

  gimple_seq_add_seq (&new_body, par_ilist);
  gimple_seq_add_seq (&new_body, par_body);
  gimple_seq_add_seq (&new_body, par_rlist);
  if (ctx->cancellable)
    gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
  gimple_seq_add_seq (&new_body, par_olist);
  new_body = maybe_catch_exception (new_body);
  if (gimple_code (stmt) == GIMPLE_OMP_TASK)
    gimple_seq_add_stmt (&new_body,
			 gimple_build_omp_continue (integer_zero_node,
						    integer_zero_node));
  gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
  gimple_omp_set_body (stmt, new_body);

  if (dep_bind && gimple_bind_block (par_bind) == NULL_TREE)
    bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
  else
    bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
  gsi_replace (gsi_p, dep_bind ? dep_bind : bind, true);
  gimple_bind_add_seq (bind, ilist);
  gimple_bind_add_stmt (bind, stmt);
  gimple_bind_add_seq (bind, olist);

  pop_gimplify_context (NULL);

  if (dep_bind)
    {
      gimple_bind_add_seq (dep_bind, dep_ilist);
      gimple_bind_add_seq (dep_bind, tskred_ilist);
      gimple_bind_add_stmt (dep_bind, bind);
      gimple_bind_add_seq (dep_bind, tskred_olist);
      gimple_bind_add_seq (dep_bind, dep_olist);
      pop_gimplify_context (dep_bind);
    }
}

/* Lower the GIMPLE_OMP_TARGET in the current statement
   in GSI_P.  CTX holds context information for the directive.  */

static void
lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
  tree clauses;
  tree child_fn, t, c;
  gomp_target *stmt = as_a <gomp_target *> (gsi_stmt (*gsi_p));
  gbind *tgt_bind, *bind, *dep_bind = NULL;
  gimple_seq tgt_body, olist, ilist, fplist, new_body;
  location_t loc = gimple_location (stmt);
  bool offloaded, data_region;
  unsigned int map_cnt = 0;
  tree in_reduction_clauses = NULL_TREE;

  offloaded = is_gimple_omp_offloaded (stmt);
  switch (gimple_omp_target_kind (stmt))
    {
    case GF_OMP_TARGET_KIND_REGION:
      tree *p, *q;
      q = &in_reduction_clauses;
      for (p = gimple_omp_target_clauses_ptr (stmt); *p; )
	if (OMP_CLAUSE_CODE (*p) == OMP_CLAUSE_IN_REDUCTION)
	  {
	    *q = *p;
	    q = &OMP_CLAUSE_CHAIN (*q);
	    *p = OMP_CLAUSE_CHAIN (*p);
	  }
	else
	  p = &OMP_CLAUSE_CHAIN (*p);
      *q = NULL_TREE;
      *p = in_reduction_clauses;
      /* FALLTHRU */
    case GF_OMP_TARGET_KIND_UPDATE:
    case GF_OMP_TARGET_KIND_ENTER_DATA:
    case GF_OMP_TARGET_KIND_EXIT_DATA:
    case GF_OMP_TARGET_KIND_OACC_PARALLEL:
    case GF_OMP_TARGET_KIND_OACC_KERNELS:
    case GF_OMP_TARGET_KIND_OACC_SERIAL:
    case GF_OMP_TARGET_KIND_OACC_UPDATE:
    case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
    case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
    case GF_OMP_TARGET_KIND_OACC_DECLARE:
    case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
    case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
      data_region = false;
      break;
    case GF_OMP_TARGET_KIND_DATA:
    case GF_OMP_TARGET_KIND_OACC_DATA:
    case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
    case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
      data_region = true;
      break;
    default:
      gcc_unreachable ();
    }

  clauses = gimple_omp_target_clauses (stmt);

  gimple_seq dep_ilist = NULL;
  gimple_seq dep_olist = NULL;
  bool has_depend = omp_find_clause (clauses, OMP_CLAUSE_DEPEND) != NULL_TREE;
  if (has_depend || in_reduction_clauses)
    {
      push_gimplify_context ();
      dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
      if (has_depend)
	lower_depend_clauses (gimple_omp_target_clauses_ptr (stmt),
			      &dep_ilist, &dep_olist);
      if (in_reduction_clauses)
	lower_rec_input_clauses (in_reduction_clauses, &dep_ilist, &dep_olist,
				 ctx, NULL);
    }

  tgt_bind = NULL;
  tgt_body = NULL;
  if (offloaded)
    {
      tgt_bind = gimple_seq_first_stmt_as_a_bind (gimple_omp_body (stmt));
      tgt_body = gimple_bind_body (tgt_bind);
    }
  else if (data_region)
    tgt_body = gimple_omp_body (stmt);
  child_fn = ctx->cb.dst_fn;

  push_gimplify_context ();
  fplist = NULL;

  for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    switch (OMP_CLAUSE_CODE (c))
      {
	tree var, x;

      default:
	break;
      case OMP_CLAUSE_MAP:
#if CHECKING_P
	/* First check what we're prepared to handle in the following.  */
	switch (OMP_CLAUSE_MAP_KIND (c))
	  {
	  case GOMP_MAP_ALLOC:
	  case GOMP_MAP_TO:
	  case GOMP_MAP_FROM:
	  case GOMP_MAP_TOFROM:
	  case GOMP_MAP_POINTER:
	  case GOMP_MAP_TO_PSET:
	  case GOMP_MAP_DELETE:
	  case GOMP_MAP_RELEASE:
	  case GOMP_MAP_ALWAYS_TO:
	  case GOMP_MAP_ALWAYS_FROM:
	  case GOMP_MAP_ALWAYS_TOFROM:
	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
	  case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
	  case GOMP_MAP_STRUCT:
	  case GOMP_MAP_ALWAYS_POINTER:
	  case GOMP_MAP_ATTACH:
	  case GOMP_MAP_DETACH:
	    break;
	  case GOMP_MAP_IF_PRESENT:
	  case GOMP_MAP_FORCE_ALLOC:
	  case GOMP_MAP_FORCE_TO:
	  case GOMP_MAP_FORCE_FROM:
	  case GOMP_MAP_FORCE_TOFROM:
	  case GOMP_MAP_FORCE_PRESENT:
	  case GOMP_MAP_FORCE_DEVICEPTR:
	  case GOMP_MAP_DEVICE_RESIDENT:
	  case GOMP_MAP_LINK:
	  case GOMP_MAP_FORCE_DETACH:
	    gcc_assert (is_gimple_omp_oacc (stmt));
	    break;
	  default:
	    gcc_unreachable ();
	  }
#endif
	  /* FALLTHRU */
      case OMP_CLAUSE_TO:
      case OMP_CLAUSE_FROM:
      oacc_firstprivate:
	var = OMP_CLAUSE_DECL (c);
	if (!DECL_P (var))
	  {
	    if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
		|| (!OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
		    && (OMP_CLAUSE_MAP_KIND (c)
			!= GOMP_MAP_FIRSTPRIVATE_POINTER)))
	      map_cnt++;
	    continue;
	  }

	if (DECL_SIZE (var)
	    && TREE_CODE (DECL_SIZE (var)) != INTEGER_CST)
	  {
	    tree var2 = DECL_VALUE_EXPR (var);
	    gcc_assert (TREE_CODE (var2) == INDIRECT_REF);
	    var2 = TREE_OPERAND (var2, 0);
	    gcc_assert (DECL_P (var2));
	    var = var2;
	  }

	if (offloaded
	    && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
	    && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
		|| OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
	  {
	    if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
	      {
		if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx))
		    && varpool_node::get_create (var)->offloadable)
		  continue;

		tree type = build_pointer_type (TREE_TYPE (var));
		tree new_var = lookup_decl (var, ctx);
		x = create_tmp_var_raw (type, get_name (new_var));
		gimple_add_tmp_var (x);
		x = build_simple_mem_ref (x);
		SET_DECL_VALUE_EXPR (new_var, x);
		DECL_HAS_VALUE_EXPR_P (new_var) = 1;
	      }
	    continue;
	  }

	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
	    && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
		|| OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
	    && is_omp_target (stmt))
	  {
	    gcc_assert (maybe_lookup_field (c, ctx));
	    map_cnt++;
	    continue;
	  }

	if (!maybe_lookup_field (var, ctx))
	  continue;

	/* Don't remap compute constructs' reduction variables, because the
	   intermediate result must be local to each gang.  */
	if (offloaded && !(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
			   && is_gimple_omp_oacc (ctx->stmt)
			   && OMP_CLAUSE_MAP_IN_REDUCTION (c)))
	  {
	    x = build_receiver_ref (var, true, ctx);
	    tree new_var = lookup_decl (var, ctx);

	    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
		&& OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
		&& !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
		&& TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
	      x = build_simple_mem_ref (x);
	    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
	      {
		gcc_assert (is_gimple_omp_oacc (ctx->stmt));
		if (omp_privatize_by_reference (new_var)
		    && (TREE_CODE (TREE_TYPE (new_var)) != POINTER_TYPE
		        || DECL_BY_REFERENCE (var)))
		  {
		    /* Create a local object to hold the instance
		       value.  */
		    tree type = TREE_TYPE (TREE_TYPE (new_var));
		    const char *id = IDENTIFIER_POINTER (DECL_NAME (new_var));
		    tree inst = create_tmp_var (type, id);
		    gimplify_assign (inst, fold_indirect_ref (x), &fplist);
		    x = build_fold_addr_expr (inst);
		  }
		gimplify_assign (new_var, x, &fplist);
	      }
	    else if (DECL_P (new_var))
	      {
		SET_DECL_VALUE_EXPR (new_var, x);
		DECL_HAS_VALUE_EXPR_P (new_var) = 1;
	      }
	    else
	      gcc_unreachable ();
	  }
	map_cnt++;
	break;

      case OMP_CLAUSE_FIRSTPRIVATE:
	gcc_checking_assert (offloaded);
	if (is_gimple_omp_oacc (ctx->stmt))
	  {
	    /* No 'firstprivate' clauses on OpenACC 'kernels'.  */
	    gcc_checking_assert (!is_oacc_kernels (ctx));
	    /* Likewise, on OpenACC 'kernels' decomposed parts.  */
	    gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));

	    goto oacc_firstprivate;
	  }
	map_cnt++;
	var = OMP_CLAUSE_DECL (c);
	if (!omp_privatize_by_reference (var)
	    && !is_gimple_reg_type (TREE_TYPE (var)))
	  {
	    tree new_var = lookup_decl (var, ctx);
	    if (is_variable_sized (var))
	      {
		tree pvar = DECL_VALUE_EXPR (var);
		gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
		pvar = TREE_OPERAND (pvar, 0);
		gcc_assert (DECL_P (pvar));
		tree new_pvar = lookup_decl (pvar, ctx);
		x = build_fold_indirect_ref (new_pvar);
		TREE_THIS_NOTRAP (x) = 1;
	      }
	    else
	      x = build_receiver_ref (var, true, ctx);
	    SET_DECL_VALUE_EXPR (new_var, x);
	    DECL_HAS_VALUE_EXPR_P (new_var) = 1;
	  }
	break;

      case OMP_CLAUSE_PRIVATE:
	gcc_checking_assert (offloaded);
	if (is_gimple_omp_oacc (ctx->stmt))
	  {
	    /* No 'private' clauses on OpenACC 'kernels'.  */
	    gcc_checking_assert (!is_oacc_kernels (ctx));
	    /* Likewise, on OpenACC 'kernels' decomposed parts.  */
	    gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));

	    break;
	  }
	var = OMP_CLAUSE_DECL (c);
	if (is_variable_sized (var))
	  {
	    tree new_var = lookup_decl (var, ctx);
	    tree pvar = DECL_VALUE_EXPR (var);
	    gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
	    pvar = TREE_OPERAND (pvar, 0);
	    gcc_assert (DECL_P (pvar));
	    tree new_pvar = lookup_decl (pvar, ctx);
	    x = build_fold_indirect_ref (new_pvar);
	    TREE_THIS_NOTRAP (x) = 1;
	    SET_DECL_VALUE_EXPR (new_var, x);
	    DECL_HAS_VALUE_EXPR_P (new_var) = 1;
	  }
	break;

      case OMP_CLAUSE_USE_DEVICE_PTR:
      case OMP_CLAUSE_USE_DEVICE_ADDR:
      case OMP_CLAUSE_IS_DEVICE_PTR:
	var = OMP_CLAUSE_DECL (c);
	map_cnt++;
	if (is_variable_sized (var))
	  {
	    tree new_var = lookup_decl (var, ctx);
	    tree pvar = DECL_VALUE_EXPR (var);
	    gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
	    pvar = TREE_OPERAND (pvar, 0);
	    gcc_assert (DECL_P (pvar));
	    tree new_pvar = lookup_decl (pvar, ctx);
	    x = build_fold_indirect_ref (new_pvar);
	    TREE_THIS_NOTRAP (x) = 1;
	    SET_DECL_VALUE_EXPR (new_var, x);
	    DECL_HAS_VALUE_EXPR_P (new_var) = 1;
	  }
	else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
		  && !omp_privatize_by_reference (var)
		  && !omp_is_allocatable_or_ptr (var)
		  && !lang_hooks.decls.omp_array_data (var, true))
		 || TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
	  {
	    tree new_var = lookup_decl (var, ctx);
	    tree type = build_pointer_type (TREE_TYPE (var));
	    x = create_tmp_var_raw (type, get_name (new_var));
	    gimple_add_tmp_var (x);
	    x = build_simple_mem_ref (x);
	    SET_DECL_VALUE_EXPR (new_var, x);
	    DECL_HAS_VALUE_EXPR_P (new_var) = 1;
	  }
	else
	  {
	    tree new_var = lookup_decl (var, ctx);
	    x = create_tmp_var_raw (TREE_TYPE (new_var), get_name (new_var));
	    gimple_add_tmp_var (x);
	    SET_DECL_VALUE_EXPR (new_var, x);
	    DECL_HAS_VALUE_EXPR_P (new_var) = 1;
	  }
	break;
      }

  if (offloaded)
    {
      target_nesting_level++;
      lower_omp (&tgt_body, ctx);
      target_nesting_level--;
    }
  else if (data_region)
    lower_omp (&tgt_body, ctx);

  if (offloaded)
    {
      /* Declare all the variables created by mapping and the variables
	 declared in the scope of the target body.  */
      record_vars_into (ctx->block_vars, child_fn);
      maybe_remove_omp_member_access_dummy_vars (tgt_bind);
      record_vars_into (gimple_bind_vars (tgt_bind), child_fn);
    }

  olist = NULL;
  ilist = NULL;
  if (ctx->record_type)
    {
      ctx->sender_decl
	= create_tmp_var (ctx->record_type, ".omp_data_arr");
      DECL_NAMELESS (ctx->sender_decl) = 1;
      TREE_ADDRESSABLE (ctx->sender_decl) = 1;
      t = make_tree_vec (3);
      TREE_VEC_ELT (t, 0) = ctx->sender_decl;
      TREE_VEC_ELT (t, 1)
	= create_tmp_var (build_array_type_nelts (size_type_node, map_cnt),
			  ".omp_data_sizes");
      DECL_NAMELESS (TREE_VEC_ELT (t, 1)) = 1;
      TREE_ADDRESSABLE (TREE_VEC_ELT (t, 1)) = 1;
      TREE_STATIC (TREE_VEC_ELT (t, 1)) = 1;
      tree tkind_type = short_unsigned_type_node;
      int talign_shift = 8;
      TREE_VEC_ELT (t, 2)
	= create_tmp_var (build_array_type_nelts (tkind_type, map_cnt),
			  ".omp_data_kinds");
      DECL_NAMELESS (TREE_VEC_ELT (t, 2)) = 1;
      TREE_ADDRESSABLE (TREE_VEC_ELT (t, 2)) = 1;
      TREE_STATIC (TREE_VEC_ELT (t, 2)) = 1;
      gimple_omp_target_set_data_arg (stmt, t);

      vec<constructor_elt, va_gc> *vsize;
      vec<constructor_elt, va_gc> *vkind;
      vec_alloc (vsize, map_cnt);
      vec_alloc (vkind, map_cnt);
      unsigned int map_idx = 0;

      for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
	switch (OMP_CLAUSE_CODE (c))
	  {
	    tree ovar, nc, s, purpose, var, x, type;
	    unsigned int talign;

	  default:
	    break;

	  case OMP_CLAUSE_MAP:
	  case OMP_CLAUSE_TO:
	  case OMP_CLAUSE_FROM:
	  oacc_firstprivate_map:
	    nc = c;
	    ovar = OMP_CLAUSE_DECL (c);
	    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
		&& (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
		    || (OMP_CLAUSE_MAP_KIND (c)
			== GOMP_MAP_FIRSTPRIVATE_REFERENCE)))
	      break;
	    if (!DECL_P (ovar))
	      {
		if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
		    && OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
		  {
		    nc = OMP_CLAUSE_CHAIN (c);
		    gcc_checking_assert (OMP_CLAUSE_DECL (nc)
					 == get_base_address (ovar));
		    ovar = OMP_CLAUSE_DECL (nc);
		  }
		else
		  {
		    tree x = build_sender_ref (ovar, ctx);
		    tree v = ovar;
		    if (in_reduction_clauses
			&& OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
			&& OMP_CLAUSE_MAP_IN_REDUCTION (c))
		      {
			v = unshare_expr (v);
			tree *p = &v;
			while (handled_component_p (*p)
			       || TREE_CODE (*p) == INDIRECT_REF
			       || TREE_CODE (*p) == ADDR_EXPR
			       || TREE_CODE (*p) == MEM_REF
			       || TREE_CODE (*p) == NON_LVALUE_EXPR)
			  p = &TREE_OPERAND (*p, 0);
			tree d = *p;
			if (is_variable_sized (d))
			  {
			    gcc_assert (DECL_HAS_VALUE_EXPR_P (d));
			    d = DECL_VALUE_EXPR (d);
			    gcc_assert (TREE_CODE (d) == INDIRECT_REF);
			    d = TREE_OPERAND (d, 0);
			    gcc_assert (DECL_P (d));
			  }
			splay_tree_key key
			  = (splay_tree_key) &DECL_CONTEXT (d);
			tree nd = (tree) splay_tree_lookup (ctx->field_map,
							    key)->value;
			if (d == *p)
			  *p = nd;
			else
			  *p = build_fold_indirect_ref (nd);
		      }
		    v = build_fold_addr_expr_with_type (v, ptr_type_node);
		    gimplify_assign (x, v, &ilist);
		    nc = NULL_TREE;
		  }
	      }
	    else
	      {
		if (DECL_SIZE (ovar)
		    && TREE_CODE (DECL_SIZE (ovar)) != INTEGER_CST)
		  {
		    tree ovar2 = DECL_VALUE_EXPR (ovar);
		    gcc_assert (TREE_CODE (ovar2) == INDIRECT_REF);
		    ovar2 = TREE_OPERAND (ovar2, 0);
		    gcc_assert (DECL_P (ovar2));
		    ovar = ovar2;
		  }
		if (!maybe_lookup_field (ovar, ctx)
		    && !(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
			 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
			     || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)))
		  continue;
	      }

	    talign = TYPE_ALIGN_UNIT (TREE_TYPE (ovar));
	    if (DECL_P (ovar) && DECL_ALIGN_UNIT (ovar) > talign)
	      talign = DECL_ALIGN_UNIT (ovar);

	    var = NULL_TREE;
	    if (nc)
	      {
		if (in_reduction_clauses
		    && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
		    && OMP_CLAUSE_MAP_IN_REDUCTION (c))
		  {
		    tree d = ovar;
		    if (is_variable_sized (d))
		      {
			gcc_assert (DECL_HAS_VALUE_EXPR_P (d));
			d = DECL_VALUE_EXPR (d);
			gcc_assert (TREE_CODE (d) == INDIRECT_REF);
			d = TREE_OPERAND (d, 0);
			gcc_assert (DECL_P (d));
		      }
		    splay_tree_key key
		      = (splay_tree_key) &DECL_CONTEXT (d);
		    tree nd = (tree) splay_tree_lookup (ctx->field_map,
							key)->value;
		    if (d == ovar)
		      var = nd;
		    else
		      var = build_fold_indirect_ref (nd);
		  }
		else
		  var = lookup_decl_in_outer_ctx (ovar, ctx);
	      }
	    if (nc
		&& OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
		&& (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
		    || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
		&& is_omp_target (stmt))
	      {
		x = build_sender_ref (c, ctx);
		gimplify_assign (x, build_fold_addr_expr (var), &ilist);
	      }
	    else if (nc)
	      {
		x = build_sender_ref (ovar, ctx);

		if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
		    && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
		    && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
		    && TREE_CODE (TREE_TYPE (ovar)) == ARRAY_TYPE)
		  {
		    gcc_assert (offloaded);
		    tree avar
		      = create_tmp_var (TREE_TYPE (TREE_TYPE (x)));
		    mark_addressable (avar);
		    gimplify_assign (avar, build_fold_addr_expr (var), &ilist);
		    talign = DECL_ALIGN_UNIT (avar);
		    avar = build_fold_addr_expr (avar);
		    gimplify_assign (x, avar, &ilist);
		  }
		else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
		  {
		    gcc_assert (is_gimple_omp_oacc (ctx->stmt));
		    if (!omp_privatize_by_reference (var))
		      {
			if (is_gimple_reg (var)
			    && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
			  suppress_warning (var);
			var = build_fold_addr_expr (var);
		      }
		    else
		      talign = TYPE_ALIGN_UNIT (TREE_TYPE (TREE_TYPE (ovar)));
		    gimplify_assign (x, var, &ilist);
		  }
		else if (is_gimple_reg (var))
		  {
		    gcc_assert (offloaded);
		    tree avar = create_tmp_var (TREE_TYPE (var));
		    mark_addressable (avar);
		    enum gomp_map_kind map_kind = OMP_CLAUSE_MAP_KIND (c);
		    if (GOMP_MAP_COPY_TO_P (map_kind)
			|| map_kind == GOMP_MAP_POINTER
			|| map_kind == GOMP_MAP_TO_PSET
			|| map_kind == GOMP_MAP_FORCE_DEVICEPTR)
		      {
			/* If we need to initialize a temporary
			   with VAR because it is not addressable, and
			   the variable hasn't been initialized yet, then
			   we'll get a warning for the store to avar.
			   Don't warn in that case, the mapping might
			   be implicit.  */
			suppress_warning (var, OPT_Wuninitialized);
			gimplify_assign (avar, var, &ilist);
		      }
		    avar = build_fold_addr_expr (avar);
		    gimplify_assign (x, avar, &ilist);
		    if ((GOMP_MAP_COPY_FROM_P (map_kind)
			 || map_kind == GOMP_MAP_FORCE_DEVICEPTR)
			&& !TYPE_READONLY (TREE_TYPE (var)))
		      {
			x = unshare_expr (x);
			x = build_simple_mem_ref (x);
			gimplify_assign (var, x, &olist);
		      }
		  }
		else
		  {
		    /* While MAP is handled explicitly by the FE,
		       for 'target update', only the identified is passed.  */
		    if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM
			 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO)
			&& (omp_is_allocatable_or_ptr (var)
			    && omp_check_optional_argument (var, false)))
		      var = build_fold_indirect_ref (var);
		    else if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FROM
			      && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TO)
			     || (!omp_is_allocatable_or_ptr (var)
				 && !omp_check_optional_argument (var, false)))
		      var = build_fold_addr_expr (var);
		    gimplify_assign (x, var, &ilist);
		  }
	      }
	    s = NULL_TREE;
	    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
	      {
		gcc_checking_assert (is_gimple_omp_oacc (ctx->stmt));
		s = TREE_TYPE (ovar);
		if (TREE_CODE (s) == REFERENCE_TYPE
		    || omp_check_optional_argument (ovar, false))
		  s = TREE_TYPE (s);
		s = TYPE_SIZE_UNIT (s);
	      }
	    else
	      s = OMP_CLAUSE_SIZE (c);
	    if (s == NULL_TREE)
	      s = TYPE_SIZE_UNIT (TREE_TYPE (ovar));
	    s = fold_convert (size_type_node, s);
	    purpose = size_int (map_idx++);
	    CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
	    if (TREE_CODE (s) != INTEGER_CST)
	      TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;

	    unsigned HOST_WIDE_INT tkind, tkind_zero;
	    switch (OMP_CLAUSE_CODE (c))
	      {
	      case OMP_CLAUSE_MAP:
		tkind = OMP_CLAUSE_MAP_KIND (c);
		tkind_zero = tkind;
		if (OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c))
		  switch (tkind)
		    {
		    case GOMP_MAP_ALLOC:
		    case GOMP_MAP_IF_PRESENT:
		    case GOMP_MAP_TO:
		    case GOMP_MAP_FROM:
		    case GOMP_MAP_TOFROM:
		    case GOMP_MAP_ALWAYS_TO:
		    case GOMP_MAP_ALWAYS_FROM:
		    case GOMP_MAP_ALWAYS_TOFROM:
		    case GOMP_MAP_RELEASE:
		    case GOMP_MAP_FORCE_TO:
		    case GOMP_MAP_FORCE_FROM:
		    case GOMP_MAP_FORCE_TOFROM:
		    case GOMP_MAP_FORCE_PRESENT:
		      tkind_zero = GOMP_MAP_ZERO_LEN_ARRAY_SECTION;
		      break;
		    case GOMP_MAP_DELETE:
		      tkind_zero = GOMP_MAP_DELETE_ZERO_LEN_ARRAY_SECTION;
		    default:
		      break;
		    }
		if (tkind_zero != tkind)
		  {
		    if (integer_zerop (s))
		      tkind = tkind_zero;
		    else if (integer_nonzerop (s))
		      tkind_zero = tkind;
		  }
		break;
	      case OMP_CLAUSE_FIRSTPRIVATE:
		gcc_checking_assert (is_gimple_omp_oacc (ctx->stmt));
		tkind = GOMP_MAP_TO;
		tkind_zero = tkind;
		break;
	      case OMP_CLAUSE_TO:
		tkind = GOMP_MAP_TO;
		tkind_zero = tkind;
		break;
	      case OMP_CLAUSE_FROM:
		tkind = GOMP_MAP_FROM;
		tkind_zero = tkind;
		break;
	      default:
		gcc_unreachable ();
	      }
	    gcc_checking_assert (tkind
				 < (HOST_WIDE_INT_C (1U) << talign_shift));
	    gcc_checking_assert (tkind_zero
				 < (HOST_WIDE_INT_C (1U) << talign_shift));
	    talign = ceil_log2 (talign);
	    tkind |= talign << talign_shift;
	    tkind_zero |= talign << talign_shift;
	    gcc_checking_assert (tkind
				 <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
	    gcc_checking_assert (tkind_zero
				 <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
	    if (tkind == tkind_zero)
	      x = build_int_cstu (tkind_type, tkind);
	    else
	      {
		TREE_STATIC (TREE_VEC_ELT (t, 2)) = 0;
		x = build3 (COND_EXPR, tkind_type,
			    fold_build2 (EQ_EXPR, boolean_type_node,
					 unshare_expr (s), size_zero_node),
			    build_int_cstu (tkind_type, tkind_zero),
			    build_int_cstu (tkind_type, tkind));
	      }
	    CONSTRUCTOR_APPEND_ELT (vkind, purpose, x);
	    if (nc && nc != c)
	      c = nc;
	    break;

	  case OMP_CLAUSE_FIRSTPRIVATE:
	    if (is_gimple_omp_oacc (ctx->stmt))
	      goto oacc_firstprivate_map;
	    ovar = OMP_CLAUSE_DECL (c);
	    if (omp_privatize_by_reference (ovar))
	      talign = TYPE_ALIGN_UNIT (TREE_TYPE (TREE_TYPE (ovar)));
	    else
	      talign = DECL_ALIGN_UNIT (ovar);
	    var = lookup_decl_in_outer_ctx (ovar, ctx);
	    x = build_sender_ref (ovar, ctx);
	    tkind = GOMP_MAP_FIRSTPRIVATE;
	    type = TREE_TYPE (ovar);
	    if (omp_privatize_by_reference (ovar))
	      type = TREE_TYPE (type);
	    if ((INTEGRAL_TYPE_P (type)
		 && TYPE_PRECISION (type) <= POINTER_SIZE)
		|| TREE_CODE (type) == POINTER_TYPE)
	      {
		tkind = GOMP_MAP_FIRSTPRIVATE_INT;
		tree t = var;
		if (omp_privatize_by_reference (var))
		  t = build_simple_mem_ref (var);
		else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
		  suppress_warning (var);
		if (TREE_CODE (type) != POINTER_TYPE)
		  t = fold_convert (pointer_sized_int_node, t);
		t = fold_convert (TREE_TYPE (x), t);
		gimplify_assign (x, t, &ilist);
	      }
	    else if (omp_privatize_by_reference (var))
	      gimplify_assign (x, var, &ilist);
	    else if (is_gimple_reg (var))
	      {
		tree avar = create_tmp_var (TREE_TYPE (var));
		mark_addressable (avar);
		if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
		  suppress_warning (var);
		gimplify_assign (avar, var, &ilist);
		avar = build_fold_addr_expr (avar);
		gimplify_assign (x, avar, &ilist);
	      }
	    else
	      {
		var = build_fold_addr_expr (var);
		gimplify_assign (x, var, &ilist);
	      }
	    if (tkind == GOMP_MAP_FIRSTPRIVATE_INT)
	      s = size_int (0);
	    else if (omp_privatize_by_reference (ovar))
	      s = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ovar)));
	    else
	      s = TYPE_SIZE_UNIT (TREE_TYPE (ovar));
	    s = fold_convert (size_type_node, s);
	    purpose = size_int (map_idx++);
	    CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
	    if (TREE_CODE (s) != INTEGER_CST)
	      TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;

	    gcc_checking_assert (tkind
				 < (HOST_WIDE_INT_C (1U) << talign_shift));
	    talign = ceil_log2 (talign);
	    tkind |= talign << talign_shift;
	    gcc_checking_assert (tkind
				 <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
	    CONSTRUCTOR_APPEND_ELT (vkind, purpose,
				    build_int_cstu (tkind_type, tkind));
	    break;

	  case OMP_CLAUSE_USE_DEVICE_PTR:
	  case OMP_CLAUSE_USE_DEVICE_ADDR:
	  case OMP_CLAUSE_IS_DEVICE_PTR:
	    ovar = OMP_CLAUSE_DECL (c);
	    var = lookup_decl_in_outer_ctx (ovar, ctx);

	    if (lang_hooks.decls.omp_array_data (ovar, true))
	      {
		tkind = (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IS_DEVICE_PTR
			 ? GOMP_MAP_USE_DEVICE_PTR : GOMP_MAP_FIRSTPRIVATE_INT);
		x = build_sender_ref ((splay_tree_key) &DECL_NAME (ovar), ctx);
	      }
	    else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IS_DEVICE_PTR)
	      {
		tkind = GOMP_MAP_USE_DEVICE_PTR;
		x = build_sender_ref ((splay_tree_key) &DECL_UID (ovar), ctx);
	      }
	    else
	      {
		tkind = GOMP_MAP_FIRSTPRIVATE_INT;
		x = build_sender_ref (ovar, ctx);
	      }

	    if (is_gimple_omp_oacc (ctx->stmt))
	      {
		gcc_assert (tkind == GOMP_MAP_USE_DEVICE_PTR);

		if (OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c))
		  tkind = GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT;
	      }

	    type = TREE_TYPE (ovar);
	    if (lang_hooks.decls.omp_array_data (ovar, true))
	      var = lang_hooks.decls.omp_array_data (ovar, false);
	    else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
		      && !omp_privatize_by_reference (ovar)
		      && !omp_is_allocatable_or_ptr (ovar))
		     || TREE_CODE (type) == ARRAY_TYPE)
	      var = build_fold_addr_expr (var);
	    else
	      {
		if (omp_privatize_by_reference (ovar)
		    || omp_check_optional_argument (ovar, false)
		    || omp_is_allocatable_or_ptr (ovar))
		  {
		    type = TREE_TYPE (type);
		    if (POINTER_TYPE_P (type)
			&& TREE_CODE (type) != ARRAY_TYPE
			&& ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_USE_DEVICE_ADDR
			    && !omp_is_allocatable_or_ptr (ovar))
			   || (omp_privatize_by_reference (ovar)
			       && omp_is_allocatable_or_ptr (ovar))))
		      var = build_simple_mem_ref (var);
		    var = fold_convert (TREE_TYPE (x), var);
		  }
	      }
	    tree present;
	    present = omp_check_optional_argument (ovar, true);
	    if (present)
	      {
		tree null_label = create_artificial_label (UNKNOWN_LOCATION);
		tree notnull_label = create_artificial_label (UNKNOWN_LOCATION);
		tree opt_arg_label = create_artificial_label (UNKNOWN_LOCATION);
		tree new_x = unshare_expr (x);
		gimplify_expr (&present, &ilist, NULL, is_gimple_val,
			       fb_rvalue);
		gcond *cond = gimple_build_cond_from_tree (present,
							   notnull_label,
							   null_label);
		gimple_seq_add_stmt (&ilist, cond);
		gimple_seq_add_stmt (&ilist, gimple_build_label (null_label));
		gimplify_assign (new_x, null_pointer_node, &ilist);
		gimple_seq_add_stmt (&ilist, gimple_build_goto (opt_arg_label));
		gimple_seq_add_stmt (&ilist,
				     gimple_build_label (notnull_label));
		gimplify_assign (x, var, &ilist);
		gimple_seq_add_stmt (&ilist,
				     gimple_build_label (opt_arg_label));
	      }
	    else
	      gimplify_assign (x, var, &ilist);
	    s = size_int (0);
	    purpose = size_int (map_idx++);
	    CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
	    gcc_checking_assert (tkind
				 < (HOST_WIDE_INT_C (1U) << talign_shift));
	    gcc_checking_assert (tkind
				 <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
	    CONSTRUCTOR_APPEND_ELT (vkind, purpose,
				    build_int_cstu (tkind_type, tkind));
	    break;
	  }

      gcc_assert (map_idx == map_cnt);

      DECL_INITIAL (TREE_VEC_ELT (t, 1))
	= build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 1)), vsize);
      DECL_INITIAL (TREE_VEC_ELT (t, 2))
	= build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 2)), vkind);
      for (int i = 1; i <= 2; i++)
	if (!TREE_STATIC (TREE_VEC_ELT (t, i)))
	  {
	    gimple_seq initlist = NULL;
	    force_gimple_operand (build1 (DECL_EXPR, void_type_node,
					  TREE_VEC_ELT (t, i)),
				  &initlist, true, NULL_TREE);
	    gimple_seq_add_seq (&ilist, initlist);

	    tree clobber = build_clobber (TREE_TYPE (TREE_VEC_ELT (t, i)));
	    gimple_seq_add_stmt (&olist,
				 gimple_build_assign (TREE_VEC_ELT (t, i),
						      clobber));
	  }
	else if (omp_maybe_offloaded_ctx (ctx->outer))
	  {
	    tree id = get_identifier ("omp declare target");
	    tree decl = TREE_VEC_ELT (t, i);
	    DECL_ATTRIBUTES (decl)
	      = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
	    varpool_node *node = varpool_node::get (decl);
	    if (node)
	      {
		node->offloadable = 1;
		if (ENABLE_OFFLOADING)
		  {
		    g->have_offload = true;
		    vec_safe_push (offload_vars, t);
		  }
	      }
	  }

      tree clobber = build_clobber (ctx->record_type);
      gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
							clobber));
    }

  /* Once all the expansions are done, sequence all the different
     fragments inside gimple_omp_body.  */

  new_body = NULL;

  if (offloaded
      && ctx->record_type)
    {
      t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
      /* fixup_child_record_type might have changed receiver_decl's type.  */
      t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
      gimple_seq_add_stmt (&new_body,
	  		   gimple_build_assign (ctx->receiver_decl, t));
    }
  gimple_seq_add_seq (&new_body, fplist);

  if (offloaded || data_region)
    {
      tree prev = NULL_TREE;
      for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
	switch (OMP_CLAUSE_CODE (c))
	  {
	    tree var, x;
	  default:
	    break;
	  case OMP_CLAUSE_FIRSTPRIVATE:
	    if (is_gimple_omp_oacc (ctx->stmt))
	      break;
	    var = OMP_CLAUSE_DECL (c);
	    if (omp_privatize_by_reference (var)
		|| is_gimple_reg_type (TREE_TYPE (var)))
	      {
		tree new_var = lookup_decl (var, ctx);
		tree type;
		type = TREE_TYPE (var);
		if (omp_privatize_by_reference (var))
		  type = TREE_TYPE (type);
		if ((INTEGRAL_TYPE_P (type)
		     && TYPE_PRECISION (type) <= POINTER_SIZE)
		    || TREE_CODE (type) == POINTER_TYPE)
		  {
		    x = build_receiver_ref (var, false, ctx);
		    if (TREE_CODE (type) != POINTER_TYPE)
		      x = fold_convert (pointer_sized_int_node, x);
		    x = fold_convert (type, x);
		    gimplify_expr (&x, &new_body, NULL, is_gimple_val,
				   fb_rvalue);
		    if (omp_privatize_by_reference (var))
		      {
			tree v = create_tmp_var_raw (type, get_name (var));
			gimple_add_tmp_var (v);
			TREE_ADDRESSABLE (v) = 1;
			gimple_seq_add_stmt (&new_body,
					     gimple_build_assign (v, x));
			x = build_fold_addr_expr (v);
		      }
		    gimple_seq_add_stmt (&new_body,
					 gimple_build_assign (new_var, x));
		  }
		else
		  {
		    bool by_ref = !omp_privatize_by_reference (var);
		    x = build_receiver_ref (var, by_ref, ctx);
		    gimplify_expr (&x, &new_body, NULL, is_gimple_val,
				   fb_rvalue);
		    gimple_seq_add_stmt (&new_body,
					 gimple_build_assign (new_var, x));
		  }
	      }
	    else if (is_variable_sized (var))
	      {
		tree pvar = DECL_VALUE_EXPR (var);
		gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
		pvar = TREE_OPERAND (pvar, 0);
		gcc_assert (DECL_P (pvar));
		tree new_var = lookup_decl (pvar, ctx);
		x = build_receiver_ref (var, false, ctx);
		gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
		gimple_seq_add_stmt (&new_body,
				     gimple_build_assign (new_var, x));
	      }
	    break;
	  case OMP_CLAUSE_PRIVATE:
	    if (is_gimple_omp_oacc (ctx->stmt))
	      break;
	    var = OMP_CLAUSE_DECL (c);
	    if (omp_privatize_by_reference (var))
	      {
		location_t clause_loc = OMP_CLAUSE_LOCATION (c);
		tree new_var = lookup_decl (var, ctx);
		x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
		if (TREE_CONSTANT (x))
		  {
		    x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
					    get_name (var));
		    gimple_add_tmp_var (x);
		    TREE_ADDRESSABLE (x) = 1;
		    x = build_fold_addr_expr_loc (clause_loc, x);
		  }
		else
		  break;

		x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
		gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
		gimple_seq_add_stmt (&new_body,
				     gimple_build_assign (new_var, x));
	      }
	    break;
	  case OMP_CLAUSE_USE_DEVICE_PTR:
	  case OMP_CLAUSE_USE_DEVICE_ADDR:
	  case OMP_CLAUSE_IS_DEVICE_PTR:
	    tree new_var;
	    gimple_seq assign_body;
	    bool is_array_data;
	    bool do_optional_check;
	    assign_body = NULL;
	    do_optional_check = false;
	    var = OMP_CLAUSE_DECL (c);
	    is_array_data = lang_hooks.decls.omp_array_data (var, true) != NULL;

	    if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IS_DEVICE_PTR)
	      x = build_sender_ref (is_array_data
				    ? (splay_tree_key) &DECL_NAME (var)
				    : (splay_tree_key) &DECL_UID (var), ctx);
	    else
	      x = build_receiver_ref (var, false, ctx);

	    if (is_array_data)
	      {
		bool is_ref = omp_privatize_by_reference (var);
		do_optional_check = true;
		/* First, we copy the descriptor data from the host; then
		   we update its data to point to the target address.  */
		new_var = lookup_decl (var, ctx);
		new_var = DECL_VALUE_EXPR (new_var);
		tree v = new_var;

		if (is_ref)
		  {
		    var = build_fold_indirect_ref (var);
		    gimplify_expr (&var, &assign_body, NULL, is_gimple_val,
				   fb_rvalue);
		    v = create_tmp_var_raw (TREE_TYPE (var), get_name (var));
		    gimple_add_tmp_var (v);
		    TREE_ADDRESSABLE (v) = 1;
		    gimple_seq_add_stmt (&assign_body,
					 gimple_build_assign (v, var));
		    tree rhs = build_fold_addr_expr (v);
		    gimple_seq_add_stmt (&assign_body,
					 gimple_build_assign (new_var, rhs));
		  }
		else
		  gimple_seq_add_stmt (&assign_body,
				       gimple_build_assign (new_var, var));

		tree v2 = lang_hooks.decls.omp_array_data (unshare_expr (v), false);
		gcc_assert (v2);
		gimplify_expr (&x, &assign_body, NULL, is_gimple_val, fb_rvalue);
		gimple_seq_add_stmt (&assign_body,
				     gimple_build_assign (v2, x));
	      }
	    else if (is_variable_sized (var))
	      {
		tree pvar = DECL_VALUE_EXPR (var);
		gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
		pvar = TREE_OPERAND (pvar, 0);
		gcc_assert (DECL_P (pvar));
		new_var = lookup_decl (pvar, ctx);
		gimplify_expr (&x, &assign_body, NULL, is_gimple_val, fb_rvalue);
		gimple_seq_add_stmt (&assign_body,
				     gimple_build_assign (new_var, x));
	      }
	    else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
		      && !omp_privatize_by_reference (var)
		      && !omp_is_allocatable_or_ptr (var))
		     || TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
	      {
		new_var = lookup_decl (var, ctx);
		new_var = DECL_VALUE_EXPR (new_var);
		gcc_assert (TREE_CODE (new_var) == MEM_REF);
		new_var = TREE_OPERAND (new_var, 0);
		gcc_assert (DECL_P (new_var));
		gimplify_expr (&x, &assign_body, NULL, is_gimple_val, fb_rvalue);
		gimple_seq_add_stmt (&assign_body,
				     gimple_build_assign (new_var, x));
	      }
	    else
	      {
		tree type = TREE_TYPE (var);
		new_var = lookup_decl (var, ctx);
		if (omp_privatize_by_reference (var))
		  {
		    type = TREE_TYPE (type);
		    if (POINTER_TYPE_P (type)
			&& TREE_CODE (type) != ARRAY_TYPE
			&& (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_USE_DEVICE_ADDR
			    || (omp_privatize_by_reference (var)
				&& omp_is_allocatable_or_ptr (var))))
		      {
			tree v = create_tmp_var_raw (type, get_name (var));
			gimple_add_tmp_var (v);
			TREE_ADDRESSABLE (v) = 1;
			x = fold_convert (type, x);
			gimplify_expr (&x, &assign_body, NULL, is_gimple_val,
				       fb_rvalue);
			gimple_seq_add_stmt (&assign_body,
					     gimple_build_assign (v, x));
			x = build_fold_addr_expr (v);
			do_optional_check = true;
		      }
		  }
		new_var = DECL_VALUE_EXPR (new_var);
		x = fold_convert (TREE_TYPE (new_var), x);
		gimplify_expr (&x, &assign_body, NULL, is_gimple_val, fb_rvalue);
		gimple_seq_add_stmt (&assign_body,
				     gimple_build_assign (new_var, x));
	      }
	    tree present;
	    present = (do_optional_check
		       ? omp_check_optional_argument (OMP_CLAUSE_DECL (c), true)
		       : NULL_TREE);
	    if (present)
	      {
		tree null_label = create_artificial_label (UNKNOWN_LOCATION);
		tree notnull_label = create_artificial_label (UNKNOWN_LOCATION);
		tree opt_arg_label = create_artificial_label (UNKNOWN_LOCATION);
		glabel *null_glabel = gimple_build_label (null_label);
		glabel *notnull_glabel = gimple_build_label (notnull_label);
		ggoto *opt_arg_ggoto = gimple_build_goto (opt_arg_label);
		gimplify_expr (&x, &new_body, NULL, is_gimple_val,
					   fb_rvalue);
		gimplify_expr (&present, &new_body, NULL, is_gimple_val,
			       fb_rvalue);
		gcond *cond = gimple_build_cond_from_tree (present,
							   notnull_label,
							   null_label);
		gimple_seq_add_stmt (&new_body, cond);
		gimple_seq_add_stmt (&new_body, null_glabel);
		gimplify_assign (new_var, null_pointer_node, &new_body);
		gimple_seq_add_stmt (&new_body, opt_arg_ggoto);
		gimple_seq_add_stmt (&new_body, notnull_glabel);
		gimple_seq_add_seq (&new_body, assign_body);
		gimple_seq_add_stmt (&new_body,
				     gimple_build_label (opt_arg_label));
	      }
	    else
	      gimple_seq_add_seq (&new_body, assign_body);
	    break;
	  }
      /* Handle GOMP_MAP_FIRSTPRIVATE_{POINTER,REFERENCE} in second pass,
	 so that firstprivate vars holding OMP_CLAUSE_SIZE if needed
	 are already handled.  Similarly OMP_CLAUSE_PRIVATE for VLAs
	 or references to VLAs.  */
      for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
	switch (OMP_CLAUSE_CODE (c))
	  {
	    tree var;
	  default:
	    break;
	  case OMP_CLAUSE_MAP:
	    if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
		|| OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
	      {
		location_t clause_loc = OMP_CLAUSE_LOCATION (c);
		poly_int64 offset = 0;
		gcc_assert (prev);
		var = OMP_CLAUSE_DECL (c);
		if (DECL_P (var)
		    && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
		    && is_global_var (maybe_lookup_decl_in_outer_ctx (var,
								      ctx))
		    && varpool_node::get_create (var)->offloadable)
		  break;
		if (TREE_CODE (var) == INDIRECT_REF
		    && TREE_CODE (TREE_OPERAND (var, 0)) == COMPONENT_REF)
		  var = TREE_OPERAND (var, 0);
		if (TREE_CODE (var) == COMPONENT_REF)
		  {
		    var = get_addr_base_and_unit_offset (var, &offset);
		    gcc_assert (var != NULL_TREE && DECL_P (var));
		  }
		else if (DECL_SIZE (var)
			 && TREE_CODE (DECL_SIZE (var)) != INTEGER_CST)
		  {
		    tree var2 = DECL_VALUE_EXPR (var);
		    gcc_assert (TREE_CODE (var2) == INDIRECT_REF);
		    var2 = TREE_OPERAND (var2, 0);
		    gcc_assert (DECL_P (var2));
		    var = var2;
		  }
		tree new_var = lookup_decl (var, ctx), x;
		tree type = TREE_TYPE (new_var);
		bool is_ref;
		if (TREE_CODE (OMP_CLAUSE_DECL (c)) == INDIRECT_REF
		    && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
			== COMPONENT_REF))
		  {
		    type = TREE_TYPE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0));
		    is_ref = true;
		    new_var = build2 (MEM_REF, type,
				      build_fold_addr_expr (new_var),
				      build_int_cst (build_pointer_type (type),
						     offset));
		  }
		else if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPONENT_REF)
		  {
		    type = TREE_TYPE (OMP_CLAUSE_DECL (c));
		    is_ref = TREE_CODE (type) == REFERENCE_TYPE;
		    new_var = build2 (MEM_REF, type,
				      build_fold_addr_expr (new_var),
				      build_int_cst (build_pointer_type (type),
						     offset));
		  }
		else
		  is_ref = omp_privatize_by_reference (var);
		if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
		  is_ref = false;
		bool ref_to_array = false;
		if (is_ref)
		  {
		    type = TREE_TYPE (type);
		    if (TREE_CODE (type) == ARRAY_TYPE)
		      {
			type = build_pointer_type (type);
			ref_to_array = true;
		      }
		  }
		else if (TREE_CODE (type) == ARRAY_TYPE)
		  {
		    tree decl2 = DECL_VALUE_EXPR (new_var);
		    gcc_assert (TREE_CODE (decl2) == MEM_REF);
		    decl2 = TREE_OPERAND (decl2, 0);
		    gcc_assert (DECL_P (decl2));
		    new_var = decl2;
		    type = TREE_TYPE (new_var);
		  }
		x = build_receiver_ref (OMP_CLAUSE_DECL (prev), false, ctx);
		x = fold_convert_loc (clause_loc, type, x);
		if (!integer_zerop (OMP_CLAUSE_SIZE (c)))
		  {
		    tree bias = OMP_CLAUSE_SIZE (c);
		    if (DECL_P (bias))
		      bias = lookup_decl (bias, ctx);
		    bias = fold_convert_loc (clause_loc, sizetype, bias);
		    bias = fold_build1_loc (clause_loc, NEGATE_EXPR, sizetype,
					    bias);
		    x = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
					 TREE_TYPE (x), x, bias);
		  }
		if (ref_to_array)
		  x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
		gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
		if (is_ref && !ref_to_array)
		  {
		    tree t = create_tmp_var_raw (type, get_name (var));
		    gimple_add_tmp_var (t);
		    TREE_ADDRESSABLE (t) = 1;
		    gimple_seq_add_stmt (&new_body,
					 gimple_build_assign (t, x));
		    x = build_fold_addr_expr_loc (clause_loc, t);
		  }
		gimple_seq_add_stmt (&new_body,
				     gimple_build_assign (new_var, x));
		prev = NULL_TREE;
	      }
	    else if (OMP_CLAUSE_CHAIN (c)
		     && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c))
			== OMP_CLAUSE_MAP
		     && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
			 == GOMP_MAP_FIRSTPRIVATE_POINTER
			 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
			     == GOMP_MAP_FIRSTPRIVATE_REFERENCE)))
	      prev = c;
	    break;
	  case OMP_CLAUSE_PRIVATE:
	    var = OMP_CLAUSE_DECL (c);
	    if (is_variable_sized (var))
	      {
		location_t clause_loc = OMP_CLAUSE_LOCATION (c);
		tree new_var = lookup_decl (var, ctx);
		tree pvar = DECL_VALUE_EXPR (var);
		gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
		pvar = TREE_OPERAND (pvar, 0);
		gcc_assert (DECL_P (pvar));
		tree new_pvar = lookup_decl (pvar, ctx);
		tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
		tree al = size_int (DECL_ALIGN (var));
		tree x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
		x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
		x = fold_convert_loc (clause_loc, TREE_TYPE (new_pvar), x);
		gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
		gimple_seq_add_stmt (&new_body,
				     gimple_build_assign (new_pvar, x));
	      }
	    else if (omp_privatize_by_reference (var)
		     && !is_gimple_omp_oacc (ctx->stmt))
	      {
		location_t clause_loc = OMP_CLAUSE_LOCATION (c);
		tree new_var = lookup_decl (var, ctx);
		tree x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
		if (TREE_CONSTANT (x))
		  break;
		else
		  {
		    tree atmp
		      = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
		    tree rtype = TREE_TYPE (TREE_TYPE (new_var));
		    tree al = size_int (TYPE_ALIGN (rtype));
		    x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
		  }

		x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
		gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
		gimple_seq_add_stmt (&new_body,
				     gimple_build_assign (new_var, x));
	      }
	    break;
	  }

      gimple_seq fork_seq = NULL;
      gimple_seq join_seq = NULL;

      if (offloaded && is_gimple_omp_oacc (ctx->stmt))
	{
	  /* If there are reductions on the offloaded region itself, treat
	     them as a dummy GANG loop.  */
	  tree level = build_int_cst (integer_type_node, GOMP_DIM_GANG);

	  gcall *private_marker = lower_oacc_private_marker (ctx);

	  if (private_marker)
	    gimple_call_set_arg (private_marker, 2, level);

	  lower_oacc_reductions (gimple_location (ctx->stmt), clauses, level,
				 false, NULL, private_marker, NULL, &fork_seq,
				 &join_seq, ctx);
	}

      gimple_seq_add_seq (&new_body, fork_seq);
      gimple_seq_add_seq (&new_body, tgt_body);
      gimple_seq_add_seq (&new_body, join_seq);

      if (offloaded)
	{
	  new_body = maybe_catch_exception (new_body);
	  gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
	}
      gimple_omp_set_body (stmt, new_body);
    }

  bind = gimple_build_bind (NULL, NULL,
			    tgt_bind ? gimple_bind_block (tgt_bind)
				     : NULL_TREE);
  gsi_replace (gsi_p, dep_bind ? dep_bind : bind, true);
  gimple_bind_add_seq (bind, ilist);
  gimple_bind_add_stmt (bind, stmt);
  gimple_bind_add_seq (bind, olist);

  pop_gimplify_context (NULL);

  if (dep_bind)
    {
      gimple_bind_add_seq (dep_bind, dep_ilist);
      gimple_bind_add_stmt (dep_bind, bind);
      gimple_bind_add_seq (dep_bind, dep_olist);
      pop_gimplify_context (dep_bind);
    }
}

/* Expand code for an OpenMP teams directive.  */

static void
lower_omp_teams (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
  gomp_teams *teams_stmt = as_a <gomp_teams *> (gsi_stmt (*gsi_p));
  push_gimplify_context ();

  tree block = make_node (BLOCK);
  gbind *bind = gimple_build_bind (NULL, NULL, block);
  gsi_replace (gsi_p, bind, true);
  gimple_seq bind_body = NULL;
  gimple_seq dlist = NULL;
  gimple_seq olist = NULL;

  tree num_teams = omp_find_clause (gimple_omp_teams_clauses (teams_stmt),
				    OMP_CLAUSE_NUM_TEAMS);
  if (num_teams == NULL_TREE)
    num_teams = build_int_cst (unsigned_type_node, 0);
  else
    {
      num_teams = OMP_CLAUSE_NUM_TEAMS_EXPR (num_teams);
      num_teams = fold_convert (unsigned_type_node, num_teams);
      gimplify_expr (&num_teams, &bind_body, NULL, is_gimple_val, fb_rvalue);
    }
  tree thread_limit = omp_find_clause (gimple_omp_teams_clauses (teams_stmt),
				       OMP_CLAUSE_THREAD_LIMIT);
  if (thread_limit == NULL_TREE)
    thread_limit = build_int_cst (unsigned_type_node, 0);
  else
    {
      thread_limit = OMP_CLAUSE_THREAD_LIMIT_EXPR (thread_limit);
      thread_limit = fold_convert (unsigned_type_node, thread_limit);
      gimplify_expr (&thread_limit, &bind_body, NULL, is_gimple_val,
		     fb_rvalue);
    }

  lower_rec_input_clauses (gimple_omp_teams_clauses (teams_stmt),
			   &bind_body, &dlist, ctx, NULL);
  lower_omp (gimple_omp_body_ptr (teams_stmt), ctx);
  lower_reduction_clauses (gimple_omp_teams_clauses (teams_stmt), &olist,
			   NULL, ctx);
  gimple_seq_add_stmt (&bind_body, teams_stmt);

  location_t loc = gimple_location (teams_stmt);
  tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TEAMS);
  gimple *call = gimple_build_call (decl, 2, num_teams, thread_limit);
  gimple_set_location (call, loc);
  gimple_seq_add_stmt (&bind_body, call);

  gimple_seq_add_seq (&bind_body, gimple_omp_body (teams_stmt));
  gimple_omp_set_body (teams_stmt, NULL);
  gimple_seq_add_seq (&bind_body, olist);
  gimple_seq_add_seq (&bind_body, dlist);
  gimple_seq_add_stmt (&bind_body, gimple_build_omp_return (true));
  gimple_bind_set_body (bind, bind_body);

  pop_gimplify_context (bind);

  gimple_bind_append_vars (bind, ctx->block_vars);
  BLOCK_VARS (block) = ctx->block_vars;
  if (BLOCK_VARS (block))
    TREE_USED (block) = 1;
}

/* Callback for lower_omp_1.  Return non-NULL if *tp needs to be
   regimplified.  If DATA is non-NULL, lower_omp_1 is outside
   of OMP context, but with task_shared_vars set.  */

static tree
lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
    			void *data)
{
  tree t = *tp;

  /* Any variable with DECL_VALUE_EXPR needs to be regimplified.  */
  if ((VAR_P (t) || TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
      && data == NULL
      && DECL_HAS_VALUE_EXPR_P (t))
    return t;

  if (task_shared_vars
      && DECL_P (t)
      && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
    return t;

  /* If a global variable has been privatized, TREE_CONSTANT on
     ADDR_EXPR might be wrong.  */
  if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
    recompute_tree_invariant_for_addr_expr (t);

  *walk_subtrees = !IS_TYPE_OR_DECL_P (t);
  return NULL_TREE;
}

/* Data to be communicated between lower_omp_regimplify_operands and
   lower_omp_regimplify_operands_p.  */

struct lower_omp_regimplify_operands_data
{
  omp_context *ctx;
  vec<tree> *decls;
};

/* Helper function for lower_omp_regimplify_operands.  Find
   omp_member_access_dummy_var vars and adjust temporarily their
   DECL_VALUE_EXPRs if needed.  */

static tree
lower_omp_regimplify_operands_p (tree *tp, int *walk_subtrees,
				 void *data)
{
  tree t = omp_member_access_dummy_var (*tp);
  if (t)
    {
      struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
      lower_omp_regimplify_operands_data *ldata
	= (lower_omp_regimplify_operands_data *) wi->info;
      tree o = maybe_lookup_decl (t, ldata->ctx);
      if (o != t)
	{
	  ldata->decls->safe_push (DECL_VALUE_EXPR (*tp));
	  ldata->decls->safe_push (*tp);
	  tree v = unshare_and_remap (DECL_VALUE_EXPR (*tp), t, o);
	  SET_DECL_VALUE_EXPR (*tp, v);
	}
    }
  *walk_subtrees = !IS_TYPE_OR_DECL_P (*tp);
  return NULL_TREE;
}

/* Wrapper around gimple_regimplify_operands that adjusts DECL_VALUE_EXPRs
   of omp_member_access_dummy_var vars during regimplification.  */

static void
lower_omp_regimplify_operands (omp_context *ctx, gimple *stmt,
			       gimple_stmt_iterator *gsi_p)
{
  auto_vec<tree, 10> decls;
  if (ctx)
    {
      struct walk_stmt_info wi;
      memset (&wi, '\0', sizeof (wi));
      struct lower_omp_regimplify_operands_data data;
      data.ctx = ctx;
      data.decls = &decls;
      wi.info = &data;
      walk_gimple_op (stmt, lower_omp_regimplify_operands_p, &wi);
    }
  gimple_regimplify_operands (stmt, gsi_p);
  while (!decls.is_empty ())
    {
      tree t = decls.pop ();
      tree v = decls.pop ();
      SET_DECL_VALUE_EXPR (t, v);
    }
}

static void
lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
  gimple *stmt = gsi_stmt (*gsi_p);
  struct walk_stmt_info wi;
  gcall *call_stmt;

  if (gimple_has_location (stmt))
    input_location = gimple_location (stmt);

  if (task_shared_vars)
    memset (&wi, '\0', sizeof (wi));

  /* If we have issued syntax errors, avoid doing any heavy lifting.
     Just replace the OMP directives with a NOP to avoid
     confusing RTL expansion.  */
  if (seen_error () && is_gimple_omp (stmt))
    {
      gsi_replace (gsi_p, gimple_build_nop (), true);
      return;
    }

  switch (gimple_code (stmt))
    {
    case GIMPLE_COND:
      {
	gcond *cond_stmt = as_a <gcond *> (stmt);
	if ((ctx || task_shared_vars)
	    && (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
			   lower_omp_regimplify_p,
			   ctx ? NULL : &wi, NULL)
		|| walk_tree (gimple_cond_rhs_ptr (cond_stmt),
			      lower_omp_regimplify_p,
			      ctx ? NULL : &wi, NULL)))
	  lower_omp_regimplify_operands (ctx, cond_stmt, gsi_p);
      }
      break;
    case GIMPLE_CATCH:
      lower_omp (gimple_catch_handler_ptr (as_a <gcatch *> (stmt)), ctx);
      break;
    case GIMPLE_EH_FILTER:
      lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
      break;
    case GIMPLE_TRY:
      lower_omp (gimple_try_eval_ptr (stmt), ctx);
      lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
      break;
    case GIMPLE_TRANSACTION:
      lower_omp (gimple_transaction_body_ptr (as_a <gtransaction *> (stmt)),
		 ctx);
      break;
    case GIMPLE_BIND:
      if (ctx && is_gimple_omp_oacc (ctx->stmt))
	{
	  tree vars = gimple_bind_vars (as_a <gbind *> (stmt));
	  oacc_privatization_scan_decl_chain (ctx, vars);
	}
      lower_omp (gimple_bind_body_ptr (as_a <gbind *> (stmt)), ctx);
      maybe_remove_omp_member_access_dummy_vars (as_a <gbind *> (stmt));
      break;
    case GIMPLE_OMP_PARALLEL:
    case GIMPLE_OMP_TASK:
      ctx = maybe_lookup_ctx (stmt);
      gcc_assert (ctx);
      if (ctx->cancellable)
	ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
      lower_omp_taskreg (gsi_p, ctx);
      break;
    case GIMPLE_OMP_FOR:
      ctx = maybe_lookup_ctx (stmt);
      gcc_assert (ctx);
      if (ctx->cancellable)
	ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
      lower_omp_for (gsi_p, ctx);
      break;
    case GIMPLE_OMP_SECTIONS:
      ctx = maybe_lookup_ctx (stmt);
      gcc_assert (ctx);
      if (ctx->cancellable)
	ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
      lower_omp_sections (gsi_p, ctx);
      break;
    case GIMPLE_OMP_SCOPE:
      ctx = maybe_lookup_ctx (stmt);
      gcc_assert (ctx);
      lower_omp_scope (gsi_p, ctx);
      break;
    case GIMPLE_OMP_SINGLE:
      ctx = maybe_lookup_ctx (stmt);
      gcc_assert (ctx);
      lower_omp_single (gsi_p, ctx);
      break;
    case GIMPLE_OMP_MASTER:
    case GIMPLE_OMP_MASKED:
      ctx = maybe_lookup_ctx (stmt);
      gcc_assert (ctx);
      lower_omp_master (gsi_p, ctx);
      break;
    case GIMPLE_OMP_TASKGROUP:
      ctx = maybe_lookup_ctx (stmt);
      gcc_assert (ctx);
      lower_omp_taskgroup (gsi_p, ctx);
      break;
    case GIMPLE_OMP_ORDERED:
      ctx = maybe_lookup_ctx (stmt);
      gcc_assert (ctx);
      lower_omp_ordered (gsi_p, ctx);
      break;
    case GIMPLE_OMP_SCAN:
      ctx = maybe_lookup_ctx (stmt);
      gcc_assert (ctx);
      lower_omp_scan (gsi_p, ctx);
      break;
    case GIMPLE_OMP_CRITICAL:
      ctx = maybe_lookup_ctx (stmt);
      gcc_assert (ctx);
      lower_omp_critical (gsi_p, ctx);
      break;
    case GIMPLE_OMP_ATOMIC_LOAD:
      if ((ctx || task_shared_vars)
	  && walk_tree (gimple_omp_atomic_load_rhs_ptr (
			  as_a <gomp_atomic_load *> (stmt)),
			lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
	lower_omp_regimplify_operands (ctx, stmt, gsi_p);
      break;
    case GIMPLE_OMP_TARGET:
      ctx = maybe_lookup_ctx (stmt);
      gcc_assert (ctx);
      lower_omp_target (gsi_p, ctx);
      break;
    case GIMPLE_OMP_TEAMS:
      ctx = maybe_lookup_ctx (stmt);
      gcc_assert (ctx);
      if (gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
	lower_omp_taskreg (gsi_p, ctx);
      else
	lower_omp_teams (gsi_p, ctx);
      break;
    case GIMPLE_CALL:
      tree fndecl;
      call_stmt = as_a <gcall *> (stmt);
      fndecl = gimple_call_fndecl (call_stmt);
      if (fndecl
	  && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
	switch (DECL_FUNCTION_CODE (fndecl))
	  {
	  case BUILT_IN_GOMP_BARRIER:
	    if (ctx == NULL)
	      break;
	    /* FALLTHRU */
	  case BUILT_IN_GOMP_CANCEL:
	  case BUILT_IN_GOMP_CANCELLATION_POINT:
	    omp_context *cctx;
	    cctx = ctx;
	    if (gimple_code (cctx->stmt) == GIMPLE_OMP_SECTION)
	      cctx = cctx->outer;
	    gcc_assert (gimple_call_lhs (call_stmt) == NULL_TREE);
	    if (!cctx->cancellable)
	      {
		if (DECL_FUNCTION_CODE (fndecl)
		    == BUILT_IN_GOMP_CANCELLATION_POINT)
		  {
		    stmt = gimple_build_nop ();
		    gsi_replace (gsi_p, stmt, false);
		  }
		break;
	      }
	    if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
	      {
		fndecl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER_CANCEL);
		gimple_call_set_fndecl (call_stmt, fndecl);
		gimple_call_set_fntype (call_stmt, TREE_TYPE (fndecl));
	      }
	    tree lhs;
	    lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (fndecl)));
	    gimple_call_set_lhs (call_stmt, lhs);
	    tree fallthru_label;
	    fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
	    gimple *g;
	    g = gimple_build_label (fallthru_label);
	    gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
	    g = gimple_build_cond (NE_EXPR, lhs,
				   fold_convert (TREE_TYPE (lhs),
						 boolean_false_node),
				   cctx->cancel_label, fallthru_label);
	    gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
	    break;
	  default:
	    break;
	  }
      goto regimplify;

    case GIMPLE_ASSIGN:
      for (omp_context *up = ctx; up; up = up->outer)
	{
	  if (gimple_code (up->stmt) == GIMPLE_OMP_ORDERED
	      || gimple_code (up->stmt) == GIMPLE_OMP_CRITICAL
	      || gimple_code (up->stmt) == GIMPLE_OMP_TASKGROUP
	      || gimple_code (up->stmt) == GIMPLE_OMP_SCOPE
	      || gimple_code (up->stmt) == GIMPLE_OMP_SECTION
	      || gimple_code (up->stmt) == GIMPLE_OMP_SCAN
	      || (gimple_code (up->stmt) == GIMPLE_OMP_TARGET
		  && (gimple_omp_target_kind (up->stmt)
		      == GF_OMP_TARGET_KIND_DATA)))
	    continue;
	  else if (!up->lastprivate_conditional_map)
	    break;
	  tree lhs = get_base_address (gimple_assign_lhs (stmt));
	  if (TREE_CODE (lhs) == MEM_REF
	      && DECL_P (TREE_OPERAND (lhs, 0))
	      && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs,
						     0))) == REFERENCE_TYPE)
	    lhs = TREE_OPERAND (lhs, 0);
	  if (DECL_P (lhs))
	    if (tree *v = up->lastprivate_conditional_map->get (lhs))
	      {
		tree clauses;
		if (up->combined_into_simd_safelen1)
		  {
		    up = up->outer;
		    if (gimple_code (up->stmt) == GIMPLE_OMP_SCAN)
		      up = up->outer;
		  }
		if (gimple_code (up->stmt) == GIMPLE_OMP_FOR)
		  clauses = gimple_omp_for_clauses (up->stmt);
		else
		  clauses = gimple_omp_sections_clauses (up->stmt);
		tree c = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_);
		if (!OMP_CLAUSE__CONDTEMP__ITER (c))
		  c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
				       OMP_CLAUSE__CONDTEMP_);
		gcc_assert (OMP_CLAUSE__CONDTEMP__ITER (c));
		gimple *g = gimple_build_assign (*v, OMP_CLAUSE_DECL (c));
		gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
	      }
	}
      /* FALLTHRU */

    default:
    regimplify:
      if ((ctx || task_shared_vars)
	  && walk_gimple_op (stmt, lower_omp_regimplify_p,
			     ctx ? NULL : &wi))
	{
	  /* Just remove clobbers, this should happen only if we have
	     "privatized" local addressable variables in SIMD regions,
	     the clobber isn't needed in that case and gimplifying address
	     of the ARRAY_REF into a pointer and creating MEM_REF based
	     clobber would create worse code than we get with the clobber
	     dropped.  */
	  if (gimple_clobber_p (stmt))
	    {
	      gsi_replace (gsi_p, gimple_build_nop (), true);
	      break;
	    }
	  lower_omp_regimplify_operands (ctx, stmt, gsi_p);
	}
      break;
    }
}

static void
lower_omp (gimple_seq *body, omp_context *ctx)
{
  location_t saved_location = input_location;
  gimple_stmt_iterator gsi;
  for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
    lower_omp_1 (&gsi, ctx);
  /* During gimplification, we haven't folded statments inside offloading
     or taskreg regions (gimplify.c:maybe_fold_stmt); do that now.  */
  if (target_nesting_level || taskreg_nesting_level)
    for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
      fold_stmt (&gsi);
  input_location = saved_location;
}

/* Main entry point.  */

static unsigned int
execute_lower_omp (void)
{
  gimple_seq body;
  int i;
  omp_context *ctx;

  /* This pass always runs, to provide PROP_gimple_lomp.
     But often, there is nothing to do.  */
  if (flag_openacc == 0 && flag_openmp == 0
      && flag_openmp_simd == 0)
    return 0;

  all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
				 delete_omp_context);

  body = gimple_body (current_function_decl);

  scan_omp (&body, NULL);
  gcc_assert (taskreg_nesting_level == 0);
  FOR_EACH_VEC_ELT (taskreg_contexts, i, ctx)
    finish_taskreg_scan (ctx);
  taskreg_contexts.release ();

  if (all_contexts->root)
    {
      if (task_shared_vars)
	push_gimplify_context ();
      lower_omp (&body, NULL);
      if (task_shared_vars)
	pop_gimplify_context (NULL);
    }

  if (all_contexts)
    {
      splay_tree_delete (all_contexts);
      all_contexts = NULL;
    }
  BITMAP_FREE (task_shared_vars);
  BITMAP_FREE (global_nonaddressable_vars);

  /* If current function is a method, remove artificial dummy VAR_DECL created
     for non-static data member privatization, they aren't needed for
     debuginfo nor anything else, have been already replaced everywhere in the
     IL and cause problems with LTO.  */
  if (DECL_ARGUMENTS (current_function_decl)
      && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl))
      && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl)))
	  == POINTER_TYPE))
    remove_member_access_dummy_vars (DECL_INITIAL (current_function_decl));
  return 0;
}

namespace {

const pass_data pass_data_lower_omp =
{
  GIMPLE_PASS, /* type */
  "omplower", /* name */
  OPTGROUP_OMP, /* optinfo_flags */
  TV_NONE, /* tv_id */
  PROP_gimple_any, /* properties_required */
  PROP_gimple_lomp | PROP_gimple_lomp_dev, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_lower_omp : public gimple_opt_pass
{
public:
  pass_lower_omp (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_lower_omp, ctxt)
  {}

  /* opt_pass methods: */
  virtual unsigned int execute (function *) { return execute_lower_omp (); }

}; // class pass_lower_omp

} // anon namespace

gimple_opt_pass *
make_pass_lower_omp (gcc::context *ctxt)
{
  return new pass_lower_omp (ctxt);
}

/* The following is a utility to diagnose structured block violations.
   It is not part of the "omplower" pass, as that's invoked too late.  It
   should be invoked by the respective front ends after gimplification.  */

static splay_tree all_labels;

/* Check for mismatched contexts and generate an error if needed.  Return
   true if an error is detected.  */

static bool
diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
	       gimple *branch_ctx, gimple *label_ctx)
{
  gcc_checking_assert (!branch_ctx || is_gimple_omp (branch_ctx));
  gcc_checking_assert (!label_ctx || is_gimple_omp (label_ctx));

  if (label_ctx == branch_ctx)
    return false;

  const char* kind = NULL;

  if (flag_openacc)
    {
      if ((branch_ctx && is_gimple_omp_oacc (branch_ctx))
	  || (label_ctx && is_gimple_omp_oacc (label_ctx)))
	{
	  gcc_checking_assert (kind == NULL);
	  kind = "OpenACC";
	}
    }
  if (kind == NULL)
    {
      gcc_checking_assert (flag_openmp || flag_openmp_simd);
      kind = "OpenMP";
    }

  /* Previously we kept track of the label's entire context in diagnose_sb_[12]
     so we could traverse it and issue a correct "exit" or "enter" error
     message upon a structured block violation.

     We built the context by building a list with tree_cons'ing, but there is
     no easy counterpart in gimple tuples.  It seems like far too much work
     for issuing exit/enter error messages.  If someone really misses the
     distinct error message... patches welcome.  */

#if 0
  /* Try to avoid confusing the user by producing and error message
     with correct "exit" or "enter" verbiage.  We prefer "exit"
     unless we can show that LABEL_CTX is nested within BRANCH_CTX.  */
  if (branch_ctx == NULL)
    exit_p = false;
  else
    {
      while (label_ctx)
	{
	  if (TREE_VALUE (label_ctx) == branch_ctx)
	    {
	      exit_p = false;
	      break;
	    }
	  label_ctx = TREE_CHAIN (label_ctx);
	}
    }

  if (exit_p)
    error ("invalid exit from %s structured block", kind);
  else
    error ("invalid entry to %s structured block", kind);
#endif

  /* If it's obvious we have an invalid entry, be specific about the error.  */
  if (branch_ctx == NULL)
    error ("invalid entry to %s structured block", kind);
  else
    {
      /* Otherwise, be vague and lazy, but efficient.  */
      error ("invalid branch to/from %s structured block", kind);
    }

  gsi_replace (gsi_p, gimple_build_nop (), false);
  return true;
}

/* Pass 1: Create a minimal tree of structured blocks, and record
   where each label is found.  */

static tree
diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
    	       struct walk_stmt_info *wi)
{
  gimple *context = (gimple *) wi->info;
  gimple *inner_context;
  gimple *stmt = gsi_stmt (*gsi_p);

  *handled_ops_p = true;

  switch (gimple_code (stmt))
    {
    WALK_SUBSTMTS;

    case GIMPLE_OMP_PARALLEL:
    case GIMPLE_OMP_TASK:
    case GIMPLE_OMP_SCOPE:
    case GIMPLE_OMP_SECTIONS:
    case GIMPLE_OMP_SINGLE:
    case GIMPLE_OMP_SECTION:
    case GIMPLE_OMP_MASTER:
    case GIMPLE_OMP_MASKED:
    case GIMPLE_OMP_ORDERED:
    case GIMPLE_OMP_SCAN:
    case GIMPLE_OMP_CRITICAL:
    case GIMPLE_OMP_TARGET:
    case GIMPLE_OMP_TEAMS:
    case GIMPLE_OMP_TASKGROUP:
      /* The minimal context here is just the current OMP construct.  */
      inner_context = stmt;
      wi->info = inner_context;
      walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
      wi->info = context;
      break;

    case GIMPLE_OMP_FOR:
      inner_context = stmt;
      wi->info = inner_context;
      /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
	 walk them.  */
      walk_gimple_seq (gimple_omp_for_pre_body (stmt),
	  	       diagnose_sb_1, NULL, wi);
      walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
      wi->info = context;
      break;

    case GIMPLE_LABEL:
      splay_tree_insert (all_labels,
			 (splay_tree_key) gimple_label_label (
					    as_a <glabel *> (stmt)),
			 (splay_tree_value) context);
      break;

    default:
      break;
    }

  return NULL_TREE;
}

/* Pass 2: Check each branch and see if its context differs from that of
   the destination label's context.  */

static tree
diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
    	       struct walk_stmt_info *wi)
{
  gimple *context = (gimple *) wi->info;
  splay_tree_node n;
  gimple *stmt = gsi_stmt (*gsi_p);

  *handled_ops_p = true;

  switch (gimple_code (stmt))
    {
    WALK_SUBSTMTS;

    case GIMPLE_OMP_PARALLEL:
    case GIMPLE_OMP_TASK:
    case GIMPLE_OMP_SCOPE:
    case GIMPLE_OMP_SECTIONS:
    case GIMPLE_OMP_SINGLE:
    case GIMPLE_OMP_SECTION:
    case GIMPLE_OMP_MASTER:
    case GIMPLE_OMP_MASKED:
    case GIMPLE_OMP_ORDERED:
    case GIMPLE_OMP_SCAN:
    case GIMPLE_OMP_CRITICAL:
    case GIMPLE_OMP_TARGET:
    case GIMPLE_OMP_TEAMS:
    case GIMPLE_OMP_TASKGROUP:
      wi->info = stmt;
      walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
      wi->info = context;
      break;

    case GIMPLE_OMP_FOR:
      wi->info = stmt;
      /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
	 walk them.  */
      walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
			   diagnose_sb_2, NULL, wi);
      walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
      wi->info = context;
      break;

    case GIMPLE_COND:
	{
	  gcond *cond_stmt = as_a <gcond *> (stmt);
	  tree lab = gimple_cond_true_label (cond_stmt);
	  if (lab)
	    {
	      n = splay_tree_lookup (all_labels,
				     (splay_tree_key) lab);
	      diagnose_sb_0 (gsi_p, context,
			     n ? (gimple *) n->value : NULL);
	    }
	  lab = gimple_cond_false_label (cond_stmt);
	  if (lab)
	    {
	      n = splay_tree_lookup (all_labels,
				     (splay_tree_key) lab);
	      diagnose_sb_0 (gsi_p, context,
			     n ? (gimple *) n->value : NULL);
	    }
	}
      break;

    case GIMPLE_GOTO:
      {
	tree lab = gimple_goto_dest (stmt);
	if (TREE_CODE (lab) != LABEL_DECL)
	  break;

	n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
	diagnose_sb_0 (gsi_p, context, n ? (gimple *) n->value : NULL);
      }
      break;

    case GIMPLE_SWITCH:
      {
	gswitch *switch_stmt = as_a <gswitch *> (stmt);
	unsigned int i;
	for (i = 0; i < gimple_switch_num_labels (switch_stmt); ++i)
	  {
	    tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
	    n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
	    if (n && diagnose_sb_0 (gsi_p, context, (gimple *) n->value))
	      break;
	  }
      }
      break;

    case GIMPLE_RETURN:
      diagnose_sb_0 (gsi_p, context, NULL);
      break;

    default:
      break;
    }

  return NULL_TREE;
}

static unsigned int
diagnose_omp_structured_block_errors (void)
{
  struct walk_stmt_info wi;
  gimple_seq body = gimple_body (current_function_decl);

  all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);

  memset (&wi, 0, sizeof (wi));
  walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);

  memset (&wi, 0, sizeof (wi));
  wi.want_locations = true;
  walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);

  gimple_set_body (current_function_decl, body);

  splay_tree_delete (all_labels);
  all_labels = NULL;

  return 0;
}

namespace {

const pass_data pass_data_diagnose_omp_blocks =
{
  GIMPLE_PASS, /* type */
  "*diagnose_omp_blocks", /* name */
  OPTGROUP_OMP, /* optinfo_flags */
  TV_NONE, /* tv_id */
  PROP_gimple_any, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_diagnose_omp_blocks : public gimple_opt_pass
{
public:
  pass_diagnose_omp_blocks (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_diagnose_omp_blocks, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *)
  {
    return flag_openacc || flag_openmp || flag_openmp_simd;
  }
  virtual unsigned int execute (function *)
    {
      return diagnose_omp_structured_block_errors ();
    }

}; // class pass_diagnose_omp_blocks

} // anon namespace

gimple_opt_pass *
make_pass_diagnose_omp_blocks (gcc::context *ctxt)
{
  return new pass_diagnose_omp_blocks (ctxt);
}


#include "gt-omp-low.h"
