aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/c/c-typeck.c3
-rw-r--r--gcc/omp-low.c72
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/allocate-1.c37
3 files changed, 86 insertions, 26 deletions
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index df1dad4..26a5f71 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -15199,7 +15199,8 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
OMP_CLAUSE_LINEAR_STEP (c));
remove = true;
}
- else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+ && reduction_seen == -2)
OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
if (remove)
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index ed805e2..eec3481 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -1197,6 +1197,14 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
if (is_oacc_parallel_or_serial (ctx) || is_oacc_kernels (ctx))
ctx->local_reduction_clauses
= tree_cons (NULL, c, ctx->local_reduction_clauses);
+ if ((OMP_CLAUSE_REDUCTION_INSCAN (c)
+ || OMP_CLAUSE_REDUCTION_TASK (c)) && ctx->allocate_map)
+ {
+ tree decl = OMP_CLAUSE_DECL (c);
+ /* For now. */
+ if (ctx->allocate_map->get (decl))
+ ctx->allocate_map->remove (decl);
+ }
/* FALLTHRU */
case OMP_CLAUSE_IN_REDUCTION:
@@ -4392,13 +4400,17 @@ lower_private_allocate (tree var, tree new_var, tree &allocator,
if (allocator)
return false;
gcc_assert (allocate_ptr == NULL_TREE);
- if (ctx->allocate_map && DECL_P (new_var))
+ 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_is_reference (var))
- return false;
+ {
+ allocator = NULL_TREE;
+ return false;
+ }
if (TREE_CODE (allocator) != INTEGER_CST)
allocator = build_outer_var_ref (allocator, ctx);
@@ -4410,19 +4422,24 @@ lower_private_allocate (tree var, tree new_var, tree &allocator,
allocator = var;
}
- tree ptr_type, align, sz;
- if (is_ref)
+ tree ptr_type, align, sz = size;
+ if (TYPE_P (new_var))
+ {
+ ptr_type = build_pointer_type (new_var);
+ align = build_int_cst (size_type_node, TYPE_ALIGN_UNIT (new_var));
+ }
+ else if (is_ref)
{
ptr_type = build_pointer_type (TREE_TYPE (TREE_TYPE (new_var)));
align = build_int_cst (size_type_node,
TYPE_ALIGN_UNIT (TREE_TYPE (ptr_type)));
- sz = size;
}
else
{
ptr_type = build_pointer_type (TREE_TYPE (new_var));
align = build_int_cst (size_type_node, DECL_ALIGN_UNIT (new_var));
- sz = fold_convert (size_type_node, DECL_SIZE_UNIT (new_var));
+ if (sz == NULL_TREE)
+ sz = fold_convert (size_type_node, DECL_SIZE_UNIT (new_var));
}
if (TREE_CODE (sz) != INTEGER_CST)
{
@@ -4855,7 +4872,23 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
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 = 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);
@@ -4913,6 +4946,13 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
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);
@@ -4924,20 +4964,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
{
tree atmp
= builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
- tree 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)));
tree al = size_int (TYPE_ALIGN (TREE_TYPE (type)));
- x = build_call_expr_loc (clause_loc, atmp, 2, t, al);
+ x = build_call_expr_loc (clause_loc, atmp, 2, sz, al);
}
tree ptype = build_pointer_type (TREE_TYPE (type));
@@ -5199,6 +5227,12 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
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)
diff --git a/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c b/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c
index 532795f..5dd51b5 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c
@@ -3,7 +3,7 @@
#include <stdint.h>
void
-foo (int x, omp_allocator_handle_t h, int fl)
+foo (int x, int *p, int *q, int px, omp_allocator_handle_t h, int fl)
{
int y = 0, r = 0, i, i1, l, l2[4], l3, n = 8;
int i2, j2, n2 = 9, l4;
@@ -11,7 +11,12 @@ foo (int x, omp_allocator_handle_t h, int fl)
int i4, j4, n4 = 11, l6;
int i5;
int v[x], w[x];
+ int r2[4] = { 0, 0, 0, 0 };
int xo = x;
+ for (i = 0; i < 4; i++)
+ p[i] = 0;
+ for (i = 0; i < 3; i++)
+ q[i] = 0;
for (i = 0; i < x; i++)
w[i] = i;
#pragma omp parallel private (y, v) firstprivate (x) allocate (x, y, v)
@@ -117,6 +122,21 @@ foo (int x, omp_allocator_handle_t h, int fl)
if ((fl & 2) && (((uintptr_t) &i5) & 63) != 0)
abort ();
}
+ #pragma omp for reduction(+:p[2:px], q[:3], r2) allocate(h: p, q, r2)
+ for (i = 0; i < 32; i++)
+ {
+ p[2] += i;
+ p[3] += 2 * i;
+ q[0] += 3 * i;
+ q[2] += 4 * i;
+ r2[0] += 5 * i;
+ r2[3] += 6 * i;
+ /* Can't really rely on alignment of &p[0], the implementation could
+ allocate the whole array or do what GCC does and allocate only part
+ of it. */
+ if ((fl & 1) && (((uintptr_t) &q[0] | (uintptr_t) &r2[0]) & 63) != 0)
+ abort ();
+ }
}
if (r != 64 * 63 / 2 || l != 63 || n != 8 + 16 * 64)
abort ();
@@ -130,6 +150,10 @@ foo (int x, omp_allocator_handle_t h, int fl)
abort ();
if (i5 != 19)
abort ();
+ if (p[2] != (32 * 31) / 2 || p[3] != 2 * (32 * 31) / 2
+ || q[0] != 3 * (32 * 31) / 2 || q[2] != 4 * (32 * 31) / 2
+ || r2[0] != 5 * (32 * 31) / 2 || r2[3] != 6 * (32 * 31) / 2)
+ abort ();
}
void
@@ -239,15 +263,16 @@ main ()
{ omp_atk_fallback, omp_atv_null_fb } };
omp_allocator_handle_t a
= omp_init_allocator (omp_default_mem_space, 2, traits);
+ int p[4], q[3];
if (a == omp_null_allocator)
abort ();
omp_set_default_allocator (omp_default_mem_alloc);
- foo (42, omp_null_allocator, 0);
- foo (42, omp_default_mem_alloc, 0);
- foo (42, a, 1);
+ foo (42, p, q, 2, omp_null_allocator, 0);
+ foo (42, p, q, 2, omp_default_mem_alloc, 0);
+ foo (42, p, q, 2, a, 1);
omp_set_default_allocator (a);
- foo (42, omp_null_allocator, 3);
- foo (42, omp_default_mem_alloc, 2);
+ foo (42, p, q, 2, omp_null_allocator, 3);
+ foo (42, p, q, 2, omp_default_mem_alloc, 2);
bar (42, a);
omp_destroy_allocator (a);
return 0;