openmp: Fix handling of allocate clause on taskloop

This patch fixes gimplification of allocate clause on taskloop - puts
allocate on inner taskloop only if there is allocate clause, because otherwise
the data sharing clauses are only on the task construct in the construct sandwich.

2020-10-30  Jakub Jelinek  <jakub@redhat.com>

	* gimplify.c (gimplify_scan_omp_clauses): Force
	OMP_CLAUSE_ALLOCATE_ALLOCATOR into a temporary if it is non-NULL and
	non-constant.
	(gimplify_omp_for): Only put allocate on inner taskloop if lastprivate
	for the same variable is going to be put there, and in that case
	if the OMP_CLAUSE_ALLOCATE_ALLOCATOR is non-NULL non-constant, make
	the allocator firstprivate on task.

	* c-c++-common/gomp/allocate-3.c: New test.
This commit is contained in:
Jakub Jelinek 2020-10-30 09:18:36 +01:00
parent 5a6b1d8ef4
commit 71e713209a
2 changed files with 88 additions and 5 deletions

View File

@ -9721,6 +9721,13 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
remove = true;
break;
}
else if (code == OMP_TASKLOOP
&& OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
&& (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
!= INTEGER_CST))
OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
= get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
pre_p, NULL, false);
break;
case OMP_CLAUSE_DEFAULT:
@ -12120,6 +12127,20 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
tree *gtask_clauses_ptr = &task_clauses;
tree outer_for_clauses = NULL_TREE;
tree *gforo_clauses_ptr = &outer_for_clauses;
bitmap lastprivate_uids = NULL;
if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
{
c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
if (c)
{
lastprivate_uids = BITMAP_ALLOC (NULL);
for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
OMP_CLAUSE_LASTPRIVATE))
bitmap_set_bit (lastprivate_uids,
DECL_UID (OMP_CLAUSE_DECL (c)));
}
c = *gfor_clauses_ptr;
}
for (; c; c = OMP_CLAUSE_CHAIN (c))
switch (OMP_CLAUSE_CODE (c))
{
@ -12207,12 +12228,35 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
break;
/* Allocate clause we duplicate on task and inner taskloop. */
/* Allocate clause we duplicate on task and inner taskloop
if the decl is lastprivate, otherwise just put on task. */
case OMP_CLAUSE_ALLOCATE:
*gfor_clauses_ptr = c;
gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
*gtask_clauses_ptr = copy_node (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);
gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
}
else
{
*gtask_clauses_ptr = c;
gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
}
break;
default:
gcc_unreachable ();
@ -12220,6 +12264,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
*gfor_clauses_ptr = NULL_TREE;
*gtask_clauses_ptr = NULL_TREE;
*gforo_clauses_ptr = NULL_TREE;
BITMAP_FREE (lastprivate_uids);
g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
NULL_TREE, NULL_TREE, NULL_TREE);

View File

@ -0,0 +1,38 @@
typedef enum omp_allocator_handle_t
#if __cplusplus >= 201103L
: __UINTPTR_TYPE__
#endif
{
omp_null_allocator = 0,
omp_default_mem_alloc = 1,
omp_large_cap_mem_alloc = 2,
omp_const_mem_alloc = 3,
omp_high_bw_mem_alloc = 4,
omp_low_lat_mem_alloc = 5,
omp_cgroup_mem_alloc = 6,
omp_pteam_mem_alloc = 7,
omp_thread_mem_alloc = 8,
__omp_allocator_handle_t_max__ = __UINTPTR_MAX__
} omp_allocator_handle_t;
omp_allocator_handle_t baz (int);
int
foo (omp_allocator_handle_t h1, omp_allocator_handle_t h2, int y)
{
int x;
#pragma omp taskloop default(none) lastprivate (x) allocate (h1:x) firstprivate(y) allocate (h2:y)
for (int i = 0; i < 64; i++)
x = y + i;
return x;
}
int
bar (int y)
{
int x;
#pragma omp taskloop default(none) lastprivate (x) allocate (baz (0):x) allocate (baz (1):y) firstprivate(y)
for (int i = 0; i < 64; i++)
x = y + i;
return x;
}