openmp: Add support for non-VLA {,first}private allocate on omp task
This patch adds support for custom allocators on private/firstprivate clauses for task (and taskloop) constructs. Private didn't need anything special, but firstprivate if it is passed by reference needs the GOMP_alloc calls in the copyfn and GOMP_free in the task body. 2020-11-14 Jakub Jelinek <jakub@redhat.com> * gimplify.c (gimplify_omp_for): Add OMP_CLAUSE_ALLOCATE_ALLOCATOR decls as firstprivate on task clauses even when allocate clause decl is not lastprivate. * omp-low.c (install_var_field): Don't dereference omp_is_reference types if mask is 33 rather than 1. (scan_sharing_clauses): Populate allocate_map even for task constructs. For now remove it back for variables mentioned in reduction and in_reduction clauses on task/taskloop constructs or on VLA task firstprivates. For firstprivate on task construct, install the var field into field_map with by_ref and 33 instead of false and 1 if mentioned in allocate clause. (lower_private_allocate): Set TREE_THIS_NOTRAP on the created MEM_REF. (lower_rec_input_clauses): Handle allocate for task firstprivatized non-VLA variables. (create_task_copyfn): Likewise. * testsuite/libgomp.c-c++-common/allocate-1.c (struct S): New type. (foo): Add tests for non-VLA private and firstprivate clauses on omp task. (bar): Likewise. Remove taking of address from private/firstprivate variables. * testsuite/libgomp.c++/allocate-1.C (struct S): New type. (foo): Add p, q, px and s arguments. Add tests for array reductions and for non-VLA private and firstprivate clauses on omp task. (bar): Removed. (main): Adjust foo caller. Don't call bar.
This commit is contained in:
parent
77f67db2a4
commit
a4dd85e015
|
@ -12463,22 +12463,22 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
|
|||
/* Allocate clause we duplicate on task and inner taskloop
|
||||
if the decl is lastprivate, otherwise just put on task. */
|
||||
case OMP_CLAUSE_ALLOCATE:
|
||||
if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
|
||||
&& DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
|
||||
{
|
||||
/* Additionally, put firstprivate clause on task
|
||||
for the allocator if it is not constant. */
|
||||
*gtask_clauses_ptr
|
||||
= build_omp_clause (OMP_CLAUSE_LOCATION (c),
|
||||
OMP_CLAUSE_FIRSTPRIVATE);
|
||||
OMP_CLAUSE_DECL (*gtask_clauses_ptr)
|
||||
= OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
|
||||
gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
|
||||
}
|
||||
if (lastprivate_uids
|
||||
&& bitmap_bit_p (lastprivate_uids,
|
||||
DECL_UID (OMP_CLAUSE_DECL (c))))
|
||||
{
|
||||
if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
|
||||
&& DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
|
||||
{
|
||||
/* Additionally, put firstprivate clause on task
|
||||
for the allocator if it is not constant. */
|
||||
*gtask_clauses_ptr
|
||||
= build_omp_clause (OMP_CLAUSE_LOCATION (c),
|
||||
OMP_CLAUSE_FIRSTPRIVATE);
|
||||
OMP_CLAUSE_DECL (*gtask_clauses_ptr)
|
||||
= OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
|
||||
gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
|
||||
}
|
||||
*gfor_clauses_ptr = c;
|
||||
gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
|
||||
*gtask_clauses_ptr = copy_node (c);
|
||||
|
|
110
gcc/omp-low.c
110
gcc/omp-low.c
|
@ -803,7 +803,7 @@ install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
|
|||
}
|
||||
else if (by_ref)
|
||||
type = build_pointer_type (type);
|
||||
else if ((mask & 3) == 1 && omp_is_reference (var))
|
||||
else if ((mask & (32 | 3)) == 1 && omp_is_reference (var))
|
||||
type = TREE_TYPE (type);
|
||||
|
||||
field = build_decl (DECL_SOURCE_LOCATION (var),
|
||||
|
@ -1141,8 +1141,6 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
|
|||
/* omp_default_mem_alloc is 1 */
|
||||
|| !integer_onep (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))))
|
||||
{
|
||||
if (is_task_ctx (ctx))
|
||||
continue; /* For now. */
|
||||
if (ctx->allocate_map == NULL)
|
||||
ctx->allocate_map = new hash_map<tree, tree>;
|
||||
ctx->allocate_map->put (OMP_CLAUSE_DECL (c),
|
||||
|
@ -1222,18 +1220,20 @@ scan_sharing_clauses (tree clauses, omp_context *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:
|
||||
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)))
|
||||
|| 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);
|
||||
|
@ -1317,7 +1317,16 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
|
|||
if (is_variable_sized (decl))
|
||||
{
|
||||
if (is_task_ctx (ctx))
|
||||
install_var_field (decl, false, 1, 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))
|
||||
|
@ -1329,7 +1338,11 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
|
|||
if (is_task_ctx (ctx)
|
||||
&& (global || by_ref || omp_is_reference (decl)))
|
||||
{
|
||||
install_var_field (decl, false, 1, ctx);
|
||||
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);
|
||||
}
|
||||
|
@ -4498,7 +4511,9 @@ lower_private_allocate (tree var, tree new_var, tree &allocator,
|
|||
gimple_seq_add_stmt (ilist, g);
|
||||
if (!is_ref)
|
||||
{
|
||||
SET_DECL_VALUE_EXPR (new_var, build_simple_mem_ref (allocate_ptr));
|
||||
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;
|
||||
|
@ -5409,7 +5424,18 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
|||
if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
|
||||
{
|
||||
x = build_receiver_ref (var, false, ctx);
|
||||
x = build_fold_addr_expr_loc (clause_loc, x);
|
||||
if (ctx->allocate_map)
|
||||
if (tree *allocatep = ctx->allocate_map->get (var))
|
||||
{
|
||||
allocator = *allocatep;
|
||||
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,
|
||||
|
@ -5676,6 +5702,18 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
|||
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);
|
||||
|
@ -5704,6 +5742,18 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
|||
|| 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) != 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;
|
||||
|
@ -11290,7 +11340,35 @@ create_task_copyfn (gomp_task *task_stmt, omp_context *ctx)
|
|||
if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
|
||||
t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
|
||||
else
|
||||
t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
|
||||
{
|
||||
if (ctx->allocate_map)
|
||||
if (tree *allocatorp = ctx->allocate_map->get (decl))
|
||||
{
|
||||
tree allocator = *allocatorp;
|
||||
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,
|
||||
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:
|
||||
|
|
|
@ -2,17 +2,26 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct S { int a, b; };
|
||||
|
||||
void
|
||||
foo (int &x, int &y, int &r, int &l, int (&l2)[4], int &l3, int &n, omp_allocator_handle_t h, int fl)
|
||||
foo (int &x, int &y, int &r, int &l, int (&l2)[4], int &l3, int &n, int *&p,
|
||||
int *&q, int &px, struct S &s, omp_allocator_handle_t h, int fl)
|
||||
{
|
||||
int i;
|
||||
typedef int T[x];
|
||||
T v, w;
|
||||
T &v2 = v;
|
||||
T &w2 = w;
|
||||
int r1[4] = { 0, 0, 0, 0 };
|
||||
int (&r2)[4] = r1;
|
||||
int xo = x;
|
||||
for (i = 0; i < x; i++)
|
||||
w[i] = i;
|
||||
for (i = 0; i < 4; i++)
|
||||
p[i] = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
q[i] = 0;
|
||||
#pragma omp parallel private (y, v2) firstprivate (x) allocate (x, y, v2)
|
||||
{
|
||||
int *volatile p1 = &x;
|
||||
|
@ -66,6 +75,7 @@ foo (int &x, int &y, int &r, int &l, int (&l2)[4], int &l3, int &n, omp_allocato
|
|||
| (uintptr_t) &l | (uintptr_t) &n) & 63) != 0)
|
||||
abort ();
|
||||
}
|
||||
x = xo;
|
||||
#pragma omp parallel
|
||||
{
|
||||
#pragma omp for lastprivate (l2) allocate (h: l2, l3) lastprivate (conditional: l3)
|
||||
|
@ -80,84 +90,86 @@ foo (int &x, int &y, int &r, int &l, int (&l2)[4], int &l3, int &n, omp_allocato
|
|||
if ((fl & 1) && (((uintptr_t) &l2[0] | (uintptr_t) &l3) & 63) != 0)
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
if (r != 64 * 63 / 2 || l != 63 || n != 8 + 16 * 64)
|
||||
abort ();
|
||||
if (l2[0] != 63 || l2[1] != 63 + 1 || l2[2] != 63 + 2 || l2[3] != 63 + 3 || l3 != 36)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void
|
||||
bar (int &x, int &y, int &r, int &l, int (&l2)[4], int &l3, int &n, omp_allocator_handle_t h)
|
||||
{
|
||||
int i;
|
||||
typedef int T[x];
|
||||
T v, w;
|
||||
T &v2 = v;
|
||||
T &w2 = w;
|
||||
int xo = x;
|
||||
for (i = 0; i < x; i++)
|
||||
w[i] = i;
|
||||
#pragma omp parallel private (y, v2) firstprivate (x) allocate (x, y, v2)
|
||||
{
|
||||
int *volatile p1 = &x;
|
||||
int *volatile p2 = &y;
|
||||
if (x != 42)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
*p2 = 1;
|
||||
p1[0]++;
|
||||
v2[0] = 7;
|
||||
v2[41] = 8;
|
||||
#pragma omp barrier
|
||||
if (x != 43 || y != 1)
|
||||
abort ();
|
||||
if (v2[0] != 7 || v2[41] != 8)
|
||||
abort ();
|
||||
}
|
||||
x = xo;
|
||||
#pragma omp teams
|
||||
#pragma omp parallel private (y) firstprivate (x, w2) allocate (h: x, y, w2)
|
||||
{
|
||||
int *volatile p1 = &x;
|
||||
int *volatile p2 = &y;
|
||||
if (x != 42 || w2[17] != 17 || w2[41] != 41)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
*p2 = 1;
|
||||
p1[0]++;
|
||||
#pragma omp barrier
|
||||
if (x != 43 || y != 1)
|
||||
abort ();
|
||||
}
|
||||
x = xo;
|
||||
#pragma omp parallel for private (y) firstprivate (x) allocate (h: x, y, r, l, n) reduction(+: r) lastprivate (l) linear (n: 16)
|
||||
for (i = 0; i < 64; i++)
|
||||
#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 ();
|
||||
}
|
||||
#pragma omp task private(y) firstprivate(x) allocate(x, y)
|
||||
{
|
||||
int *volatile p1 = &x;
|
||||
int *volatile p2 = &y;
|
||||
if (x != 42)
|
||||
abort ();
|
||||
y = 1;
|
||||
l = i;
|
||||
n += y + 15;
|
||||
r += i;
|
||||
p1[0]++;
|
||||
p2[0] = 21;
|
||||
if (x != 43 || y != 21)
|
||||
abort ();
|
||||
if ((fl & 2) && (((uintptr_t) p1 | (uintptr_t) p2) & 63) != 0)
|
||||
abort ();
|
||||
}
|
||||
#pragma omp task private(y) firstprivate(x) allocate(h: x, y)
|
||||
{
|
||||
int *volatile p1 = &x;
|
||||
int *volatile p2 = &y;
|
||||
if (x != 42)
|
||||
abort ();
|
||||
p1[0]++;
|
||||
p2[0] = 21;
|
||||
if (x != 43 || y != 21)
|
||||
abort ();
|
||||
if ((fl & 1) && (((uintptr_t) p1 | (uintptr_t) p2) & 63) != 0)
|
||||
abort ();
|
||||
}
|
||||
#pragma omp task private(y) firstprivate(s) allocate(s, y)
|
||||
{
|
||||
int *volatile p1 = &s.a;
|
||||
int *volatile p2 = &s.b;
|
||||
int *volatile p3 = &y;
|
||||
if (s.a != 27 || s.b != 29)
|
||||
abort ();
|
||||
p1[0]++;
|
||||
p2[0]++;
|
||||
p3[0] = 21;
|
||||
if (s.a != 28 || s.b != 30 || y != 21)
|
||||
abort ();
|
||||
if ((fl & 2) && (((uintptr_t) p1 | (uintptr_t) p3) & 63) != 0)
|
||||
abort ();
|
||||
}
|
||||
#pragma omp task private(y) firstprivate(s) allocate(h: s, y)
|
||||
{
|
||||
int *volatile p1 = &s.a;
|
||||
int *volatile p2 = &s.b;
|
||||
int *volatile p3 = &y;
|
||||
if (s.a != 27 || s.b != 29)
|
||||
abort ();
|
||||
p1[0]++;
|
||||
p2[0]++;
|
||||
p3[0] = 21;
|
||||
if (s.a != 28 || s.b != 30 || y != 21)
|
||||
abort ();
|
||||
if ((fl & 1) && (((uintptr_t) p1 | (uintptr_t) p3) & 63) != 0)
|
||||
abort ();
|
||||
}
|
||||
#pragma omp parallel
|
||||
{
|
||||
#pragma omp for lastprivate (l2) allocate (h: l2, l3) lastprivate (conditional: l3)
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
l2[0] = i;
|
||||
l2[1] = i + 1;
|
||||
l2[2] = i + 2;
|
||||
l2[3] = i + 3;
|
||||
if (i < 37)
|
||||
l3 = i;
|
||||
}
|
||||
}
|
||||
if (r != 64 * 63 / 2 || l != 63 || n != 8 + 16 * 64)
|
||||
abort ();
|
||||
if (l2[0] != 63 || l2[1] != 63 + 1 || l2[2] != 63 + 2 || l2[3] != 63 + 3 || l3 != 36)
|
||||
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 ();
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -171,24 +183,25 @@ main ()
|
|||
if (a == omp_null_allocator)
|
||||
abort ();
|
||||
omp_set_default_allocator (omp_default_mem_alloc);
|
||||
struct S s = { 27, 29 };
|
||||
int p1[4], q1[3], px = 2;
|
||||
int *p = p1;
|
||||
int *q = q1;
|
||||
int x = 42, y = 0, r = 0, l, l2[4], l3, n = 8;
|
||||
foo (x, y, r, l, l2, l3, n, omp_null_allocator, 0);
|
||||
foo (x, y, r, l, l2, l3, n, p, q, px, s, omp_null_allocator, 0);
|
||||
x = 42; y = 0; r = 0; l = -1; l2[0] = -1; l2[1] = -1;
|
||||
l2[2] = -1; l2[3] = -1; n = 8;
|
||||
foo (x, y, r, l, l2, l3, n, omp_default_mem_alloc, 0);
|
||||
foo (x, y, r, l, l2, l3, n, p, q, px, s, omp_default_mem_alloc, 0);
|
||||
x = 42; y = 0; r = 0; l = -1; l2[0] = -1; l2[1] = -1;
|
||||
l2[2] = -1; l2[3] = -1; n = 8;
|
||||
foo (x, y, r, l, l2, l3, n, a, 1);
|
||||
foo (x, y, r, l, l2, l3, n, p, q, px, s, a, 1);
|
||||
x = 42; y = 0; r = 0; l = -1; l2[0] = -1; l2[1] = -1;
|
||||
l2[2] = -1; l2[3] = -1; n = 8;
|
||||
omp_set_default_allocator (a);
|
||||
foo (x, y, r, l, l2, l3, n, omp_null_allocator, 3);
|
||||
foo (x, y, r, l, l2, l3, n, p, q, px, s, omp_null_allocator, 3);
|
||||
x = 42; y = 0; r = 0; l = -1; l2[0] = -1; l2[1] = -1;
|
||||
l2[2] = -1; l2[3] = -1; n = 8;
|
||||
foo (x, y, r, l, l2, l3, n, omp_default_mem_alloc, 2);
|
||||
x = 42; y = 0; r = 0; l = -1; l2[0] = -1; l2[1] = -1;
|
||||
l2[2] = -1; l2[3] = -1; n = 8;
|
||||
bar (x, y, r, l, l2, l3, n, a);
|
||||
foo (x, y, r, l, l2, l3, n, p, q, px, s, omp_default_mem_alloc, 2);
|
||||
omp_destroy_allocator (a);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct S { int a, b; };
|
||||
|
||||
void
|
||||
foo (int x, int *p, int *q, int px, omp_allocator_handle_t h, int fl)
|
||||
{
|
||||
|
@ -13,6 +15,7 @@ foo (int x, int *p, int *q, int px, omp_allocator_handle_t h, int fl)
|
|||
int v[x], w[x];
|
||||
int r2[4] = { 0, 0, 0, 0 };
|
||||
int xo = x;
|
||||
struct S s = { 27, 29 };
|
||||
for (i = 0; i < 4; i++)
|
||||
p[i] = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
|
@ -72,6 +75,7 @@ foo (int x, int *p, int *q, int px, omp_allocator_handle_t h, int fl)
|
|||
| (uintptr_t) &l | (uintptr_t) &n) & 63) != 0)
|
||||
abort ();
|
||||
}
|
||||
x = xo;
|
||||
#pragma omp parallel
|
||||
{
|
||||
#pragma omp for lastprivate (l2) private (i1) allocate (h: l2, l3, i1) lastprivate (conditional: l3)
|
||||
|
@ -137,6 +141,62 @@ foo (int x, int *p, int *q, int px, omp_allocator_handle_t h, int fl)
|
|||
if ((fl & 1) && (((uintptr_t) &q[0] | (uintptr_t) &r2[0]) & 63) != 0)
|
||||
abort ();
|
||||
}
|
||||
#pragma omp task private(y) firstprivate(x) allocate(x, y)
|
||||
{
|
||||
int *volatile p1 = &x;
|
||||
int *volatile p2 = &y;
|
||||
if (x != 42)
|
||||
abort ();
|
||||
p1[0]++;
|
||||
p2[0] = 21;
|
||||
if (x != 43 || y != 21)
|
||||
abort ();
|
||||
if ((fl & 2) && (((uintptr_t) p1 | (uintptr_t) p2) & 63) != 0)
|
||||
abort ();
|
||||
}
|
||||
#pragma omp task private(y) firstprivate(x) allocate(h: x, y)
|
||||
{
|
||||
int *volatile p1 = &x;
|
||||
int *volatile p2 = &y;
|
||||
if (x != 42)
|
||||
abort ();
|
||||
p1[0]++;
|
||||
p2[0] = 21;
|
||||
if (x != 43 || y != 21)
|
||||
abort ();
|
||||
if ((fl & 1) && (((uintptr_t) p1 | (uintptr_t) p2) & 63) != 0)
|
||||
abort ();
|
||||
}
|
||||
#pragma omp task private(y) firstprivate(s) allocate(s, y)
|
||||
{
|
||||
int *volatile p1 = &s.a;
|
||||
int *volatile p2 = &s.b;
|
||||
int *volatile p3 = &y;
|
||||
if (s.a != 27 || s.b != 29)
|
||||
abort ();
|
||||
p1[0]++;
|
||||
p2[0]++;
|
||||
p3[0] = 21;
|
||||
if (s.a != 28 || s.b != 30 || y != 21)
|
||||
abort ();
|
||||
if ((fl & 2) && (((uintptr_t) p1 | (uintptr_t) p3) & 63) != 0)
|
||||
abort ();
|
||||
}
|
||||
#pragma omp task private(y) firstprivate(s) allocate(h: s, y)
|
||||
{
|
||||
int *volatile p1 = &s.a;
|
||||
int *volatile p2 = &s.b;
|
||||
int *volatile p3 = &y;
|
||||
if (s.a != 27 || s.b != 29)
|
||||
abort ();
|
||||
p1[0]++;
|
||||
p2[0]++;
|
||||
p3[0] = 21;
|
||||
if (s.a != 28 || s.b != 30 || y != 21)
|
||||
abort ();
|
||||
if ((fl & 1) && (((uintptr_t) p1 | (uintptr_t) p3) & 63) != 0)
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
if (r != 64 * 63 / 2 || l != 63 || n != 8 + 16 * 64)
|
||||
abort ();
|
||||
|
@ -164,16 +224,15 @@ bar (int x, omp_allocator_handle_t h)
|
|||
int i3, j3, n3 = 10, l5;
|
||||
int i4, j4, n4 = 11, l6;
|
||||
int i5;
|
||||
struct S s = { 27, 29 };
|
||||
int xo = x;
|
||||
#pragma omp parallel private (y) firstprivate (x) allocate (x, y)
|
||||
{
|
||||
int *volatile p1 = &x;
|
||||
int *volatile p2 = &y;
|
||||
if (x != 42)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
*p2 = 1;
|
||||
p1[0]++;
|
||||
y = 1;
|
||||
x++;
|
||||
#pragma omp barrier
|
||||
if (x != 43 || y != 1)
|
||||
abort ();
|
||||
|
@ -182,13 +241,11 @@ bar (int x, omp_allocator_handle_t h)
|
|||
#pragma omp teams
|
||||
#pragma omp parallel private (y) firstprivate (x) allocate (h: x, y)
|
||||
{
|
||||
int *volatile p1 = &x;
|
||||
int *volatile p2 = &y;
|
||||
if (x != 42)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
*p2 = 1;
|
||||
p1[0]++;
|
||||
y = 1;
|
||||
x++;
|
||||
#pragma omp barrier
|
||||
if (x != 43 || y != 1)
|
||||
abort ();
|
||||
|
@ -204,6 +261,7 @@ bar (int x, omp_allocator_handle_t h)
|
|||
n += y + 15;
|
||||
r += i;
|
||||
}
|
||||
x = xo;
|
||||
#pragma omp parallel
|
||||
{
|
||||
#pragma omp for lastprivate (l2) private (i1) allocate (h: l2, l3, i1) lastprivate (conditional: l3)
|
||||
|
@ -240,6 +298,44 @@ bar (int x, omp_allocator_handle_t h)
|
|||
#pragma omp for lastprivate (i5) allocate (i5)
|
||||
for (i5 = 1; i5 < 17; i5 += 3)
|
||||
;
|
||||
#pragma omp task private(y) firstprivate(x) allocate(x, y)
|
||||
{
|
||||
if (x != 42)
|
||||
abort ();
|
||||
x++;
|
||||
y = 21;
|
||||
if (x != 43 || y != 21)
|
||||
abort ();
|
||||
}
|
||||
#pragma omp task private(y) firstprivate(x) allocate(h: x, y)
|
||||
{
|
||||
if (x != 42)
|
||||
abort ();
|
||||
x++;
|
||||
y = 21;
|
||||
if (x != 43 || y != 21)
|
||||
abort ();
|
||||
}
|
||||
#pragma omp task private(y) firstprivate(s) allocate(s, y)
|
||||
{
|
||||
if (s.a != 27 || s.b != 29)
|
||||
abort ();
|
||||
s.a++;
|
||||
s.b++;
|
||||
y = 21;
|
||||
if (s.a != 28 || s.b != 30 || y != 21)
|
||||
abort ();
|
||||
}
|
||||
#pragma omp task private(y) firstprivate(s) allocate(h: s, y)
|
||||
{
|
||||
if (s.a != 27 || s.b != 29)
|
||||
abort ();
|
||||
s.a++;
|
||||
s.b++;
|
||||
y = 21;
|
||||
if (s.a != 28 || s.b != 30 || y != 21)
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
if (r != 64 * 63 / 2 || l != 63 || n != 8 + 16 * 64)
|
||||
abort ();
|
||||
|
|
Loading…
Reference in New Issue