+2016-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/69183
+ * omp-low.c (build_outer_var_ref): Change lastprivate argument
+ to code, pass it recursively, adjust uses. For OMP_CLAUSE_PRIVATE
+ on worksharing constructs, treat it like clauses on simd construct.
+ Formatting fix.
+ (lower_rec_input_clauses): For OMP_CLAUSE_PRIVATE_OUTER_REF pass
+ OMP_CLAUSE_PRIVATE as last argument to build_outer_var_ref.
+ (lower_lastprivate_clauses): Pass OMP_CLAUSE_LASTPRIVATE instead
+ of true as last argument to build_outer_var_ref.
+
2016-11-23 Uros Bizjak <ubizjak@gmail.com>
- * gcc.target/config/i386.md (*movqi_internal): Calculate mode
+ * config/i386/i386.md (*movqi_internal): Calculate mode
attribute of alternatives 7,8,9 depending on TARGET_AVX512DQ.
<TYPE_MSKMOV>: Emit kmovw for MODE_HI insn mode attribute.
(*k<logic><mode>): Calculate mode attribute depending on
this is some variable. */
static tree
-build_outer_var_ref (tree var, omp_context *ctx, bool lastprivate = false)
+build_outer_var_ref (tree var, omp_context *ctx,
+ enum omp_clause_code code = OMP_CLAUSE_ERROR)
{
tree x;
else if (is_variable_sized (var))
{
x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
- x = build_outer_var_ref (x, ctx, lastprivate);
+ 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_SIMD)
- {
- /* #pragma omp simd isn't a worksharing construct, and can reference even
- private vars in its linear etc. clauses. */
+ else if ((gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
+ || (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 (ctx->outer && is_taskreg_ctx (ctx))
x = lookup_decl (var, ctx->outer);
if (x == NULL_TREE)
x = var;
}
- else if (lastprivate && is_taskloop_ctx (ctx))
+ else if (code == OMP_CLAUSE_LASTPRIVATE && is_taskloop_ctx (ctx))
{
gcc_assert (ctx->outer);
splay_tree_node n
gcc_assert (outer
&& gimple_code (outer->stmt) != GIMPLE_OMP_GRID_BODY);
}
- x = lookup_decl (var, outer);
+ x = lookup_decl (var, outer);
}
else if (is_reference (var))
/* This can happen with orphaned constructs. If var is reference, it is
if (is_task_ctx (ctx))
x = build_receiver_ref (var, false, ctx);
else
- x = build_outer_var_ref (var, ctx);
+ x = build_outer_var_ref (var, ctx, OMP_CLAUSE_PRIVATE);
}
else
x = NULL;
x = ovar;
}
if (!x)
- x = build_outer_var_ref (var, ctx, true);
+ x = build_outer_var_ref (var, ctx, OMP_CLAUSE_LASTPRIVATE);
if (is_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);