diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-11-14 01:46:16 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-11-14 01:46:16 +0100 |
commit | a4dd85e01599890286d9af5b106a1ab20e51169e (patch) | |
tree | 3ea1bdeca840ecb5e7708bb78903693eeae47cf8 | |
parent | 77f67db2a4709388b905397421bd3a851fbbf884 (diff) | |
download | gcc-a4dd85e01599890286d9af5b106a1ab20e51169e.zip gcc-a4dd85e01599890286d9af5b106a1ab20e51169e.tar.gz gcc-a4dd85e01599890286d9af5b106a1ab20e51169e.tar.bz2 |
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.
-rw-r--r-- | gcc/gimplify.c | 24 | ||||
-rw-r--r-- | gcc/omp-low.c | 108 | ||||
-rw-r--r-- | libgomp/testsuite/libgomp.c++/allocate-1.C | 169 | ||||
-rw-r--r-- | libgomp/testsuite/libgomp.c-c++-common/allocate-1.c | 112 |
4 files changed, 300 insertions, 113 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index b861e17..2566ec7 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -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); diff --git a/gcc/omp-low.c b/gcc/omp-low.c index a1604e0..09a8cbd 100644 --- a/gcc/omp-low.c +++ b/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) + /* 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))) { - 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 (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: diff --git a/libgomp/testsuite/libgomp.c++/allocate-1.C b/libgomp/testsuite/libgomp.c++/allocate-1.C index ee89f31..0876719 100644 --- a/libgomp/testsuite/libgomp.c++/allocate-1.C +++ b/libgomp/testsuite/libgomp.c++/allocate-1.C @@ -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); - 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); + 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; - 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; } diff --git a/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c b/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c index 5dd51b5..4398ff9 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c +++ b/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c @@ -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 (); |