/* 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);
}
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),
/* 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),
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);
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))
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);
}
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;
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,
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);
|| 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;
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:
#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;
| (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)
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
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;
}
#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)
{
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++)
| (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)
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 ();
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 ();
#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 ();
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)
#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 ();