aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-10-30 09:18:36 +0100
committerJakub Jelinek <jakub@redhat.com>2020-10-30 09:18:36 +0100
commit71e713209adcb3b7f65d14906eb200317cc1c2ae (patch)
tree8de62c1db565afb998d7f751f3abf12c1b6fd813
parent5a6b1d8ef4218a1a2ed6d43c6ee058db9c417bc8 (diff)
downloadgcc-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.c55
-rw-r--r--gcc/testsuite/c-c++-common/gomp/allocate-3.c38
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;
+}