diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-10-30 09:18:36 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-10-30 09:18:36 +0100 |
commit | 71e713209adcb3b7f65d14906eb200317cc1c2ae (patch) | |
tree | 8de62c1db565afb998d7f751f3abf12c1b6fd813 | |
parent | 5a6b1d8ef4218a1a2ed6d43c6ee058db9c417bc8 (diff) | |
download | gcc-71e713209adcb3b7f65d14906eb200317cc1c2ae.zip gcc-71e713209adcb3b7f65d14906eb200317cc1c2ae.tar.gz gcc-71e713209adcb3b7f65d14906eb200317cc1c2ae.tar.bz2 |
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.
-rw-r--r-- | gcc/gimplify.c | 55 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/allocate-3.c | 38 |
2 files changed, 88 insertions, 5 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index f766fee..aa3b914 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -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); diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-3.c b/gcc/testsuite/c-c++-common/gomp/allocate-3.c new file mode 100644 index 0000000..e61cc1e --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/allocate-3.c @@ -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; +} |