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:
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);
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)
{
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);
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);
{
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));
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)
#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;
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)
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 ();
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
{ 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;