Skip to content

Commit 67100cb

Browse files
committed
openmp: Support allocate for C/C++ array section reductions
This adds allocate clause support for array section reductions. Furthermore, it fixes one bug that would cause inscan reductions with allocate to be rejected by C, and for now just ignores allocate for inscan/task reductions, that will need slightly more work. 2020-11-13 Jakub Jelinek <[email protected]> gcc/ * omp-low.c (scan_sharing_clauses): For now remove for reduction clauses with inscan or task modifiers decl from allocate_map. (lower_private_allocate): Handle TYPE_P (new_var). (lower_rec_input_clauses): Handle allocate clause for C/C++ array reductions. gcc/c/ * c-typeck.c (c_finish_omp_clauses): Don't clear OMP_CLAUSE_REDUCTION_INSCAN unless reduction_seen == -2. libgomp/ * testsuite/libgomp.c-c++-common/allocate-1.c (foo): Add tests for array reductions. (main): Adjust foo callers.
1 parent 2e97d64 commit 67100cb

File tree

3 files changed

+86
-26
lines changed

3 files changed

+86
-26
lines changed

gcc/c/c-typeck.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15199,7 +15199,8 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
1519915199
OMP_CLAUSE_LINEAR_STEP (c));
1520015200
remove = true;
1520115201
}
15202-
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
15202+
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
15203+
&& reduction_seen == -2)
1520315204
OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
1520415205

1520515206
if (remove)

gcc/omp-low.c

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,14 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
11971197
if (is_oacc_parallel_or_serial (ctx) || is_oacc_kernels (ctx))
11981198
ctx->local_reduction_clauses
11991199
= tree_cons (NULL, c, ctx->local_reduction_clauses);
1200+
if ((OMP_CLAUSE_REDUCTION_INSCAN (c)
1201+
|| OMP_CLAUSE_REDUCTION_TASK (c)) && ctx->allocate_map)
1202+
{
1203+
tree decl = OMP_CLAUSE_DECL (c);
1204+
/* For now. */
1205+
if (ctx->allocate_map->get (decl))
1206+
ctx->allocate_map->remove (decl);
1207+
}
12001208
/* FALLTHRU */
12011209

12021210
case OMP_CLAUSE_IN_REDUCTION:
@@ -4392,13 +4400,17 @@ lower_private_allocate (tree var, tree new_var, tree &allocator,
43924400
if (allocator)
43934401
return false;
43944402
gcc_assert (allocate_ptr == NULL_TREE);
4395-
if (ctx->allocate_map && DECL_P (new_var))
4403+
if (ctx->allocate_map
4404+
&& (DECL_P (new_var) || (TYPE_P (new_var) && size)))
43964405
if (tree *allocatorp = ctx->allocate_map->get (var))
43974406
allocator = *allocatorp;
43984407
if (allocator == NULL_TREE)
43994408
return false;
44004409
if (!is_ref && omp_is_reference (var))
4401-
return false;
4410+
{
4411+
allocator = NULL_TREE;
4412+
return false;
4413+
}
44024414

44034415
if (TREE_CODE (allocator) != INTEGER_CST)
44044416
allocator = build_outer_var_ref (allocator, ctx);
@@ -4410,19 +4422,24 @@ lower_private_allocate (tree var, tree new_var, tree &allocator,
44104422
allocator = var;
44114423
}
44124424

4413-
tree ptr_type, align, sz;
4414-
if (is_ref)
4425+
tree ptr_type, align, sz = size;
4426+
if (TYPE_P (new_var))
4427+
{
4428+
ptr_type = build_pointer_type (new_var);
4429+
align = build_int_cst (size_type_node, TYPE_ALIGN_UNIT (new_var));
4430+
}
4431+
else if (is_ref)
44154432
{
44164433
ptr_type = build_pointer_type (TREE_TYPE (TREE_TYPE (new_var)));
44174434
align = build_int_cst (size_type_node,
44184435
TYPE_ALIGN_UNIT (TREE_TYPE (ptr_type)));
4419-
sz = size;
44204436
}
44214437
else
44224438
{
44234439
ptr_type = build_pointer_type (TREE_TYPE (new_var));
44244440
align = build_int_cst (size_type_node, DECL_ALIGN_UNIT (new_var));
4425-
sz = fold_convert (size_type_node, DECL_SIZE_UNIT (new_var));
4441+
if (sz == NULL_TREE)
4442+
sz = fold_convert (size_type_node, DECL_SIZE_UNIT (new_var));
44264443
}
44274444
if (TREE_CODE (sz) != INTEGER_CST)
44284445
{
@@ -4855,7 +4872,23 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
48554872
tree type = TREE_TYPE (d);
48564873
gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
48574874
tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
4875+
tree sz = v;
48584876
const char *name = get_name (orig_var);
4877+
if (pass != 3 && !TREE_CONSTANT (v))
4878+
{
4879+
tree t = maybe_lookup_decl (v, ctx);
4880+
if (t)
4881+
v = t;
4882+
else
4883+
v = maybe_lookup_decl_in_outer_ctx (v, ctx);
4884+
gimplify_expr (&v, ilist, NULL, is_gimple_val, fb_rvalue);
4885+
t = fold_build2_loc (clause_loc, PLUS_EXPR,
4886+
TREE_TYPE (v), v,
4887+
build_int_cst (TREE_TYPE (v), 1));
4888+
sz = fold_build2_loc (clause_loc, MULT_EXPR,
4889+
TREE_TYPE (v), t,
4890+
TYPE_SIZE_UNIT (TREE_TYPE (type)));
4891+
}
48594892
if (pass == 3)
48604893
{
48614894
tree xv = create_tmp_var (ptr_type_node);
@@ -4913,6 +4946,13 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
49134946
gimplify_assign (cond, x, ilist);
49144947
x = xv;
49154948
}
4949+
else if (lower_private_allocate (var, type, allocator,
4950+
allocate_ptr, ilist, ctx,
4951+
true,
4952+
TREE_CONSTANT (v)
4953+
? TYPE_SIZE_UNIT (type)
4954+
: sz))
4955+
x = allocate_ptr;
49164956
else if (TREE_CONSTANT (v))
49174957
{
49184958
x = create_tmp_var_raw (type, name);
@@ -4924,20 +4964,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
49244964
{
49254965
tree atmp
49264966
= builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
4927-
tree t = maybe_lookup_decl (v, ctx);
4928-
if (t)
4929-
v = t;
4930-
else
4931-
v = maybe_lookup_decl_in_outer_ctx (v, ctx);
4932-
gimplify_expr (&v, ilist, NULL, is_gimple_val, fb_rvalue);
4933-
t = fold_build2_loc (clause_loc, PLUS_EXPR,
4934-
TREE_TYPE (v), v,
4935-
build_int_cst (TREE_TYPE (v), 1));
4936-
t = fold_build2_loc (clause_loc, MULT_EXPR,
4937-
TREE_TYPE (v), t,
4938-
TYPE_SIZE_UNIT (TREE_TYPE (type)));
49394967
tree al = size_int (TYPE_ALIGN (TREE_TYPE (type)));
4940-
x = build_call_expr_loc (clause_loc, atmp, 2, t, al);
4968+
x = build_call_expr_loc (clause_loc, atmp, 2, sz, al);
49414969
}
49424970

49434971
tree ptype = build_pointer_type (TREE_TYPE (type));
@@ -5199,6 +5227,12 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
51995227
gimple_seq_add_stmt (dlist, g);
52005228
gimple_seq_add_stmt (dlist, gimple_build_label (end2));
52015229
}
5230+
if (allocator)
5231+
{
5232+
tree f = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
5233+
g = gimple_build_call (f, 2, allocate_ptr, allocator);
5234+
gimple_seq_add_stmt (dlist, g);
5235+
}
52025236
continue;
52035237
}
52045238
else if (pass == 2)

libgomp/testsuite/libgomp.c-c++-common/allocate-1.c

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,20 @@
33
#include <stdint.h>
44

55
void
6-
foo (int x, omp_allocator_handle_t h, int fl)
6+
foo (int x, int *p, int *q, int px, omp_allocator_handle_t h, int fl)
77
{
88
int y = 0, r = 0, i, i1, l, l2[4], l3, n = 8;
99
int i2, j2, n2 = 9, l4;
1010
int i3, j3, n3 = 10, l5;
1111
int i4, j4, n4 = 11, l6;
1212
int i5;
1313
int v[x], w[x];
14+
int r2[4] = { 0, 0, 0, 0 };
1415
int xo = x;
16+
for (i = 0; i < 4; i++)
17+
p[i] = 0;
18+
for (i = 0; i < 3; i++)
19+
q[i] = 0;
1520
for (i = 0; i < x; i++)
1621
w[i] = i;
1722
#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)
117122
if ((fl & 2) && (((uintptr_t) &i5) & 63) != 0)
118123
abort ();
119124
}
125+
#pragma omp for reduction(+:p[2:px], q[:3], r2) allocate(h: p, q, r2)
126+
for (i = 0; i < 32; i++)
127+
{
128+
p[2] += i;
129+
p[3] += 2 * i;
130+
q[0] += 3 * i;
131+
q[2] += 4 * i;
132+
r2[0] += 5 * i;
133+
r2[3] += 6 * i;
134+
/* Can't really rely on alignment of &p[0], the implementation could
135+
allocate the whole array or do what GCC does and allocate only part
136+
of it. */
137+
if ((fl & 1) && (((uintptr_t) &q[0] | (uintptr_t) &r2[0]) & 63) != 0)
138+
abort ();
139+
}
120140
}
121141
if (r != 64 * 63 / 2 || l != 63 || n != 8 + 16 * 64)
122142
abort ();
@@ -130,6 +150,10 @@ foo (int x, omp_allocator_handle_t h, int fl)
130150
abort ();
131151
if (i5 != 19)
132152
abort ();
153+
if (p[2] != (32 * 31) / 2 || p[3] != 2 * (32 * 31) / 2
154+
|| q[0] != 3 * (32 * 31) / 2 || q[2] != 4 * (32 * 31) / 2
155+
|| r2[0] != 5 * (32 * 31) / 2 || r2[3] != 6 * (32 * 31) / 2)
156+
abort ();
133157
}
134158

135159
void
@@ -239,15 +263,16 @@ main ()
239263
{ omp_atk_fallback, omp_atv_null_fb } };
240264
omp_allocator_handle_t a
241265
= omp_init_allocator (omp_default_mem_space, 2, traits);
266+
int p[4], q[3];
242267
if (a == omp_null_allocator)
243268
abort ();
244269
omp_set_default_allocator (omp_default_mem_alloc);
245-
foo (42, omp_null_allocator, 0);
246-
foo (42, omp_default_mem_alloc, 0);
247-
foo (42, a, 1);
270+
foo (42, p, q, 2, omp_null_allocator, 0);
271+
foo (42, p, q, 2, omp_default_mem_alloc, 0);
272+
foo (42, p, q, 2, a, 1);
248273
omp_set_default_allocator (a);
249-
foo (42, omp_null_allocator, 3);
250-
foo (42, omp_default_mem_alloc, 2);
274+
foo (42, p, q, 2, omp_null_allocator, 3);
275+
foo (42, p, q, 2, omp_default_mem_alloc, 2);
251276
bar (42, a);
252277
omp_destroy_allocator (a);
253278
return 0;

0 commit comments

Comments
 (0)