/* Nested function decomposition for GIMPLE.
- Copyright (C) 2004-2018 Free Software Foundation, Inc.
+ Copyright (C) 2004-2020 Free Software Foundation, Inc.
This file is part of GCC.
DECL_CONTEXT (tmp_var) = info->context;
DECL_CHAIN (tmp_var) = info->new_local_var_chain;
DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1;
- if (TREE_CODE (type) == COMPLEX_TYPE
- || TREE_CODE (type) == VECTOR_TYPE)
- DECL_GIMPLE_REG_P (tmp_var) = 1;
info->new_local_var_chain = tmp_var;
return tmp_var;
}
+/* Like build_simple_mem_ref, but set TREE_THIS_NOTRAP on the result. */
+
+static tree
+build_simple_mem_ref_notrap (tree ptr)
+{
+ tree t = build_simple_mem_ref (ptr);
+ TREE_THIS_NOTRAP (t) = 1;
+ return t;
+}
+
/* Take the address of EXP to be used within function CONTEXT.
Mark it for addressability as necessary. */
{
tree field = get_chain_field (i);
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
x = init_tmp_var (info, x, gsi);
}
{
tree field = get_chain_field (i);
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
x = init_tmp_var (info, x, gsi);
}
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
}
x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
for (i = info->outer; i->context != target_context; i = i->outer)
{
field = get_chain_field (i);
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
}
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
}
field = lookup_field_for_decl (i, decl, INSERT);
x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
if (use_pointer_in_frame (decl))
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
/* ??? We should be remapping types as well, surely. */
new_decl = build_decl (DECL_SOURCE_LOCATION (decl),
if (use_pointer_in_frame (t))
{
x = init_tmp_var (info, x, &wi->gsi);
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
}
}
{
struct nesting_info *const info = (struct nesting_info *) wi->info;
bool need_chain = false, need_stmts = false;
- tree clause, decl;
+ tree clause, decl, *pdecl;
int dummy;
bitmap new_suppress;
for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause))
{
+ pdecl = NULL;
switch (OMP_CLAUSE_CODE (clause))
{
case OMP_CLAUSE_REDUCTION:
+ case OMP_CLAUSE_IN_REDUCTION:
+ case OMP_CLAUSE_TASK_REDUCTION:
if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
need_stmts = true;
+ if (TREE_CODE (OMP_CLAUSE_DECL (clause)) == MEM_REF)
+ {
+ pdecl = &TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0);
+ if (TREE_CODE (*pdecl) == POINTER_PLUS_EXPR)
+ pdecl = &TREE_OPERAND (*pdecl, 0);
+ if (TREE_CODE (*pdecl) == INDIRECT_REF
+ || TREE_CODE (*pdecl) == ADDR_EXPR)
+ pdecl = &TREE_OPERAND (*pdecl, 0);
+ }
goto do_decl_clause;
case OMP_CLAUSE_LASTPRIVATE:
case OMP_CLAUSE_TO_DECLARE:
case OMP_CLAUSE_LINK:
case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
case OMP_CLAUSE_IS_DEVICE_PTR:
do_decl_clause:
- decl = OMP_CLAUSE_DECL (clause);
+ if (pdecl == NULL)
+ pdecl = &OMP_CLAUSE_DECL (clause);
+ decl = *pdecl;
if (VAR_P (decl)
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
break;
if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_SHARED)
OMP_CLAUSE_SHARED_READONLY (clause) = 0;
bitmap_set_bit (new_suppress, DECL_UID (decl));
- OMP_CLAUSE_DECL (clause) = get_nonlocal_debug_decl (info, decl);
+ *pdecl = get_nonlocal_debug_decl (info, decl);
if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_PRIVATE)
need_chain = true;
}
case OMP_CLAUSE_THREADS:
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_DEFAULTMAP:
+ case OMP_CLAUSE_ORDER:
case OMP_CLAUSE_SEQ:
case OMP_CLAUSE_INDEPENDENT:
case OMP_CLAUSE_AUTO:
case OMP_CLAUSE_IF_PRESENT:
case OMP_CLAUSE_FINALIZE:
+ case OMP_CLAUSE__CONDTEMP_:
+ case OMP_CLAUSE__SCANTEMP_:
break;
/* The following clause belongs to the OpenACC cache directive, which
case OMP_CLAUSE__REDUCTEMP_:
case OMP_CLAUSE__SIMDUID_:
case OMP_CLAUSE__GRIDDIM_:
+ case OMP_CLAUSE__SIMT_:
/* Anything else. */
default:
gcc_unreachable ();
switch (OMP_CLAUSE_CODE (clause))
{
case OMP_CLAUSE_REDUCTION:
+ case OMP_CLAUSE_IN_REDUCTION:
+ case OMP_CLAUSE_TASK_REDUCTION:
if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
{
tree old_context
}
break;
+ case GIMPLE_OMP_TEAMS:
+ if (!gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
+ {
+ save_suppress = info->suppress_expansion;
+ convert_nonlocal_omp_clauses (gimple_omp_teams_clauses_ptr (stmt),
+ wi);
+ walk_body (convert_nonlocal_reference_stmt,
+ convert_nonlocal_reference_op, info,
+ gimple_omp_body_ptr (stmt));
+ info->suppress_expansion = save_suppress;
+ break;
+ }
+ /* FALLTHRU */
+
case GIMPLE_OMP_PARALLEL:
case GIMPLE_OMP_TASK:
save_suppress = info->suppress_expansion;
info->suppress_expansion = save_suppress;
break;
+ case GIMPLE_OMP_TASKGROUP:
+ save_suppress = info->suppress_expansion;
+ convert_nonlocal_omp_clauses (gimple_omp_taskgroup_clauses_ptr (stmt), wi);
+ walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
+ info, gimple_omp_body_ptr (stmt));
+ info->suppress_expansion = save_suppress;
+ break;
+
case GIMPLE_OMP_TARGET:
if (!is_gimple_omp_offloaded (stmt))
{
info->suppress_expansion = save_suppress;
break;
- case GIMPLE_OMP_TEAMS:
- save_suppress = info->suppress_expansion;
- convert_nonlocal_omp_clauses (gimple_omp_teams_clauses_ptr (stmt), wi);
- walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
- info, gimple_omp_body_ptr (stmt));
- info->suppress_expansion = save_suppress;
- break;
-
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_MASTER:
- case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_SCAN:
walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
info, gimple_omp_body_ptr (stmt));
break;
*handled_ops_p = false;
return NULL_TREE;
+ case GIMPLE_ASSIGN:
+ if (gimple_clobber_p (stmt))
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+ if (DECL_P (lhs)
+ && !(TREE_STATIC (lhs) || DECL_EXTERNAL (lhs))
+ && decl_function_context (lhs) != info->context)
+ {
+ gsi_replace (gsi, gimple_build_nop (), true);
+ break;
+ }
+ }
+ *handled_ops_p = false;
+ return NULL_TREE;
+
default:
/* For every other statement that we are not interested in
handling here, let the walker traverse the operands. */
{
struct nesting_info *const info = (struct nesting_info *) wi->info;
bool need_frame = false, need_stmts = false;
- tree clause, decl;
+ tree clause, decl, *pdecl;
int dummy;
bitmap new_suppress;
for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause))
{
+ pdecl = NULL;
switch (OMP_CLAUSE_CODE (clause))
{
case OMP_CLAUSE_REDUCTION:
+ case OMP_CLAUSE_IN_REDUCTION:
+ case OMP_CLAUSE_TASK_REDUCTION:
if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
need_stmts = true;
+ if (TREE_CODE (OMP_CLAUSE_DECL (clause)) == MEM_REF)
+ {
+ pdecl = &TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0);
+ if (TREE_CODE (*pdecl) == POINTER_PLUS_EXPR)
+ pdecl = &TREE_OPERAND (*pdecl, 0);
+ if (TREE_CODE (*pdecl) == INDIRECT_REF
+ || TREE_CODE (*pdecl) == ADDR_EXPR)
+ pdecl = &TREE_OPERAND (*pdecl, 0);
+ }
goto do_decl_clause;
case OMP_CLAUSE_LASTPRIVATE:
case OMP_CLAUSE_TO_DECLARE:
case OMP_CLAUSE_LINK:
case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
case OMP_CLAUSE_IS_DEVICE_PTR:
do_decl_clause:
- decl = OMP_CLAUSE_DECL (clause);
+ if (pdecl == NULL)
+ pdecl = &OMP_CLAUSE_DECL (clause);
+ decl = *pdecl;
if (VAR_P (decl)
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
break;
if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_SHARED)
OMP_CLAUSE_SHARED_READONLY (clause) = 0;
bitmap_set_bit (new_suppress, DECL_UID (decl));
- OMP_CLAUSE_DECL (clause)
- = get_local_debug_decl (info, decl, field);
+ *pdecl = get_local_debug_decl (info, decl, field);
need_frame = true;
}
}
case OMP_CLAUSE_THREADS:
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_DEFAULTMAP:
+ case OMP_CLAUSE_ORDER:
case OMP_CLAUSE_SEQ:
case OMP_CLAUSE_INDEPENDENT:
case OMP_CLAUSE_AUTO:
case OMP_CLAUSE_IF_PRESENT:
case OMP_CLAUSE_FINALIZE:
+ case OMP_CLAUSE__CONDTEMP_:
+ case OMP_CLAUSE__SCANTEMP_:
break;
/* The following clause belongs to the OpenACC cache directive, which
case OMP_CLAUSE__REDUCTEMP_:
case OMP_CLAUSE__SIMDUID_:
case OMP_CLAUSE__GRIDDIM_:
+ case OMP_CLAUSE__SIMT_:
/* Anything else. */
default:
gcc_unreachable ();
switch (OMP_CLAUSE_CODE (clause))
{
case OMP_CLAUSE_REDUCTION:
+ case OMP_CLAUSE_IN_REDUCTION:
+ case OMP_CLAUSE_TASK_REDUCTION:
if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
{
tree old_context
switch (gimple_code (stmt))
{
+ case GIMPLE_OMP_TEAMS:
+ if (!gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
+ {
+ save_suppress = info->suppress_expansion;
+ convert_local_omp_clauses (gimple_omp_teams_clauses_ptr (stmt), wi);
+ walk_body (convert_local_reference_stmt, convert_local_reference_op,
+ info, gimple_omp_body_ptr (stmt));
+ info->suppress_expansion = save_suppress;
+ break;
+ }
+ /* FALLTHRU */
+
case GIMPLE_OMP_PARALLEL:
case GIMPLE_OMP_TASK:
save_suppress = info->suppress_expansion;
info->suppress_expansion = save_suppress;
break;
+ case GIMPLE_OMP_TASKGROUP:
+ save_suppress = info->suppress_expansion;
+ convert_local_omp_clauses (gimple_omp_taskgroup_clauses_ptr (stmt), wi);
+ walk_body (convert_local_reference_stmt, convert_local_reference_op,
+ info, gimple_omp_body_ptr (stmt));
+ info->suppress_expansion = save_suppress;
+ break;
+
case GIMPLE_OMP_TARGET:
if (!is_gimple_omp_offloaded (stmt))
{
info->static_chain_added |= save_static_chain_added;
break;
- case GIMPLE_OMP_TEAMS:
- save_suppress = info->suppress_expansion;
- convert_local_omp_clauses (gimple_omp_teams_clauses_ptr (stmt), wi);
- walk_body (convert_local_reference_stmt, convert_local_reference_op,
- info, gimple_omp_body_ptr (stmt));
- info->suppress_expansion = save_suppress;
- break;
-
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_MASTER:
- case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_SCAN:
walk_body (convert_local_reference_stmt, convert_local_reference_op,
info, gimple_omp_body_ptr (stmt));
break;
if (gimple_clobber_p (stmt))
{
tree lhs = gimple_assign_lhs (stmt);
- if (!use_pointer_in_frame (lhs)
+ if (DECL_P (lhs)
+ && !use_pointer_in_frame (lhs)
&& lookup_field_for_decl (info, lhs, NO_INSERT))
{
gsi_replace (gsi, gimple_build_nop (), true);
break;
}
+ case GIMPLE_OMP_TEAMS:
+ if (!gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
+ {
+ *handled_ops_p = false;
+ return NULL_TREE;
+ }
+ goto do_parallel;
+
case GIMPLE_OMP_TARGET:
if (!is_gimple_omp_offloaded (stmt))
{
/* FALLTHRU */
case GIMPLE_OMP_PARALLEL:
case GIMPLE_OMP_TASK:
+ do_parallel:
{
tree save_local_var_chain = info->new_local_var_chain;
walk_gimple_op (stmt, convert_tramp_reference_op, wi);
}
break;
+ case GIMPLE_OMP_TEAMS:
+ if (!gimple_omp_teams_host (as_a <gomp_teams *> (stmt)))
+ {
+ walk_body (convert_gimple_call, NULL, info,
+ gimple_omp_body_ptr (stmt));
+ break;
+ }
+ /* FALLTHRU */
+
case GIMPLE_OMP_PARALLEL:
case GIMPLE_OMP_TASK:
save_static_chain_added = info->static_chain_added;
case GIMPLE_OMP_SECTIONS:
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_SINGLE:
- case GIMPLE_OMP_TEAMS:
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_SCAN:
case GIMPLE_OMP_CRITICAL:
walk_body (convert_gimple_call, NULL, info, gimple_omp_body_ptr (stmt));
break;