aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKwok Cheung Yeung <kcyeung@baylibre.com>2024-11-27 21:51:34 +0000
committerSandra Loosemore <sloosemore@baylibre.com>2025-05-15 20:25:52 +0000
commit176d660537b2edc8007a4bed1eb936d881a46277 (patch)
treea8e59a62cfbf3e83bf734ac1ddd2b29de9c35719 /gcc
parent4756123b29d183da7f57533d4ef67c6361fb2a79 (diff)
downloadgcc-176d660537b2edc8007a4bed1eb936d881a46277.zip
gcc-176d660537b2edc8007a4bed1eb936d881a46277.tar.gz
gcc-176d660537b2edc8007a4bed1eb936d881a46277.tar.bz2
openmp: Add support for iterators in 'target update' clauses (C/C++)
This adds support for iterators in 'to' and 'from' clauses in the 'target update' OpenMP directive. gcc/c/ * c-parser.cc (c_parser_omp_clause_from_to): Parse 'iterator' modifier. * c-typeck.cc (c_finish_omp_clauses): Finish iterators for to/from clauses. gcc/cp/ * parser.cc (cp_parser_omp_clause_from_to): Parse 'iterator' modifier. * semantics.cc (finish_omp_clauses): Finish iterators for to/from clauses. gcc/ * gimplify.cc (gimplify_scan_omp_clauses): Add argument for iterator loop sequence. Gimplify the clause decl and size into the iterator loop if iterators are used. (gimplify_omp_workshare): Add argument for iterator loops sequence in call to gimplify_scan_omp_clauses. (gimplify_omp_target_update): Call remove_unused_omp_iterator_vars and build_omp_iterators_loops. Add loop sequence as argument when calling gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses and building the Gimple statement. * tree-pretty-print.cc (dump_omp_clause): Call dump_omp_iterators for to/from clauses with iterators. * tree.cc (omp_clause_num_ops): Add extra operand for OMP_CLAUSE_FROM and OMP_CLAUSE_TO. * tree.h (OMP_CLAUSE_HAS_ITERATORS): Add check for OMP_CLAUSE_TO and OMP_CLAUSE_FROM. (OMP_CLAUSE_ITERATORS): Likewise. gcc/testsuite/ * c-c++-common/gomp/target-update-iterators-1.c: New. * c-c++-common/gomp/target-update-iterators-2.c: New. * c-c++-common/gomp/target-update-iterators-3.c: New. libgomp/ * target.c (gomp_update): Call gomp_merge_iterator_maps. Free allocated variables. * testsuite/libgomp.c-c++-common/target-update-iterators-1.c: New. * testsuite/libgomp.c-c++-common/target-update-iterators-2.c: New. * testsuite/libgomp.c-c++-common/target-update-iterators-3.c: New.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c/c-parser.cc55
-rw-r--r--gcc/c/c-typeck.cc5
-rw-r--r--gcc/cp/parser.cc56
-rw-r--r--gcc/cp/semantics.cc5
-rw-r--r--gcc/gimplify.cc37
-rw-r--r--gcc/testsuite/c-c++-common/gomp/target-update-iterators-1.c20
-rw-r--r--gcc/testsuite/c-c++-common/gomp/target-update-iterators-2.c23
-rw-r--r--gcc/testsuite/c-c++-common/gomp/target-update-iterators-3.c17
-rw-r--r--gcc/tree-pretty-print.cc10
-rw-r--r--gcc/tree.cc4
-rw-r--r--gcc/tree.h6
11 files changed, 200 insertions, 38 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 8c85cce..f1c7efc 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -20988,8 +20988,11 @@ c_parser_omp_clause_device_type (c_parser *parser, tree list)
to ( variable-list )
OpenMP 5.1:
- from ( [present :] variable-list )
- to ( [present :] variable-list ) */
+ from ( [motion-modifier[,] [motion-modifier[,]...]:] variable-list )
+ to ( [motion-modifier[,] [motion-modifier[,]...]:] variable-list )
+
+ motion-modifier:
+ present | iterator (iterators-definition) */
static tree
c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind,
@@ -21001,20 +21004,27 @@ c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind,
return list;
int pos = 1, colon_pos = 0;
+ int iterator_length = 0;
while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
{
- if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
- pos += 2;
- else if (c_parser_peek_nth_token_raw (parser, pos + 1)->type
- == CPP_OPEN_PAREN)
+ const char *identifier =
+ IDENTIFIER_POINTER (c_parser_peek_nth_token_raw (parser, pos)->value);
+ if (c_parser_peek_nth_token_raw (parser, pos + 1)->type
+ == CPP_OPEN_PAREN)
{
unsigned int npos = pos + 2;
if (c_parser_check_balanced_raw_token_sequence (parser, &npos)
- && (c_parser_peek_nth_token_raw (parser, npos)->type
- == CPP_CLOSE_PAREN))
- pos = npos + 1;
+ && (c_parser_peek_nth_token_raw (parser, npos)->type
+ == CPP_CLOSE_PAREN))
+ {
+ if (strcmp (identifier, "iterator") == 0)
+ iterator_length = npos - pos + 1;
+ pos = npos;
+ }
}
+ if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
+ pos += 2;
else
pos++;
if (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_COLON)
@@ -21027,6 +21037,7 @@ c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind,
int present_modifier = false;
int mapper_modifier = false;
tree mapper_name = NULL_TREE;
+ tree iterators = NULL_TREE;
for (int pos = 1; pos < colon_pos; ++pos)
{
@@ -21048,6 +21059,17 @@ c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind,
present_modifier++;
c_parser_consume_token (parser);
}
+ else if (strcmp ("iterator", p) == 0)
+ {
+ if (iterators)
+ {
+ c_parser_error (parser, "too many %<iterator%> modifiers");
+ parens.skip_until_found_close (parser);
+ return list;
+ }
+ iterators = c_parser_omp_iterators (parser);
+ pos += iterator_length - 1;
+ }
else if (strcmp ("mapper", p) == 0)
{
c_parser_consume_token (parser);
@@ -21104,7 +21126,7 @@ c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind,
else
{
c_parser_error (parser, "%<to%> or %<from%> clause with modifier "
- "other than %<present%> or %<mapper%>");
+ "other than %<iterator%>, %<mapper%> or %<present%>");
parens.skip_until_found_close (parser);
return list;
}
@@ -21141,6 +21163,19 @@ c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind,
OMP_CLAUSE_CHAIN (last_new) = name;
}
+ if (iterators)
+ {
+ tree block = pop_scope ();
+ if (iterators == error_mark_node)
+ iterators = NULL_TREE;
+ else
+ TREE_VEC_ELT (iterators, 5) = block;
+ }
+
+ if (iterators)
+ for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
+ OMP_CLAUSE_ITERATORS (c) = iterators;
+
return nl;
}
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 4484007..d8471e9 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -17270,6 +17270,9 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_GRID_DIM
|| OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_GRID_STRIDE)
break;
+ /* FALLTHRU */
+ case OMP_CLAUSE_TO:
+ case OMP_CLAUSE_FROM:
if (OMP_CLAUSE_ITERATORS (c)
&& c_omp_finish_iterators (OMP_CLAUSE_ITERATORS (c)))
{
@@ -17277,8 +17280,6 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
break;
}
/* FALLTHRU */
- case OMP_CLAUSE_TO:
- case OMP_CLAUSE_FROM:
case OMP_CLAUSE__CACHE_:
{
using namespace omp_addr_tokenizer;
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 5efe2da..a917658 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -43160,8 +43160,11 @@ cp_parser_omp_clause_doacross (cp_parser *parser, tree list, location_t loc)
to ( variable-list )
OpenMP 5.1:
- from ( [present :] variable-list )
- to ( [present :] variable-list ) */
+ from ( [motion-modifier[,] [motion-modifier[,]...]:] variable-list )
+ to ( [motion-modifier[,] [motion-modifier[,]...]:] variable-list )
+
+ motion-modifier:
+ present | iterator (iterators-definition) */
static tree
cp_parser_omp_clause_from_to (cp_parser *parser, enum omp_clause_code kind,
@@ -43172,14 +43175,25 @@ cp_parser_omp_clause_from_to (cp_parser *parser, enum omp_clause_code kind,
int pos = 1;
int colon_pos = 0;
+ int iterator_length = 0;
while (cp_lexer_peek_nth_token (parser->lexer, pos)->type == CPP_NAME)
{
+ const char *identifier =
+ IDENTIFIER_POINTER (cp_lexer_peek_nth_token (parser->lexer,
+ pos)->u.value);
+ if (cp_lexer_nth_token_is (parser->lexer, pos + 1, CPP_OPEN_PAREN))
+ {
+ int n = cp_parser_skip_balanced_tokens (parser, pos + 1);
+ if (n != pos + 1)
+ {
+ if (strcmp (identifier, "iterator") == 0)
+ iterator_length = n - pos;
+ pos = n - 1;
+ }
+ }
if (cp_lexer_peek_nth_token (parser->lexer, pos + 1)->type == CPP_COMMA)
pos += 2;
- else if (cp_lexer_peek_nth_token (parser->lexer, pos + 1)->type
- == CPP_OPEN_PAREN)
- pos = cp_parser_skip_balanced_tokens (parser, pos + 1);
else
pos++;
if (cp_lexer_peek_nth_token (parser->lexer, pos)->type == CPP_COLON)
@@ -43192,6 +43206,7 @@ cp_parser_omp_clause_from_to (cp_parser *parser, enum omp_clause_code kind,
bool present_modifier = false;
bool mapper_modifier = false;
tree mapper_name = NULL_TREE;
+ tree iterators = NULL_TREE;
for (int pos = 1; pos < colon_pos; ++pos)
{
@@ -43216,6 +43231,21 @@ cp_parser_omp_clause_from_to (cp_parser *parser, enum omp_clause_code kind,
present_modifier = true;
cp_lexer_consume_token (parser->lexer);
}
+ else if (strcmp ("iterator", p) == 0)
+ {
+ if (iterators)
+ {
+ cp_parser_error (parser, "too many %<iterator%> modifiers");
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+ }
+ begin_scope (sk_omp, NULL);
+ iterators = cp_parser_omp_iterators (parser);
+ pos += iterator_length - 1;
+ }
else if (strcmp ("mapper", p) == 0)
{
cp_lexer_consume_token (parser->lexer);
@@ -43278,7 +43308,8 @@ cp_parser_omp_clause_from_to (cp_parser *parser, enum omp_clause_code kind,
else
{
cp_parser_error (parser, "%<to%> or %<from%> clause with "
- "modifier other than %<present%> or %<mapper%>");
+ "modifier other than %<iterator%>, "
+ "%<mapper%> or %<present%>");
cp_parser_skip_to_closing_parenthesis (parser,
/*recovering=*/true,
/*or_comma=*/false,
@@ -43317,6 +43348,19 @@ cp_parser_omp_clause_from_to (cp_parser *parser, enum omp_clause_code kind,
OMP_CLAUSE_CHAIN (last_new) = name;
}
+ if (iterators)
+ {
+ tree block = poplevel (1, 1, 0);
+ if (iterators == error_mark_node)
+ iterators = NULL_TREE;
+ else
+ TREE_VEC_ELT (iterators, 5) = block;
+ }
+
+ if (iterators)
+ for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
+ OMP_CLAUSE_ITERATORS (c) = iterators;
+
return nl;
}
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index a65e538..532c2a3 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -9343,6 +9343,9 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_GRID_DIM
|| OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_GRID_STRIDE)
break;
+ /* FALLTHRU */
+ case OMP_CLAUSE_TO:
+ case OMP_CLAUSE_FROM:
if (OMP_CLAUSE_ITERATORS (c)
&& cp_omp_finish_iterators (OMP_CLAUSE_ITERATORS (c)))
{
@@ -9350,8 +9353,6 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
break;
}
/* FALLTHRU */
- case OMP_CLAUSE_TO:
- case OMP_CLAUSE_FROM:
case OMP_CLAUSE__CACHE_:
{
using namespace omp_addr_tokenizer;
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 017dd78..40f2fde 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -13839,7 +13839,8 @@ omp_instantiate_implicit_mappers (splay_tree_node n, void *data)
static void
gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
enum omp_region_type region_type,
- enum tree_code code)
+ enum tree_code code,
+ gimple_seq *loops_seq_p = NULL)
{
using namespace omp_addr_tokenizer;
struct gimplify_omp_ctx *ctx, *outer_ctx;
@@ -14639,23 +14640,24 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
: TYPE_SIZE_UNIT (TREE_TYPE (decl));
- if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
- NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
+ gimple_seq *seq_p;
+ seq_p = enter_omp_iterator_loop_context (c, loops_seq_p, pre_p);
+ if (gimplify_expr (&OMP_CLAUSE_SIZE (c), seq_p, NULL,
+ is_gimple_val, fb_rvalue) == GS_ERROR)
{
remove = true;
+ exit_omp_iterator_loop_context (c);
break;
}
if (!DECL_P (decl))
{
- if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
- NULL, is_gimple_lvalue, fb_lvalue)
- == GS_ERROR)
- {
- remove = true;
- break;
- }
+ if (gimplify_expr (&OMP_CLAUSE_DECL (c), seq_p, NULL,
+ is_gimple_lvalue, fb_lvalue) == GS_ERROR)
+ remove = true;
+ exit_omp_iterator_loop_context (c);
break;
}
+ exit_omp_iterator_loop_context (c);
goto do_notice;
case OMP_CLAUSE__MAPPER_BINDING_:
@@ -19395,7 +19397,7 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
if ((ort & ORT_ACC) == 0)
in_omp_construct = false;
gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
- TREE_CODE (expr));
+ TREE_CODE (expr), &iterator_loops_seq);
if (TREE_CODE (expr) == OMP_TARGET)
optimize_target_teams (expr, pre_p);
if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
@@ -19643,10 +19645,16 @@ gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
default:
gcc_unreachable ();
}
+
+ gimple_seq iterator_loops_seq = NULL;
+ remove_unused_omp_iterator_vars (&OMP_STANDALONE_CLAUSES (expr));
+ build_omp_iterators_loops (&OMP_STANDALONE_CLAUSES (expr),
+ &iterator_loops_seq);
+
gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
- ort, TREE_CODE (expr));
+ ort, TREE_CODE (expr), &iterator_loops_seq);
gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
- TREE_CODE (expr));
+ TREE_CODE (expr), &iterator_loops_seq);
if (TREE_CODE (expr) == OACC_UPDATE
&& omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
OMP_CLAUSE_IF_PRESENT))
@@ -19710,7 +19718,8 @@ gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
gcc_unreachable ();
}
}
- stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
+ stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr),
+ iterator_loops_seq);
gimplify_seq_add_stmt (pre_p, stmt);
*expr_p = NULL_TREE;
diff --git a/gcc/testsuite/c-c++-common/gomp/target-update-iterators-1.c b/gcc/testsuite/c-c++-common/gomp/target-update-iterators-1.c
new file mode 100644
index 0000000..64602d4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/target-update-iterators-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+#define DIM1 17
+#define DIM2 39
+
+void f (int **x, float **y)
+{
+ #pragma omp target update to (iterator(i=0:DIM1): x[i][:DIM2])
+
+ #pragma omp target update to (iterator(i=0:DIM1): x[i][:DIM2], y[i][:DIM2])
+
+ #pragma omp target update to (iterator(i=0:DIM1), present: x[i][:DIM2])
+
+ #pragma omp target update to (iterator(i=0:DIM1), iterator(j=0:DIM2): x[i][j]) /* { dg-error "too many 'iterator' modifiers" } */
+ /* { dg-error ".#pragma omp target update. must contain at least one .from. or .to. clauses" "" { target *-*-* } .-1 } */
+
+ #pragma omp target update to (iterator(i=0:DIM1), something: x[i][j]) /* { dg-error ".to. or .from. clause with modifier other than .iterator., .mapper. or .present. before .something." } */
+ /* { dg-error ".#pragma omp target update. must contain at least one .from. or .to. clauses" "" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/target-update-iterators-2.c b/gcc/testsuite/c-c++-common/gomp/target-update-iterators-2.c
new file mode 100644
index 0000000..ae0a222
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/target-update-iterators-2.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -fdump-tree-gimple" } */
+
+void f (int *x, float *y, double *z)
+{
+ #pragma omp target update to(iterator(i=0:10): x) /* { dg-warning "iterator variable .i. not used in clause expression" }*/
+ ;
+
+ #pragma omp target update from(iterator(i2=0:10, j2=0:20): x[i2]) /* { dg-warning "iterator variable .j2. not used in clause expression" }*/
+ ;
+
+ #pragma omp target update to(iterator(i3=0:10, j3=0:20, k3=0:30): x[i3+j3], y[j3+k3], z[k3+i3])
+ /* { dg-warning "iterator variable .i3. not used in clause expression" "" { target *-*-* } .-1 } */
+ /* { dg-warning "iterator variable .j3. not used in clause expression" "" { target *-*-* } .-2 } */
+ /* { dg-warning "iterator variable .k3. not used in clause expression" "" { target *-*-* } .-3 } */
+ ;
+}
+
+/* { dg-final { scan-tree-dump "update to\\\(x " "gimple" } } */
+/* { dg-final { scan-tree-dump "update from\\\(iterator\\\(int i2=0:10:1, loop_label=" "gimple" } } */
+/* { dg-final { scan-tree-dump "to\\\(iterator\\\(int i3=0:10:1, int k3=0:30:1, loop_label=" "gimple" } } */
+/* { dg-final { scan-tree-dump "to\\\(iterator\\\(int j3=0:20:1, int k3=0:30:1, loop_label=" "gimple" } } */
+/* { dg-final { scan-tree-dump "to\\\(iterator\\\(int i3=0:10:1, int j3=0:20:1, loop_label=" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/target-update-iterators-3.c b/gcc/testsuite/c-c++-common/gomp/target-update-iterators-3.c
new file mode 100644
index 0000000..ef55216
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/target-update-iterators-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -fdump-tree-gimple" } */
+
+#define DIM1 10
+#define DIM2 20
+#define DIM3 30
+
+void f (int ***x, float ***y, double **z)
+{
+ #pragma omp target update to (iterator(i=0:DIM1, j=0:DIM2): x[i][j][:DIM3], y[i][j][:DIM3])
+ #pragma omp target update from (iterator(i=0:DIM1): z[i][:DIM2])
+}
+
+/* { dg-final { scan-tree-dump-times "if \\(i <= 9\\) goto <D\.\[0-9\]+>; else goto <D\.\[0-9\]+>;" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "if \\(j <= 19\\) goto <D\.\[0-9\]+>; else goto <D\.\[0-9\]+>;" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "to\\(iterator\\(int i=0:10:1, int j=0:20:1, loop_label=<D\.\[0-9\]+>, elems=omp_iter_data\.\[0-9\]+, index=D\.\[0-9\]+\\):\\*D\.\[0-9\]+" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "from\\(iterator\\(int i=0:10:1, loop_label=<D\.\[0-9\]+>, elems=omp_iter_data\.\[0-9\]+, index=D\.\[0-9\]+\\):\\*D\.\[0-9\]+" 1 "gimple" } } */
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index f621c39..6f0978a 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -1270,6 +1270,11 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
pp_string (pp, "from(");
if (OMP_CLAUSE_MOTION_PRESENT (clause))
pp_string (pp, "present:");
+ if (OMP_CLAUSE_ITERATORS (clause))
+ {
+ dump_omp_iterators (pp, OMP_CLAUSE_ITERATORS (clause), spc, flags);
+ pp_colon (pp);
+ }
dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
spc, flags, false);
goto print_clause_size;
@@ -1278,6 +1283,11 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
pp_string (pp, "to(");
if (OMP_CLAUSE_MOTION_PRESENT (clause))
pp_string (pp, "present:");
+ if (OMP_CLAUSE_ITERATORS (clause))
+ {
+ dump_omp_iterators (pp, OMP_CLAUSE_ITERATORS (clause), spc, flags);
+ pp_colon (pp);
+ }
dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
spc, flags, false);
goto print_clause_size;
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 258f997..10e3d71 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -321,8 +321,8 @@ unsigned const char omp_clause_num_ops[] =
1, /* OMP_CLAUSE_IS_DEVICE_PTR */
1, /* OMP_CLAUSE_INCLUSIVE */
1, /* OMP_CLAUSE_EXCLUSIVE */
- 2, /* OMP_CLAUSE_FROM */
- 2, /* OMP_CLAUSE_TO */
+ 3, /* OMP_CLAUSE_FROM */
+ 3, /* OMP_CLAUSE_TO */
3, /* OMP_CLAUSE_MAP */
1, /* OMP_CLAUSE_HAS_DEVICE_ADDR */
1, /* OMP_CLAUSE_DOACROSS */
diff --git a/gcc/tree.h b/gcc/tree.h
index 86f0ab7..82232c5 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1654,11 +1654,13 @@ class auto_suppress_location_wrappers
#define OMP_CLAUSE_LOCATION(NODE) (OMP_CLAUSE_CHECK (NODE))->omp_clause.locus
#define OMP_CLAUSE_HAS_ITERATORS(NODE) \
- (OMP_CLAUSE_CODE (NODE) == OMP_CLAUSE_MAP \
+ ((OMP_CLAUSE_CODE (NODE) == OMP_CLAUSE_FROM \
+ || OMP_CLAUSE_CODE (NODE) == OMP_CLAUSE_TO \
+ || OMP_CLAUSE_CODE (NODE) == OMP_CLAUSE_MAP) \
&& OMP_CLAUSE_ITERATORS (NODE))
#define OMP_CLAUSE_ITERATORS(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \
- OMP_CLAUSE_MAP, \
+ OMP_CLAUSE_FROM, \
OMP_CLAUSE_MAP), 2)
/* True on OMP_FOR and other OpenMP/OpenACC looping constructs if the loop nest