From: Jakub Jelinek Date: Fri, 30 Oct 2020 08:18:36 +0000 (+0100) Subject: openmp: Fix handling of allocate clause on taskloop X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=71e713209adcb3b7f65d14906eb200317cc1c2ae;p=gcc.git 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 * 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. --- diff --git a/gcc/gimplify.c b/gcc/gimplify.c index f766fee24b9..aa3b914f6e5 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 00000000000..e61cc1e504a --- /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; +}