aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family/c-omp.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-10-28 10:38:01 +0100
committerJakub Jelinek <jakub@redhat.com>2020-10-28 10:38:01 +0100
commit3a8b20947f2b1559a7d5dcb62918f91344908c62 (patch)
treeff6700e4ff3c7bad2285b8786255a17effb21ef1 /gcc/c-family/c-omp.c
parent2298ca2d3e133945f5034065e843e2ea0f36e0bb (diff)
downloadgcc-3a8b20947f2b1559a7d5dcb62918f91344908c62.zip
gcc-3a8b20947f2b1559a7d5dcb62918f91344908c62.tar.gz
gcc-3a8b20947f2b1559a7d5dcb62918f91344908c62.tar.bz2
openmp: Parsing and some semantic analysis of OpenMP allocate clause
This patch adds parsing of OpenMP allocate clause, but still ignores it during OpenMP lowering where we should for privatized variables with allocate clause use the corresponding allocators rather than allocating them on the stack. 2020-10-28 Jakub Jelinek <jakub@redhat.com> gcc/ * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_ALLOCATE. * tree.h (OMP_CLAUSE_ALLOCATE_ALLOCATOR, OMP_CLAUSE_ALLOCATE_COMBINED): Define. * tree.c (omp_clause_num_ops, omp_clause_code_name): Add allocate clause. (walk_tree_1): Handle OMP_CLAUSE_ALLOCATE. * tree-pretty-print.c (dump_omp_clause): Likewise. * gimplify.c (gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses, gimplify_omp_for): Likewise. * tree-nested.c (convert_nonlocal_omp_clauses, convert_local_omp_clauses): Likewise. * omp-low.c (scan_sharing_clauses): Likewise. gcc/c-family/ * c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_ALLOCATE. * c-omp.c: Include bitmap.h. (c_omp_split_clauses): Handle OMP_CLAUSE_ALLOCATE. gcc/c/ * c-parser.c (c_parser_omp_clause_name): Handle allocate. (c_parser_omp_clause_allocate): New function. (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_ALLOCATE. (OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK, OMP_PARALLEL_CLAUSE_MASK, OMP_SINGLE_CLAUSE_MASK, OMP_TASK_CLAUSE_MASK, OMP_TASKGROUP_CLAUSE_MASK, OMP_DISTRIBUTE_CLAUSE_MASK, OMP_TEAMS_CLAUSE_MASK, OMP_TARGET_CLAUSE_MASK, OMP_TASKLOOP_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_ALLOCATE. * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_ALLOCATE. gcc/cp/ * parser.c (cp_parser_omp_clause_name): Handle allocate. (cp_parser_omp_clause_allocate): New function. (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_ALLOCATE. (OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK, OMP_PARALLEL_CLAUSE_MASK, OMP_SINGLE_CLAUSE_MASK, OMP_TASK_CLAUSE_MASK, OMP_TASKGROUP_CLAUSE_MASK, OMP_DISTRIBUTE_CLAUSE_MASK, OMP_TEAMS_CLAUSE_MASK, OMP_TARGET_CLAUSE_MASK, OMP_TASKLOOP_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_ALLOCATE. * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_ALLOCATE. * pt.c (tsubst_omp_clauses): Likewise. gcc/testsuite/ * c-c++-common/gomp/allocate-1.c: New test. * c-c++-common/gomp/allocate-2.c: New test. * c-c++-common/gomp/clauses-1.c (omp_allocator_handle_t): New typedef. (foo, bar, baz): Add allocate clauses where allowed.
Diffstat (limited to 'gcc/c-family/c-omp.c')
-rw-r--r--gcc/c-family/c-omp.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c
index d7cff0f..bce2f8e 100644
--- a/gcc/c-family/c-omp.c
+++ b/gcc/c-family/c-omp.c
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "attribs.h"
#include "gimplify.h"
#include "langhooks.h"
+#include "bitmap.h"
/* Complete a #pragma oacc wait construct. LOC is the location of
@@ -1575,6 +1576,7 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
tree next, c;
enum c_omp_clause_split s;
int i;
+ bool has_dup_allocate = false;
for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
cclauses[i] = NULL;
@@ -2198,6 +2200,71 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
else
s = C_OMP_CLAUSE_SPLIT_FOR;
break;
+ /* Allocate clause is allowed on target, teams, distribute, parallel,
+ for, sections and taskloop. Distribute it to all. */
+ case OMP_CLAUSE_ALLOCATE:
+ s = C_OMP_CLAUSE_SPLIT_COUNT;
+ for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
+ {
+ switch (i)
+ {
+ case C_OMP_CLAUSE_SPLIT_TARGET:
+ if ((mask & (OMP_CLAUSE_MASK_1
+ << PRAGMA_OMP_CLAUSE_MAP)) == 0)
+ continue;
+ break;
+ case C_OMP_CLAUSE_SPLIT_TEAMS:
+ if ((mask & (OMP_CLAUSE_MASK_1
+ << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) == 0)
+ continue;
+ break;
+ case C_OMP_CLAUSE_SPLIT_DISTRIBUTE:
+ if ((mask & (OMP_CLAUSE_MASK_1
+ << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
+ continue;
+ break;
+ case C_OMP_CLAUSE_SPLIT_PARALLEL:
+ if ((mask & (OMP_CLAUSE_MASK_1
+ << PRAGMA_OMP_CLAUSE_NUM_THREADS)) == 0)
+ continue;
+ break;
+ case C_OMP_CLAUSE_SPLIT_FOR:
+ STATIC_ASSERT (C_OMP_CLAUSE_SPLIT_SECTIONS
+ == C_OMP_CLAUSE_SPLIT_FOR
+ && (C_OMP_CLAUSE_SPLIT_TASKLOOP
+ == C_OMP_CLAUSE_SPLIT_FOR)
+ && (C_OMP_CLAUSE_SPLIT_LOOP
+ == C_OMP_CLAUSE_SPLIT_FOR));
+ if (code == OMP_SECTIONS)
+ break;
+ if ((mask & (OMP_CLAUSE_MASK_1
+ << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
+ break;
+ if ((mask & (OMP_CLAUSE_MASK_1
+ << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
+ break;
+ continue;
+ case C_OMP_CLAUSE_SPLIT_SIMD:
+ continue;
+ default:
+ gcc_unreachable ();
+ }
+ if (s != C_OMP_CLAUSE_SPLIT_COUNT)
+ {
+ c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
+ OMP_CLAUSE_ALLOCATE);
+ OMP_CLAUSE_DECL (c)
+ = OMP_CLAUSE_DECL (clauses);
+ OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
+ = OMP_CLAUSE_ALLOCATE_ALLOCATOR (clauses);
+ OMP_CLAUSE_CHAIN (c) = cclauses[s];
+ cclauses[s] = c;
+ has_dup_allocate = true;
+ }
+ s = (enum c_omp_clause_split) i;
+ }
+ gcc_assert (s != C_OMP_CLAUSE_SPLIT_COUNT);
+ break;
default:
gcc_unreachable ();
}
@@ -2205,6 +2272,108 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
cclauses[s] = clauses;
}
+ if (has_dup_allocate)
+ {
+ bool need_prune = false;
+ bitmap_obstack_initialize (NULL);
+ for (i = 0; i < C_OMP_CLAUSE_SPLIT_SIMD - (code == OMP_LOOP); i++)
+ if (cclauses[i])
+ {
+ bitmap_head allocate_head;
+ bitmap_initialize (&allocate_head, &bitmap_default_obstack);
+ for (c = cclauses[i]; c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE
+ && DECL_P (OMP_CLAUSE_DECL (c)))
+ bitmap_set_bit (&allocate_head,
+ DECL_UID (OMP_CLAUSE_DECL (c)));
+ for (c = cclauses[i]; c; c = OMP_CLAUSE_CHAIN (c))
+ switch (OMP_CLAUSE_CODE (c))
+ {
+ case OMP_CLAUSE_PRIVATE:
+ case OMP_CLAUSE_FIRSTPRIVATE:
+ case OMP_CLAUSE_LASTPRIVATE:
+ case OMP_CLAUSE_LINEAR:
+ case OMP_CLAUSE_REDUCTION:
+ case OMP_CLAUSE_IN_REDUCTION:
+ case OMP_CLAUSE_TASK_REDUCTION:
+ if (DECL_P (OMP_CLAUSE_DECL (c)))
+ bitmap_clear_bit (&allocate_head,
+ DECL_UID (OMP_CLAUSE_DECL (c)));
+ break;
+ default:
+ break;
+ }
+ for (c = cclauses[i]; c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE
+ && DECL_P (OMP_CLAUSE_DECL (c))
+ && bitmap_bit_p (&allocate_head,
+ DECL_UID (OMP_CLAUSE_DECL (c))))
+ {
+ /* Mark allocate clauses which don't have corresponding
+ explicit data sharing clause. */
+ OMP_CLAUSE_ALLOCATE_COMBINED (c) = 1;
+ need_prune = true;
+ }
+ }
+ bitmap_obstack_release (NULL);
+ if (need_prune)
+ {
+ /* At least one allocate clause has been marked. Walk all the
+ duplicated allocate clauses in sync. If it is marked in all
+ constituent constructs, diagnose it as invalid and remove
+ them. Otherwise, remove all marked inner clauses inside
+ a construct that doesn't have them marked. Keep the outer
+ marked ones, because some clause duplication is done only
+ during gimplification. */
+ tree *p[C_OMP_CLAUSE_SPLIT_COUNT];
+ for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
+ if (cclauses[i] == NULL_TREE
+ || i == C_OMP_CLAUSE_SPLIT_SIMD
+ || (i == C_OMP_CLAUSE_SPLIT_LOOP && code == OMP_LOOP))
+ p[i] = NULL;
+ else
+ p[i] = &cclauses[i];
+ do
+ {
+ int j = -1;
+ tree seen = NULL_TREE;
+ for (i = C_OMP_CLAUSE_SPLIT_COUNT - 1; i >= 0; i--)
+ if (p[i])
+ {
+ while (*p[i]
+ && OMP_CLAUSE_CODE (*p[i]) != OMP_CLAUSE_ALLOCATE)
+ p[i] = &OMP_CLAUSE_CHAIN (*p[i]);
+ if (*p[i] == NULL_TREE)
+ {
+ i = C_OMP_CLAUSE_SPLIT_COUNT;
+ break;
+ }
+ if (!OMP_CLAUSE_ALLOCATE_COMBINED (*p[i]) && j == -1)
+ j = i;
+ seen = *p[i];
+ }
+ if (i == C_OMP_CLAUSE_SPLIT_COUNT)
+ break;
+ if (j == -1)
+ error_at (OMP_CLAUSE_LOCATION (seen),
+ "%qD specified in %<allocate%> clause but not in "
+ "an explicit privatization clause",
+ OMP_CLAUSE_DECL (seen));
+ for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
+ if (p[i])
+ {
+ if (i > j)
+ /* Remove. */
+ *p[i] = OMP_CLAUSE_CHAIN (*p[i]);
+ else
+ /* Keep. */
+ p[i] = &OMP_CLAUSE_CHAIN (*p[i]);
+ }
+ }
+ while (1);
+ }
+ }
+
if (!flag_checking)
return;