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; +}