diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-05-27 07:23:21 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-05-27 07:23:21 +0000 |
commit | df8a60d818fe5d1bd03a5f9edbac70868e56d687 (patch) | |
tree | 7df3e8132f848a6d1ad993be97e011a038c342b1 | |
parent | 8604b5d7d7199af279794a7b839090871886762c (diff) | |
download | gcc-df8a60d818fe5d1bd03a5f9edbac70868e56d687.tar.gz |
* tree.def (OMP_TEAMS, OMP_TARGET_DATA, OMP_TARGET,
OMP_TARGET_UPDATE): New tree codes.
* tree-cfg.c (make_edges): Handle GIMPLE_OMP_TARGET
and GIMPLE_OMP_TEAMS.
* omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE_DIST_SCHEDULE.
* gimple-low.c (lower_stmt): Handle GIMPLE_OMP_TARGET
and GIMPLE_OMP_TEAMS.
* tree.h (OMP_TEAMS_BODY, OMP_TEAMS_CLAUSES, OMP_TARGET_DATA_BODY,
OMP_TARGET_DATA_CLAUSES, OMP_TARGET_BODY, OMP_TARGET_CLAUSES,
OMP_TARGET_UPDATE_CLAUSES): Define.
* tree-nested.c (convert_nonlocal_reference_stmt,
convert_local_reference_stmt, convert_gimple_call): Handle
GIMPLE_OMP_TARGET and GIMPLE_OMP_TEAMS.
* tree-inline.c (estimate_num_insns): Likewise.
(remap_gimple_stmt): Likewise. Adjust gimple_build_omp_for
caller.
* gimple.def: Adjust comments describing OMP_CLAUSEs.
(GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS): New GIMPLE stmts.
* tree-parloops.c (create_parallel_loop): Adjust gimple_build_omp_for
caller.
* tree-pretty-print.c (dump_generic_node): Handle OMP_TEAMS,
OMP_TARGET, OMP_TARGET_DATA and OMP_TARGET_UPDATE.
* gimple.h (GF_OMP_TARGET_KIND_MASK, GF_OMP_TARGET_KIND_REGION,
GF_OMP_TARGET_KIND_DATA, GF_OMP_TARGET_KIND_UPDATE): New.
(gimple_build_omp_for): Add kind argument to prototype.
(gimple_build_omp_target, gimple_build_omp_teams): New prototypes.
(gimple_has_substatements): Handle GIMPLE_OMP_TARGET and
GIMPLE_OMP_TEAMS.
(gimple_omp_subcode): Change GIMPLE_OMP_SINGLE to GIMPLE_OMP_TEAMS.
(gimple_omp_target_clauses, gimple_omp_target_clauses_ptr,
gimple_omp_target_set_clauses, gimple_omp_target_kind,
gimple_omp_target_set_kind, gimple_omp_teams_clauses,
gimple_omp_teams_clauses_ptr, gimple_omp_teams_set_clauses): New
inline functions.
(gimple_return_set_retval): Handle GIMPLE_OMP_TARGET and
GIMPLE_OMP_TEAMS.
* gimple.c (gimple_build_omp_for): Add kind argument, call
gimple_omp_for_set_kind.
(gimple_build_omp_target, gimple_build_omp_teams): New functions.
(walk_gimple_op, walk_gimple_stmt, gimple_copy): Handle
GIMPLE_OMP_TARGET and GIMPLE_OMP_TEAMS.
* gimple-pretty-print.c (dump_gimple_omp_target,
dump_gimple_omp_teams): New functions.
(pp_gimple_stmt_1): Handle GIMPLE_OMP_TARGET and GIMPLE_OMP_TEAMS.
* gimplify.c (enum gimplify_omp_var_data): Add GOVD_MAP.
(enum omp_region_type): Add ORT_TEAMS, ORT_TARGET and ORT_TARGET_DATA.
(omp_add_variable): Add temporary assertions.
(omp_notice_threadprivate_variable): Complain if threadprivate vars
appear in target region.
(omp_notice_variable): ORT_TARGET, ORT_TARGET_DATA and ORT_TEAMS
handling.
(omp_check_private): Ignore ORT_TARGET and ORT_TARGET_DATA regions.
(gimplify_scan_omp_clauses): Handle OMP_CLAUSE_MAP, OMP_CLAUSE_TO,
OMP_CLAUSE_FROM, OMP_CLAUSE_NUM_TEAMS, OMP_CLAUSE_DIST_SCHEDULE
and OMP_CLAUSE_DEVICE.
(gimplify_adjust_omp_clauses): Likewise.
(gimplify_adjust_omp_clauses_1): Handle GOVD_MAP. Fix up
check for privatization by also testing for GOVD_LINEAR.
(gimplify_omp_for): Adjust gimple_build_omp_for caller.
Clear *expr_p.
(gimplify_omp_workshare): Handle also OMP_TARGET, OMP_TARGET_DATA
and OMP_TEAMS. Clear *expr_p.
(gimplify_omp_target_update): New function.
(gimplify_expr): Handle OMP_TARGET, OMP_TARGET_DATA, OMP_TARGET_UPDATE
and OMP_TEAMS.
cp/
* parser.c (cp_parser_omp_clause_cancelkind): Remove diagnostics.
(cp_parser_omp_all_clauses): Require that OMP_CLAUSE_{TO,FROM}
and OMP_CLAUSE_{PARALLEL,FOR,SECTIONS,TASKGROUP} must be first in
the list of clauses.
(OMP_TEAMS_CLAUSE_MASK, OMP_TARGET_CLAUSE_MASK,
OMP_TARGET_DATA_CLAUSE_MASK, OMP_TARGET_UPDATE_CLAUSE_MASK,
OMP_DISTRIBUTE_CLAUSE_MASK): Define.
(cp_parser_omp_teams, cp_parser_omp_target, cp_parser_omp_target_data,
cp_parser_omp_target_update, cp_parser_omp_distribute): New functions.
(cp_parser_omp_construct): Handle PRAGMA_OMP_DISTRIBUTE and
PRAGMA_OMP_TEAMS.
(cp_parser_pragma): Handle PRAGMA_OMP_DISTRIBUTE, PRAGMA_OMP_TEAMS
and PRAGMA_OMP_TARGET.
* pt.c (tsubst_expr): Handle OMP_TEAMS, OMP_TARGET, OMP_TARGET_DATA
and OMP_TARGET_UPDATE.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gomp-4_0-branch@199349 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog.gomp | 68 | ||||
-rw-r--r-- | gcc/cp/ChangeLog.gomp | 18 | ||||
-rw-r--r-- | gcc/cp/parser.c | 222 | ||||
-rw-r--r-- | gcc/cp/pt.c | 11 | ||||
-rw-r--r-- | gcc/gimple-low.c | 2 | ||||
-rw-r--r-- | gcc/gimple-pretty-print.c | 80 | ||||
-rw-r--r-- | gcc/gimple.c | 56 | ||||
-rw-r--r-- | gcc/gimple.def | 20 | ||||
-rw-r--r-- | gcc/gimple.h | 97 | ||||
-rw-r--r-- | gcc/gimplify.c | 271 | ||||
-rw-r--r-- | gcc/omp-low.c | 2 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 2 | ||||
-rw-r--r-- | gcc/tree-inline.c | 18 | ||||
-rw-r--r-- | gcc/tree-nested.c | 34 | ||||
-rw-r--r-- | gcc/tree-parloops.c | 2 | ||||
-rw-r--r-- | gcc/tree-pretty-print.c | 21 | ||||
-rw-r--r-- | gcc/tree.def | 19 | ||||
-rw-r--r-- | gcc/tree.h | 14 |
18 files changed, 894 insertions, 63 deletions
diff --git a/gcc/ChangeLog.gomp b/gcc/ChangeLog.gomp index d9b120f7ddf..0db46c9aef5 100644 --- a/gcc/ChangeLog.gomp +++ b/gcc/ChangeLog.gomp @@ -1,3 +1,71 @@ +2013-05-27 Jakub Jelinek <jakub@redhat.com> + + * tree.def (OMP_TEAMS, OMP_TARGET_DATA, OMP_TARGET, + OMP_TARGET_UPDATE): New tree codes. + * tree-cfg.c (make_edges): Handle GIMPLE_OMP_TARGET + and GIMPLE_OMP_TEAMS. + * omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE_DIST_SCHEDULE. + * gimple-low.c (lower_stmt): Handle GIMPLE_OMP_TARGET + and GIMPLE_OMP_TEAMS. + * tree.h (OMP_TEAMS_BODY, OMP_TEAMS_CLAUSES, OMP_TARGET_DATA_BODY, + OMP_TARGET_DATA_CLAUSES, OMP_TARGET_BODY, OMP_TARGET_CLAUSES, + OMP_TARGET_UPDATE_CLAUSES): Define. + * tree-nested.c (convert_nonlocal_reference_stmt, + convert_local_reference_stmt, convert_gimple_call): Handle + GIMPLE_OMP_TARGET and GIMPLE_OMP_TEAMS. + * tree-inline.c (estimate_num_insns): Likewise. + (remap_gimple_stmt): Likewise. Adjust gimple_build_omp_for + caller. + * gimple.def: Adjust comments describing OMP_CLAUSEs. + (GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS): New GIMPLE stmts. + * tree-parloops.c (create_parallel_loop): Adjust gimple_build_omp_for + caller. + * tree-pretty-print.c (dump_generic_node): Handle OMP_TEAMS, + OMP_TARGET, OMP_TARGET_DATA and OMP_TARGET_UPDATE. + * gimple.h (GF_OMP_TARGET_KIND_MASK, GF_OMP_TARGET_KIND_REGION, + GF_OMP_TARGET_KIND_DATA, GF_OMP_TARGET_KIND_UPDATE): New. + (gimple_build_omp_for): Add kind argument to prototype. + (gimple_build_omp_target, gimple_build_omp_teams): New prototypes. + (gimple_has_substatements): Handle GIMPLE_OMP_TARGET and + GIMPLE_OMP_TEAMS. + (gimple_omp_subcode): Change GIMPLE_OMP_SINGLE to GIMPLE_OMP_TEAMS. + (gimple_omp_target_clauses, gimple_omp_target_clauses_ptr, + gimple_omp_target_set_clauses, gimple_omp_target_kind, + gimple_omp_target_set_kind, gimple_omp_teams_clauses, + gimple_omp_teams_clauses_ptr, gimple_omp_teams_set_clauses): New + inline functions. + (gimple_return_set_retval): Handle GIMPLE_OMP_TARGET and + GIMPLE_OMP_TEAMS. + * gimple.c (gimple_build_omp_for): Add kind argument, call + gimple_omp_for_set_kind. + (gimple_build_omp_target, gimple_build_omp_teams): New functions. + (walk_gimple_op, walk_gimple_stmt, gimple_copy): Handle + GIMPLE_OMP_TARGET and GIMPLE_OMP_TEAMS. + * gimple-pretty-print.c (dump_gimple_omp_target, + dump_gimple_omp_teams): New functions. + (pp_gimple_stmt_1): Handle GIMPLE_OMP_TARGET and GIMPLE_OMP_TEAMS. + * gimplify.c (enum gimplify_omp_var_data): Add GOVD_MAP. + (enum omp_region_type): Add ORT_TEAMS, ORT_TARGET and ORT_TARGET_DATA. + (omp_add_variable): Add temporary assertions. + (omp_notice_threadprivate_variable): Complain if threadprivate vars + appear in target region. + (omp_notice_variable): ORT_TARGET, ORT_TARGET_DATA and ORT_TEAMS + handling. + (omp_check_private): Ignore ORT_TARGET and ORT_TARGET_DATA regions. + (gimplify_scan_omp_clauses): Handle OMP_CLAUSE_MAP, OMP_CLAUSE_TO, + OMP_CLAUSE_FROM, OMP_CLAUSE_NUM_TEAMS, OMP_CLAUSE_DIST_SCHEDULE + and OMP_CLAUSE_DEVICE. + (gimplify_adjust_omp_clauses): Likewise. + (gimplify_adjust_omp_clauses_1): Handle GOVD_MAP. Fix up + check for privatization by also testing for GOVD_LINEAR. + (gimplify_omp_for): Adjust gimple_build_omp_for caller. + Clear *expr_p. + (gimplify_omp_workshare): Handle also OMP_TARGET, OMP_TARGET_DATA + and OMP_TEAMS. Clear *expr_p. + (gimplify_omp_target_update): New function. + (gimplify_expr): Handle OMP_TARGET, OMP_TARGET_DATA, OMP_TARGET_UPDATE + and OMP_TEAMS. + 2013-05-20 Jakub Jelinek <jakub@redhat.com> * omp-low.c (expand_omp_simd): For collapse > 1 loops, diff --git a/gcc/cp/ChangeLog.gomp b/gcc/cp/ChangeLog.gomp index 69be3ded378..9f3f38c18c6 100644 --- a/gcc/cp/ChangeLog.gomp +++ b/gcc/cp/ChangeLog.gomp @@ -1,3 +1,21 @@ +2013-05-27 Jakub Jelinek <jakub@redhat.com> + + * parser.c (cp_parser_omp_clause_cancelkind): Remove diagnostics. + (cp_parser_omp_all_clauses): Require that OMP_CLAUSE_{TO,FROM} + and OMP_CLAUSE_{PARALLEL,FOR,SECTIONS,TASKGROUP} must be first in + the list of clauses. + (OMP_TEAMS_CLAUSE_MASK, OMP_TARGET_CLAUSE_MASK, + OMP_TARGET_DATA_CLAUSE_MASK, OMP_TARGET_UPDATE_CLAUSE_MASK, + OMP_DISTRIBUTE_CLAUSE_MASK): Define. + (cp_parser_omp_teams, cp_parser_omp_target, cp_parser_omp_target_data, + cp_parser_omp_target_update, cp_parser_omp_distribute): New functions. + (cp_parser_omp_construct): Handle PRAGMA_OMP_DISTRIBUTE and + PRAGMA_OMP_TEAMS. + (cp_parser_pragma): Handle PRAGMA_OMP_DISTRIBUTE, PRAGMA_OMP_TEAMS + and PRAGMA_OMP_TARGET. + * pt.c (tsubst_expr): Handle OMP_TEAMS, OMP_TARGET, OMP_TARGET_DATA + and OMP_TARGET_UPDATE. + 2013-05-09 Jakub Jelinek <jakub@redhat.com> * cp-tree.h (cp_decl_specifier_seq): Add omp_declare_simd_clauses diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d7b041c0b5c..5bbb46b1c87 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -26823,22 +26823,7 @@ cp_parser_omp_clause_cancelkind (cp_parser * /*parser*/, enum omp_clause_code code, tree list, location_t location) { - tree c; - - for (c = list; c; c = OMP_CLAUSE_CHAIN (c)) - switch (OMP_CLAUSE_CODE (c)) - { - case OMP_CLAUSE_PARALLEL: - case OMP_CLAUSE_FOR: - case OMP_CLAUSE_SECTIONS: - case OMP_CLAUSE_TASKGROUP: - error_at (location, "only one of %<parallel%>, %<for%>, %<sections%> " - "and %<taskgroup%> clauses can be specified"); - break; - default: - break; - } - c = build_omp_clause (location, code); + tree c = build_omp_clause (location, code); OMP_CLAUSE_CHAIN (c) = list; return c; } @@ -27260,7 +27245,6 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask, token = cp_lexer_peek_token (parser->lexer); c_kind = cp_parser_omp_clause_name (parser); - first = false; switch (c_kind) { @@ -27359,31 +27343,48 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask, clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL, clauses, token->location); c_name = "parallel"; + if (!first) + { + clause_not_first: + error_at (token->location, "%qs must be the first clause of %qs", + c_name, where); + clauses = prev; + } break; case PRAGMA_OMP_CLAUSE_FOR: clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR, clauses, token->location); c_name = "for"; + if (!first) + goto clause_not_first; break; case PRAGMA_OMP_CLAUSE_SECTIONS: clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS, clauses, token->location); c_name = "sections"; + if (!first) + goto clause_not_first; break; case PRAGMA_OMP_CLAUSE_TASKGROUP: clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP, clauses, token->location); c_name = "taskgroup"; + if (!first) + goto clause_not_first; break; case PRAGMA_OMP_CLAUSE_TO: clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO, clauses); c_name = "to"; + if (!first) + goto clause_not_first; break; case PRAGMA_OMP_CLAUSE_FROM: clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FROM, clauses); c_name = "from"; + if (!first) + goto clause_not_first; break; case PRAGMA_OMP_CLAUSE_UNIFORM: clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_UNIFORM, @@ -27441,6 +27442,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask, goto saw_error; } + first = false; + if (((mask >> c_kind) & 1) == 0) { /* Remove the invalid clause(s) from the list to avoid @@ -29013,6 +29016,180 @@ cp_parser_omp_cancellation_point (cp_parser *parser, cp_token *pragma_tok) } /* OpenMP 4.0: + # pragma omp teams teams-clause[optseq] new-line + structured-block */ + +#define OMP_TEAMS_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)) + +static tree +cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok) +{ + tree stmt = make_node (OMP_TEAMS); + TREE_TYPE (stmt) = void_type_node; + + OMP_TEAMS_CLAUSES (stmt) + = cp_parser_omp_all_clauses (parser, OMP_TEAMS_CLAUSE_MASK, + "#pragma omp teams", pragma_tok); + OMP_TEAMS_BODY (stmt) = cp_parser_omp_structured_block (parser); + + return add_stmt (stmt); +} + +/* OpenMP 4.0: + # pragma omp target data target-data-clause[optseq] new-line + structured-block */ + +#define OMP_TARGET_DATA_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)) + +static tree +cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok) +{ + tree stmt = make_node (OMP_TARGET_DATA); + TREE_TYPE (stmt) = void_type_node; + + OMP_TARGET_DATA_CLAUSES (stmt) + = cp_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK, + "#pragma omp target data", pragma_tok); + OMP_TARGET_DATA_BODY (stmt) = cp_parser_omp_structured_block (parser); + + SET_EXPR_LOCATION (stmt, pragma_tok->location); + return add_stmt (stmt); +} + +/* OpenMP 4.0: + # pragma omp target update target-update-clause[optseq] new-line */ + +#define OMP_TARGET_UPDATE_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)) + +static bool +cp_parser_omp_target_update (cp_parser *parser, cp_token *pragma_tok, + enum pragma_context context) +{ + if (context == pragma_stmt) + { + error_at (pragma_tok->location, + "%<#pragma omp target update%> may only be " + "used in compound statements"); + cp_parser_skip_to_pragma_eol (parser, pragma_tok); + return false; + } + + tree clauses + = cp_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK, + "#pragma omp target update", pragma_tok); + if (find_omp_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE + && find_omp_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE) + { + error_at (pragma_tok->location, + "%<#pragma omp target update must contain either " + "%<from%> or %<to%> clauses"); + return false; + } + + tree stmt = make_node (OMP_TARGET_UPDATE); + TREE_TYPE (stmt) = void_type_node; + OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses; + SET_EXPR_LOCATION (stmt, pragma_tok->location); + add_stmt (stmt); + return false; +} + +/* OpenMP 4.0: + # pragma omp target target-clause[optseq] new-line + structured-block */ + +#define OMP_TARGET_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)) + +static bool +cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok, + enum pragma_context context) +{ + if (context != pragma_stmt && context != pragma_compound) + { + cp_parser_error (parser, "expected declaration specifiers"); + cp_parser_skip_to_pragma_eol (parser, pragma_tok); + return false; + } + + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + const char *p = IDENTIFIER_POINTER (id); + + if (strcmp (p, "data") == 0) + { + cp_lexer_consume_token (parser->lexer); + cp_parser_omp_target_data (parser, pragma_tok); + return true; + } + else if (strcmp (p, "update") == 0) + { + cp_lexer_consume_token (parser->lexer); + return cp_parser_omp_target_update (parser, pragma_tok, context); + } + } + + tree stmt = make_node (OMP_TARGET); + TREE_TYPE (stmt) = void_type_node; + + OMP_TARGET_CLAUSES (stmt) + = cp_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK, + "#pragma omp target", pragma_tok); + OMP_TARGET_BODY (stmt) = cp_parser_omp_structured_block (parser); + + SET_EXPR_LOCATION (stmt, pragma_tok->location); + add_stmt (stmt); + return true; +} + +/* OpenMP 4.0: + #pragma omp distribute distribute-clause[optseq] new-line + for-loop */ + +#define OMP_DISTRIBUTE_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)) + +static tree +cp_parser_omp_distribute (cp_parser *parser, cp_token *pragma_tok) +{ + tree clauses, sb, ret; + unsigned int save; + + clauses = cp_parser_omp_all_clauses (parser, OMP_DISTRIBUTE_CLAUSE_MASK, + "#pragma omp distribute", pragma_tok); + + sb = begin_omp_structured_block (); + save = cp_parser_begin_omp_structured_block (parser); + + ret = cp_parser_omp_for_loop (parser, OMP_DISTRIBUTE, clauses, NULL); + + cp_parser_end_omp_structured_block (parser, save); + add_stmt (finish_omp_structured_block (sb)); + + return ret; +} + +/* OpenMP 4.0: # pragma omp declare simd declare-simd-clauses[optseq] new-line */ #define OMP_DECLARE_SIMD_CLAUSE_MASK \ @@ -29112,6 +29289,9 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok) case PRAGMA_OMP_CRITICAL: stmt = cp_parser_omp_critical (parser, pragma_tok); break; + case PRAGMA_OMP_DISTRIBUTE: + stmt = cp_parser_omp_distribute (parser, pragma_tok); + break; case PRAGMA_OMP_FOR: stmt = cp_parser_omp_for (parser, pragma_tok); break; @@ -29139,6 +29319,9 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok) case PRAGMA_OMP_TASKGROUP: cp_parser_omp_taskgroup (parser, pragma_tok); return; + case PRAGMA_OMP_TEAMS: + stmt = cp_parser_omp_teams (parser, pragma_tok); + break; default: gcc_unreachable (); } @@ -29609,6 +29792,7 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context) case PRAGMA_OMP_ATOMIC: case PRAGMA_OMP_CRITICAL: + case PRAGMA_OMP_DISTRIBUTE: case PRAGMA_OMP_FOR: case PRAGMA_OMP_MASTER: case PRAGMA_OMP_ORDERED: @@ -29618,11 +29802,15 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context) case PRAGMA_OMP_SINGLE: case PRAGMA_OMP_TASK: case PRAGMA_OMP_TASKGROUP: + case PRAGMA_OMP_TEAMS: if (context != pragma_stmt && context != pragma_compound) goto bad_stmt; cp_parser_omp_construct (parser, pragma_tok); return true; + case PRAGMA_OMP_TARGET: + return cp_parser_omp_target (parser, pragma_tok, context); + case PRAGMA_OMP_SECTION: error_at (pragma_tok->location, "%<#pragma omp section%> may only be used in " diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 284f6ab6539..9583afd51ce 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -13330,6 +13330,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, case OMP_SECTIONS: case OMP_SINGLE: + case OMP_TEAMS: + case OMP_TARGET_DATA: + case OMP_TARGET: tmp = tsubst_omp_clauses (OMP_CLAUSES (t), false, args, complain, in_decl); stmt = push_stmt_list (); @@ -13342,6 +13345,14 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, add_stmt (t); break; + case OMP_TARGET_UPDATE: + tmp = tsubst_omp_clauses (OMP_TARGET_UPDATE_CLAUSES (t), false, + args, complain, in_decl); + t = copy_node (t); + OMP_CLAUSES (t) = tmp; + add_stmt (t); + break; + case OMP_SECTION: case OMP_CRITICAL: case OMP_MASTER: diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index b06d194da65..cf61ef0d646 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -444,6 +444,8 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data) case GIMPLE_OMP_PARALLEL: case GIMPLE_OMP_TASK: + case GIMPLE_OMP_TARGET: + case GIMPLE_OMP_TEAMS: data->cannot_fallthru = false; lower_omp_directive (gsi, data); data->cannot_fallthru = false; diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 14872166946..ee264e10a88 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -1264,6 +1264,78 @@ dump_gimple_omp_single (pretty_printer *buffer, gimple gs, int spc, int flags) } } +/* Dump a GIMPLE_OMP_TARGET tuple on the pretty_printer BUFFER. */ + +static void +dump_gimple_omp_target (pretty_printer *buffer, gimple gs, int spc, int flags) +{ + const char *kind; + switch (gimple_omp_target_kind (gs)) + { + case GF_OMP_TARGET_KIND_REGION: + kind = ""; + break; + case GF_OMP_TARGET_KIND_DATA: + kind = " data"; + break; + case GF_OMP_TARGET_KIND_UPDATE: + kind = " update"; + break; + default: + gcc_unreachable (); + } + if (flags & TDF_RAW) + { + dump_gimple_fmt (buffer, spc, flags, "%G%s <%+BODY <%S>%nCLAUSES <", gs, + kind, gimple_omp_body (gs)); + dump_omp_clauses (buffer, gimple_omp_target_clauses (gs), spc, flags); + dump_gimple_fmt (buffer, spc, flags, " >"); + } + else + { + pp_string (buffer, "#pragma omp target"); + pp_string (buffer, kind); + dump_omp_clauses (buffer, gimple_omp_target_clauses (gs), spc, flags); + if (!gimple_seq_empty_p (gimple_omp_body (gs))) + { + newline_and_indent (buffer, spc + 2); + pp_character (buffer, '{'); + pp_newline (buffer); + dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags); + newline_and_indent (buffer, spc + 2); + pp_character (buffer, '}'); + } + } +} + +/* Dump a GIMPLE_OMP_TEAMS tuple on the pretty_printer BUFFER. */ + +static void +dump_gimple_omp_teams (pretty_printer *buffer, gimple gs, int spc, int flags) +{ + if (flags & TDF_RAW) + { + dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs, + gimple_omp_body (gs)); + dump_omp_clauses (buffer, gimple_omp_teams_clauses (gs), spc, flags); + dump_gimple_fmt (buffer, spc, flags, " >"); + } + else + { + pp_string (buffer, "#pragma omp teams"); + dump_omp_clauses (buffer, gimple_omp_teams_clauses (gs), spc, flags); + if (!gimple_seq_empty_p (gimple_omp_body (gs))) + { + newline_and_indent (buffer, spc + 2); + pp_character (buffer, '{'); + pp_newline (buffer); + dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags); + newline_and_indent (buffer, spc + 2); + pp_character (buffer, '}'); + } + } +} + /* Dump a GIMPLE_OMP_SECTIONS tuple on the pretty_printer BUFFER. */ static void @@ -2038,6 +2110,14 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags) dump_gimple_omp_single (buffer, gs, spc, flags); break; + case GIMPLE_OMP_TARGET: + dump_gimple_omp_target (buffer, gs, spc, flags); + break; + + case GIMPLE_OMP_TEAMS: + dump_gimple_omp_teams (buffer, gs, spc, flags); + break; + case GIMPLE_OMP_RETURN: dump_gimple_omp_return (buffer, gs, spc, flags); break; diff --git a/gcc/gimple.c b/gcc/gimple.c index f5074199381..7d137fdfc5a 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -908,13 +908,14 @@ gimple_build_omp_critical (gimple_seq body, tree name) PRE_BODY is the sequence of statements that are loop invariant. */ gimple -gimple_build_omp_for (gimple_seq body, tree clauses, size_t collapse, +gimple_build_omp_for (gimple_seq body, int kind, tree clauses, size_t collapse, gimple_seq pre_body) { gimple p = gimple_alloc (GIMPLE_OMP_FOR, 0); if (body) gimple_omp_set_body (p, body); gimple_omp_for_set_clauses (p, clauses); + gimple_omp_for_set_kind (p, kind); p->gimple_omp_for.collapse = collapse; p->gimple_omp_for.iter = ggc_alloc_cleared_vec_gimple_omp_for_iter (collapse); @@ -1094,6 +1095,41 @@ gimple_build_omp_single (gimple_seq body, tree clauses) } +/* Build a GIMPLE_OMP_TARGET statement. + + BODY is the sequence of statements that will be executed. + CLAUSES are any of the OMP target construct's clauses. */ + +gimple +gimple_build_omp_target (gimple_seq body, int kind, tree clauses) +{ + gimple p = gimple_alloc (GIMPLE_OMP_TARGET, 0); + if (body) + gimple_omp_set_body (p, body); + gimple_omp_target_set_clauses (p, clauses); + gimple_omp_target_set_kind (p, kind); + + return p; +} + + +/* Build a GIMPLE_OMP_TEAMS statement. + + BODY is the sequence of statements that will be executed. + CLAUSES are any of the OMP teams construct's clauses. */ + +gimple +gimple_build_omp_teams (gimple_seq body, tree clauses) +{ + gimple p = gimple_alloc (GIMPLE_OMP_TEAMS, 0); + if (body) + gimple_omp_set_body (p, body); + gimple_omp_teams_set_clauses (p, clauses); + + return p; +} + + /* Build a GIMPLE_OMP_ATOMIC_LOAD statement. */ gimple @@ -1610,6 +1646,20 @@ walk_gimple_op (gimple stmt, walk_tree_fn callback_op, return ret; break; + case GIMPLE_OMP_TARGET: + ret = walk_tree (gimple_omp_target_clauses_ptr (stmt), callback_op, wi, + pset); + if (ret) + return ret; + break; + + case GIMPLE_OMP_TEAMS: + ret = walk_tree (gimple_omp_teams_clauses_ptr (stmt), callback_op, wi, + pset); + if (ret) + return ret; + break; + case GIMPLE_OMP_ATOMIC_LOAD: ret = walk_tree (gimple_omp_atomic_load_lhs_ptr (stmt), callback_op, wi, pset); @@ -1786,6 +1836,8 @@ walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt, case GIMPLE_OMP_TASK: case GIMPLE_OMP_SECTIONS: case GIMPLE_OMP_SINGLE: + case GIMPLE_OMP_TARGET: + case GIMPLE_OMP_TEAMS: ret = walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), callback_stmt, callback_op, wi); if (ret) @@ -2308,6 +2360,8 @@ gimple_copy (gimple stmt) /* FALLTHRU */ case GIMPLE_OMP_SINGLE: + case GIMPLE_OMP_TARGET: + case GIMPLE_OMP_TEAMS: case GIMPLE_OMP_SECTION: case GIMPLE_OMP_MASTER: case GIMPLE_OMP_ORDERED: diff --git a/gcc/gimple.def b/gcc/gimple.def index acad572e353..8d75ada3ec3 100644 --- a/gcc/gimple.def +++ b/gcc/gimple.def @@ -287,7 +287,7 @@ DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP) BODY is a the sequence of statements to be executed by all threads. - CLAUSES is a TREE_LIST node with all the clauses. + CLAUSES is an OMP_CLAUSE chain with all the clauses. CHILD_FN is set when outlining the body of the parallel region. All the statements in BODY are moved into this newly created @@ -306,7 +306,7 @@ DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL) BODY is a the sequence of statements to be executed by all threads. - CLAUSES is a TREE_LIST node with all the clauses. + CLAUSES is an OMP_CLAUSE chain with all the clauses. CHILD_FN is set when outlining the body of the explicit task region. All the statements in BODY are moved into this newly created @@ -334,7 +334,7 @@ DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", GSS_OMP) /* OMP_SECTIONS <BODY, CLAUSES, CONTROL> represents #pragma omp sections. BODY is the sequence of statements in the sections body. - CLAUSES is a TREE_LIST node holding the list of associated clauses. + CLAUSES is an OMP_CLAUSE chain holding the list of associated clauses. CONTROL is a VAR_DECL used for deciding which of the sections to execute. */ DEFGSCODE(GIMPLE_OMP_SECTIONS, "gimple_omp_sections", GSS_OMP_SECTIONS) @@ -346,9 +346,21 @@ DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE) /* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single BODY is the sequence of statements inside the single section. - CLAUSES is a TREE_LIST node holding the associated clauses. */ + CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE) +/* GIMPLE_OMP_TARGET <BODY, CLAUSES> represents + #pragma omp target {,data,update} + BODY is the sequence of statements inside the target construct + (NULL for target update). + CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ +DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_SINGLE) + +/* GIMPLE_OMP_TEAMS <BODY, CLAUSES> represents #pragma omp teams + BODY is the sequence of statements inside the single section. + CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ +DEFGSCODE(GIMPLE_OMP_TEAMS, "gimple_omp_teams", GSS_OMP_SINGLE) + /* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction. PREDICT is one of the predictors from predict.def. diff --git a/gcc/gimple.h b/gcc/gimple.h index 93e2c2732f8..5060b282afd 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -115,6 +115,10 @@ enum gf_mask { GF_OMP_FOR_KIND_SIMD = 1 << 0, GF_OMP_FOR_KIND_FOR_SIMD = 2 << 0, GF_OMP_FOR_KIND_DISTRIBUTE = 3 << 0, + GF_OMP_TARGET_KIND_MASK = 3 << 0, + GF_OMP_TARGET_KIND_REGION = 0 << 0, + GF_OMP_TARGET_KIND_DATA = 1 << 0, + GF_OMP_TARGET_KIND_UPDATE = 2 << 0, /* True on an GIMPLE_OMP_RETURN statement if the return does not require a thread synchronization via some sort of barrier. The exact barrier @@ -618,7 +622,7 @@ struct GTY(()) gimple_statement_omp_continue { tree control_use; }; -/* GIMPLE_OMP_SINGLE */ +/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS */ struct GTY(()) gimple_statement_omp_single { /* [ WORD 1-7 ] */ @@ -805,7 +809,7 @@ gimple gimple_build_switch_nlabels (unsigned, tree, tree); gimple gimple_build_switch (tree, tree, vec<tree> ); gimple gimple_build_omp_parallel (gimple_seq, tree, tree, tree); gimple gimple_build_omp_task (gimple_seq, tree, tree, tree, tree, tree, tree); -gimple gimple_build_omp_for (gimple_seq, tree, size_t, gimple_seq); +gimple gimple_build_omp_for (gimple_seq, int, tree, size_t, gimple_seq); gimple gimple_build_omp_critical (gimple_seq, tree); gimple gimple_build_omp_section (gimple_seq); gimple gimple_build_omp_continue (tree, tree); @@ -815,6 +819,8 @@ gimple gimple_build_omp_ordered (gimple_seq); gimple gimple_build_omp_sections (gimple_seq, tree); gimple gimple_build_omp_sections_switch (void); gimple gimple_build_omp_single (gimple_seq, tree); +gimple gimple_build_omp_target (gimple_seq, int, tree); +gimple gimple_build_omp_teams (gimple_seq, tree); gimple gimple_build_cdt (tree, tree); gimple gimple_build_omp_atomic_load (tree, tree); gimple gimple_build_omp_atomic_store (tree); @@ -1264,6 +1270,8 @@ gimple_has_substatements (gimple g) case GIMPLE_OMP_TASK: case GIMPLE_OMP_SECTIONS: case GIMPLE_OMP_SINGLE: + case GIMPLE_OMP_TARGET: + case GIMPLE_OMP_TEAMS: case GIMPLE_OMP_CRITICAL: case GIMPLE_WITH_CLEANUP_EXPR: case GIMPLE_TRANSACTION: @@ -1691,7 +1699,7 @@ static inline unsigned gimple_omp_subcode (const_gimple s) { gcc_gimple_checking_assert (gimple_code (s) >= GIMPLE_OMP_ATOMIC_LOAD - && gimple_code (s) <= GIMPLE_OMP_SINGLE); + && gimple_code (s) <= GIMPLE_OMP_TEAMS); return s->gsbase.subcode; } @@ -4604,6 +4612,87 @@ gimple_omp_single_set_clauses (gimple gs, tree clauses) } +/* Return the clauses associated with OMP_TARGET GS. */ + +static inline tree +gimple_omp_target_clauses (const_gimple gs) +{ + GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); + return gs->gimple_omp_single.clauses; +} + + +/* Return a pointer to the clauses associated with OMP_TARGET GS. */ + +static inline tree * +gimple_omp_target_clauses_ptr (gimple gs) +{ + GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); + return &gs->gimple_omp_single.clauses; +} + + +/* Set CLAUSES to be the clauses associated with OMP_TARGET GS. */ + +static inline void +gimple_omp_target_set_clauses (gimple gs, tree clauses) +{ + GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); + gs->gimple_omp_single.clauses = clauses; +} + + +/* Return the kind of OMP target statemement. */ + +static inline int +gimple_omp_target_kind (const_gimple g) +{ + GIMPLE_CHECK (g, GIMPLE_OMP_TARGET); + return (gimple_omp_subcode (g) & GF_OMP_TARGET_KIND_MASK); +} + + +/* Set the OMP target kind. */ + +static inline void +gimple_omp_target_set_kind (gimple g, int kind) +{ + GIMPLE_CHECK (g, GIMPLE_OMP_TARGET); + g->gsbase.subcode = (g->gsbase.subcode & ~GF_OMP_TARGET_KIND_MASK) + | (kind & GF_OMP_TARGET_KIND_MASK); +} + + +/* Return the clauses associated with OMP_TEAMS GS. */ + +static inline tree +gimple_omp_teams_clauses (const_gimple gs) +{ + GIMPLE_CHECK (gs, GIMPLE_OMP_TEAMS); + return gs->gimple_omp_single.clauses; +} + + +/* Return a pointer to the clauses associated with OMP_TEAMS GS. */ + +static inline tree * +gimple_omp_teams_clauses_ptr (gimple gs) +{ + GIMPLE_CHECK (gs, GIMPLE_OMP_TEAMS); + return &gs->gimple_omp_single.clauses; +} + + +/* Set CLAUSES to be the clauses associated with OMP_TEAMS GS. */ + +static inline void +gimple_omp_teams_set_clauses (gimple gs, tree clauses) +{ + GIMPLE_CHECK (gs, GIMPLE_OMP_TEAMS); + gs->gimple_omp_single.clauses = clauses; +} + + /* Return the clauses associated with OMP_SECTIONS GS. */ static inline tree @@ -4946,6 +5035,8 @@ gimple_return_set_retval (gimple gs, tree retval) case GIMPLE_OMP_SECTIONS: \ case GIMPLE_OMP_SECTIONS_SWITCH: \ case GIMPLE_OMP_SINGLE: \ + case GIMPLE_OMP_TARGET: \ + case GIMPLE_OMP_TEAMS: \ case GIMPLE_OMP_SECTION: \ case GIMPLE_OMP_MASTER: \ case GIMPLE_OMP_ORDERED: \ diff --git a/gcc/gimplify.c b/gcc/gimplify.c index ec377f8fc84..4fea48ab37a 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -57,10 +57,11 @@ enum gimplify_omp_var_data GOVD_LASTPRIVATE = 32, GOVD_REDUCTION = 64, GOVD_LOCAL = 128, - GOVD_DEBUG_PRIVATE = 256, - GOVD_PRIVATE_OUTER_REF = 512, - GOVD_LINEAR = 1024, - GOVD_ALIGNED = 2048, + GOVD_MAP = 256, + GOVD_DEBUG_PRIVATE = 512, + GOVD_PRIVATE_OUTER_REF = 1024, + GOVD_LINEAR = 2048, + GOVD_ALIGNED = 4096, GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR | GOVD_LOCAL) @@ -74,7 +75,10 @@ enum omp_region_type ORT_PARALLEL = 2, ORT_COMBINED_PARALLEL = 3, ORT_TASK = 4, - ORT_UNTIED_TASK = 5 + ORT_UNTIED_TASK = 5, + ORT_TEAMS = 8, + ORT_TARGET_DATA = 16, + ORT_TARGET = 32 }; struct gimplify_omp_ctx @@ -5829,6 +5833,9 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags) the parameters of the type. */ if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) { + /* To be handled later. */ + gcc_assert ((flags & GOVD_MAP) == 0); + /* Add the pointer replacement variable as PRIVATE if the variable replacement is private, else FIRSTPRIVATE since we'll need the address of the original variable either for SHARED, or for the @@ -5870,6 +5877,9 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags) } else if (lang_hooks.decls.omp_privatize_by_reference (decl)) { + /* To be handled later. */ + gcc_assert ((flags & GOVD_MAP) == 0); + gcc_assert ((flags & GOVD_LOCAL) == 0); omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl)); @@ -5896,6 +5906,22 @@ omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl, tree decl2) { splay_tree_node n; + struct gimplify_omp_ctx *octx; + + for (octx = ctx; octx; octx = octx->outer_context) + if (octx->region_type == ORT_TARGET) + { + n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); + if (n == NULL) + { + error ("threadprivate variable %qE used in target region", + DECL_NAME (decl)); + error_at (octx->location, "enclosing target region"); + splay_tree_insert (octx->variables, (splay_tree_key)decl, 0); + } + if (decl2) + splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0); + } if (ctx->region_type != ORT_UNTIED_TASK) return false; @@ -5944,13 +5970,24 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code) } n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); + if (ctx->region_type == ORT_TARGET) + { + if (n == NULL) + omp_add_variable (ctx, decl, GOVD_MAP | flags); + else + n->value |= flags; + ret = lang_hooks.decls.omp_disregard_value_expr (decl, true); + goto do_outer; + } + if (n == NULL) { enum omp_clause_default_kind default_kind, kind; struct gimplify_omp_ctx *octx; if (ctx->region_type == ORT_WORKSHARE - || ctx->region_type == ORT_SIMD) + || ctx->region_type == ORT_SIMD + || ctx->region_type == ORT_TARGET_DATA) goto do_outer; /* ??? Some compiler-generated variables (like SAVE_EXPRs) could be @@ -5964,12 +6001,24 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code) switch (default_kind) { case OMP_CLAUSE_DEFAULT_NONE: - error ("%qE not specified in enclosing parallel", - DECL_NAME (lang_hooks.decls.omp_report_decl (decl))); if ((ctx->region_type & ORT_TASK) != 0) - error_at (ctx->location, "enclosing task"); + { + error ("%qE not specified in enclosing task", + DECL_NAME (lang_hooks.decls.omp_report_decl (decl))); + error_at (ctx->location, "enclosing task"); + } + else if (ctx->region_type == ORT_TEAMS) + { + error ("%qE not specified in enclosing teams construct", + DECL_NAME (lang_hooks.decls.omp_report_decl (decl))); + error_at (ctx->location, "enclosing teams construct"); + } else - error_at (ctx->location, "enclosing parallel"); + { + error ("%qE not specified in enclosing parallel", + DECL_NAME (lang_hooks.decls.omp_report_decl (decl))); + error_at (ctx->location, "enclosing parallel"); + } /* FALLTHRU */ case OMP_CLAUSE_DEFAULT_SHARED: flags |= GOVD_SHARED; @@ -5989,13 +6038,15 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code) { splay_tree_node n2; + if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0) + continue; n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl); if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED) { flags |= GOVD_FIRSTPRIVATE; break; } - if ((octx->region_type & ORT_PARALLEL) != 0) + if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0) break; } if (flags & GOVD_FIRSTPRIVATE) @@ -6137,6 +6188,9 @@ omp_check_private (struct gimplify_omp_ctx *ctx, tree decl) /* References might be private, but might be shared too. */ || lang_hooks.decls.omp_privatize_by_reference (decl)); + if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0) + continue; + n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); if (n != NULL) return (n->value & GOVD_SHARED) == 0; @@ -6204,6 +6258,20 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, } flags = GOVD_LINEAR | GOVD_EXPLICIT; goto do_add; + case OMP_CLAUSE_MAP: + flags = GOVD_MAP | GOVD_EXPLICIT; + notice_outer = false; + goto do_add; + + case OMP_CLAUSE_TO: + case OMP_CLAUSE_FROM: + decl = OMP_CLAUSE_DECL (c); + if (error_operand_p (decl)) + { + remove = true; + break; + } + goto do_notice; do_add: decl = OMP_CLAUSE_DECL (c); @@ -6292,6 +6360,9 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, case OMP_CLAUSE_SCHEDULE: case OMP_CLAUSE_NUM_THREADS: + case OMP_CLAUSE_NUM_TEAMS: + case OMP_CLAUSE_DIST_SCHEDULE: + case OMP_CLAUSE_DEVICE: if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL, is_gimple_val, fb_rvalue) == GS_ERROR) remove = true; @@ -6357,12 +6428,40 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data) gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_PRIVATE); private_debug = true; } + else if (flags & GOVD_MAP) + private_debug = false; else private_debug = lang_hooks.decls.omp_private_debug_clause (decl, !!(flags & GOVD_SHARED)); if (private_debug) code = OMP_CLAUSE_PRIVATE; + else if (flags & GOVD_MAP) + { + /* If decl is already in the enclosing device data environment, + the spec says that it should just be used and no init/assignment + should be done. If there was any privatization in between though, + it means that original decl might be in the enclosing device data + environment, but the privatized might not. */ + struct gimplify_omp_ctx *ctx; + for (ctx = gimplify_omp_ctxp->outer_context; + ctx; ctx = ctx->outer_context) + { + n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); + if (n == NULL) + continue; + if (ctx->region_type == ORT_TARGET_DATA) + { + if ((n->value & GOVD_MAP) != 0) + return 0; + } + else if ((n->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE + | GOVD_PRIVATE | GOVD_REDUCTION + | GOVD_LINEAR)) != 0) + break; + } + code = OMP_CLAUSE_MAP; + } else if (flags & GOVD_SHARED) { if (is_global_var (decl)) @@ -6373,7 +6472,8 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data) splay_tree_node on = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE - | GOVD_PRIVATE | GOVD_REDUCTION)) != 0) + | GOVD_PRIVATE | GOVD_REDUCTION + | GOVD_LINEAR)) != 0) break; ctx = ctx->outer_context; } @@ -6400,6 +6500,8 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data) OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1; else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF)) OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1; + else if (code == OMP_CLAUSE_MAP) + OMP_CLAUSE_MAP_KIND (clause) = OMP_CLAUSE_MAP_TOFROM; *list_p = clause; lang_hooks.decls.omp_finish_clause (clause); @@ -6517,11 +6619,47 @@ gimplify_adjust_omp_clauses (tree *list_p) } break; + case OMP_CLAUSE_MAP: + decl = OMP_CLAUSE_DECL (c); + n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); + remove = false; + if (ctx->region_type == ORT_TARGET && !(n->value & GOVD_SEEN)) + remove = true; + else + { + /* If decl is already in the enclosing device data environment, + the spec says that it should just be used and no init/assignment + should be done. If there was any privatization in between though, + it means that original decl might be in the enclosing device data + environment, but the privatized might not. */ + struct gimplify_omp_ctx *octx; + for (octx = ctx->outer_context; octx; octx = octx->outer_context) + { + n = splay_tree_lookup (octx->variables, + (splay_tree_key) decl); + if (n == NULL) + continue; + if (octx->region_type == ORT_TARGET_DATA) + { + if ((n->value & GOVD_MAP) != 0) + remove = true; + } + else if ((n->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE + | GOVD_PRIVATE | GOVD_REDUCTION + | GOVD_LINEAR)) != 0) + break; + } + } + break; + case OMP_CLAUSE_REDUCTION: case OMP_CLAUSE_COPYIN: case OMP_CLAUSE_COPYPRIVATE: case OMP_CLAUSE_IF: case OMP_CLAUSE_NUM_THREADS: + case OMP_CLAUSE_NUM_TEAMS: + case OMP_CLAUSE_DIST_SCHEDULE: + case OMP_CLAUSE_DEVICE: case OMP_CLAUSE_SCHEDULE: case OMP_CLAUSE_NOWAIT: case OMP_CLAUSE_ORDERED: @@ -6532,6 +6670,8 @@ gimplify_adjust_omp_clauses (tree *list_p) case OMP_CLAUSE_MERGEABLE: case OMP_CLAUSE_PROC_BIND: case OMP_CLAUSE_SAFELEN: + case OMP_CLAUSE_TO: + case OMP_CLAUSE_FROM: break; default: @@ -6847,25 +6987,19 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (for_stmt)); - gfor = gimple_build_omp_for (for_body, OMP_FOR_CLAUSES (for_stmt), - TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)), - for_pre_body); + int kind; switch (TREE_CODE (for_stmt)) { - case OMP_FOR: - break; - case OMP_SIMD: - gimple_omp_for_set_kind (gfor, GF_OMP_FOR_KIND_SIMD); - break; - case OMP_FOR_SIMD: - gimple_omp_for_set_kind (gfor, GF_OMP_FOR_KIND_FOR_SIMD); - break; - case OMP_DISTRIBUTE: - gimple_omp_for_set_kind (gfor, GF_OMP_FOR_KIND_DISTRIBUTE); - break; + case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break; + case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break; + case OMP_FOR_SIMD: kind = GF_OMP_FOR_KIND_FOR_SIMD; break; + case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break; default: gcc_unreachable (); } + gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (for_stmt), + TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)), + for_pre_body); for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) { @@ -6880,11 +7014,15 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) } gimplify_seq_add_stmt (pre_p, gfor); - return ret == GS_ALL_DONE ? GS_ALL_DONE : GS_ERROR; + if (ret != GS_ALL_DONE) + return GS_ERROR; + *expr_p = NULL_TREE; + return GS_ALL_DONE; } -/* Gimplify the gross structure of other OpenMP worksharing constructs. - In particular, OMP_SECTIONS and OMP_SINGLE. */ +/* Gimplify the gross structure of other OpenMP constructs. + In particular, OMP_SECTIONS, OMP_SINGLE, OMP_TARGET, OMP_TARGET_DATA + and OMP_TEAMS. */ static void gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p) @@ -6892,19 +7030,72 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p) tree expr = *expr_p; gimple stmt; gimple_seq body = NULL; + enum omp_region_type ort = ORT_WORKSHARE; - gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ORT_WORKSHARE); + switch (TREE_CODE (expr)) + { + case OMP_SECTIONS: + case OMP_SINGLE: + break; + case OMP_TARGET: + ort = ORT_TARGET; + break; + case OMP_TARGET_DATA: + ort = ORT_TARGET_DATA; + break; + case OMP_TEAMS: + ort = ORT_TEAMS; + break; + default: + gcc_unreachable (); + } + gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort); gimplify_and_add (OMP_BODY (expr), &body); gimplify_adjust_omp_clauses (&OMP_CLAUSES (expr)); - if (TREE_CODE (expr) == OMP_SECTIONS) - stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr)); - else if (TREE_CODE (expr) == OMP_SINGLE) - stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr)); - else - gcc_unreachable (); + switch (TREE_CODE (expr)) + { + case OMP_SECTIONS: + stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr)); + break; + case OMP_SINGLE: + stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr)); + break; + case OMP_TARGET: + stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION, + OMP_CLAUSES (expr)); + break; + case OMP_TARGET_DATA: + stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA, + OMP_CLAUSES (expr)); + break; + case OMP_TEAMS: + stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr)); + break; + default: + gcc_unreachable (); + } + + gimplify_seq_add_stmt (pre_p, stmt); + *expr_p = NULL_TREE; +} + +/* Gimplify the gross structure of OpenMP target update construct. */ + +static void +gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p) +{ + tree expr = *expr_p; + gimple stmt; + + gimplify_scan_omp_clauses (&OMP_TARGET_UPDATE_CLAUSES (expr), pre_p, + ORT_WORKSHARE); + gimplify_adjust_omp_clauses (&OMP_TARGET_UPDATE_CLAUSES (expr)); + stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_UPDATE, + OMP_TARGET_UPDATE_CLAUSES (expr)); gimplify_seq_add_stmt (pre_p, stmt); + *expr_p = NULL_TREE; } /* A subroutine of gimplify_omp_atomic. The front end is supposed to have @@ -7811,10 +8002,18 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, case OMP_SECTIONS: case OMP_SINGLE: + case OMP_TARGET: + case OMP_TARGET_DATA: + case OMP_TEAMS: gimplify_omp_workshare (expr_p, pre_p); ret = GS_ALL_DONE; break; + case OMP_TARGET_UPDATE: + gimplify_omp_target_update (expr_p, pre_p); + ret = GS_ALL_DONE; + break; + case OMP_SECTION: case OMP_MASTER: case OMP_ORDERED: diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 6d964840839..7c795624a7a 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -1483,6 +1483,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) case OMP_CLAUSE_IF: case OMP_CLAUSE_NUM_THREADS: case OMP_CLAUSE_SCHEDULE: + case OMP_CLAUSE_DIST_SCHEDULE: if (ctx->outer) scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer); break; @@ -1548,6 +1549,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) case OMP_CLAUSE_IF: case OMP_CLAUSE_NUM_THREADS: case OMP_CLAUSE_SCHEDULE: + case OMP_CLAUSE_DIST_SCHEDULE: case OMP_CLAUSE_NOWAIT: case OMP_CLAUSE_ORDERED: case OMP_CLAUSE_COLLAPSE: diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 721c4f77d4a..c9a218bda5d 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -592,6 +592,8 @@ make_edges (void) case GIMPLE_OMP_TASK: case GIMPLE_OMP_FOR: case GIMPLE_OMP_SINGLE: + case GIMPLE_OMP_TARGET: + case GIMPLE_OMP_TEAMS: case GIMPLE_OMP_MASTER: case GIMPLE_OMP_ORDERED: case GIMPLE_OMP_CRITICAL: diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 57af7de2c09..b7b2b364dcc 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1298,7 +1298,8 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id) case GIMPLE_OMP_FOR: s1 = remap_gimple_seq (gimple_omp_body (stmt), id); s2 = remap_gimple_seq (gimple_omp_for_pre_body (stmt), id); - copy = gimple_build_omp_for (s1, gimple_omp_for_clauses (stmt), + copy = gimple_build_omp_for (s1, gimple_omp_for_kind (stmt), + gimple_omp_for_clauses (stmt), gimple_omp_for_collapse (stmt), s2); { size_t i; @@ -1345,6 +1346,19 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id) (s1, gimple_omp_single_clauses (stmt)); break; + case GIMPLE_OMP_TARGET: + s1 = remap_gimple_seq (gimple_omp_body (stmt), id); + copy = gimple_build_omp_target + (s1, gimple_omp_target_kind (stmt), + gimple_omp_target_clauses (stmt)); + break; + + case GIMPLE_OMP_TEAMS: + s1 = remap_gimple_seq (gimple_omp_body (stmt), id); + copy = gimple_build_omp_teams + (s1, gimple_omp_teams_clauses (stmt)); + break; + case GIMPLE_OMP_CRITICAL: s1 = remap_gimple_seq (gimple_omp_body (stmt), id); copy @@ -3716,6 +3730,8 @@ estimate_num_insns (gimple stmt, eni_weights *weights) case GIMPLE_OMP_SECTION: case GIMPLE_OMP_SECTIONS: case GIMPLE_OMP_SINGLE: + case GIMPLE_OMP_TARGET: + case GIMPLE_OMP_TEAMS: return (weights->omp_cost + estimate_num_insns_seq (gimple_omp_body (stmt), weights)); diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index fe44679a013..41548821acf 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -1291,6 +1291,22 @@ convert_nonlocal_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, info->suppress_expansion = save_suppress; break; + case GIMPLE_OMP_TARGET: + save_suppress = info->suppress_expansion; + convert_nonlocal_omp_clauses (gimple_omp_target_clauses_ptr (stmt), wi); + walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op, + info, gimple_omp_body_ptr (stmt)); + info->suppress_expansion = save_suppress; + break; + + case GIMPLE_OMP_TEAMS: + save_suppress = info->suppress_expansion; + convert_nonlocal_omp_clauses (gimple_omp_teams_clauses_ptr (stmt), wi); + walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op, + info, gimple_omp_body_ptr (stmt)); + info->suppress_expansion = save_suppress; + break; + case GIMPLE_OMP_SECTION: case GIMPLE_OMP_MASTER: case GIMPLE_OMP_ORDERED: @@ -1714,6 +1730,22 @@ convert_local_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, info->suppress_expansion = save_suppress; break; + case GIMPLE_OMP_TARGET: + save_suppress = info->suppress_expansion; + convert_local_omp_clauses (gimple_omp_target_clauses_ptr (stmt), wi); + walk_body (convert_local_reference_stmt, convert_local_reference_op, + info, gimple_omp_body_ptr (stmt)); + info->suppress_expansion = save_suppress; + break; + + case GIMPLE_OMP_TEAMS: + save_suppress = info->suppress_expansion; + convert_local_omp_clauses (gimple_omp_teams_clauses_ptr (stmt), wi); + walk_body (convert_local_reference_stmt, convert_local_reference_op, + info, gimple_omp_body_ptr (stmt)); + info->suppress_expansion = save_suppress; + break; + case GIMPLE_OMP_SECTION: case GIMPLE_OMP_MASTER: case GIMPLE_OMP_ORDERED: @@ -2071,6 +2103,8 @@ convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p, case GIMPLE_OMP_SECTIONS: case GIMPLE_OMP_SECTION: case GIMPLE_OMP_SINGLE: + case GIMPLE_OMP_TARGET: + case GIMPLE_OMP_TEAMS: case GIMPLE_OMP_MASTER: case GIMPLE_OMP_ORDERED: case GIMPLE_OMP_CRITICAL: diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index cea6f030c0a..1e6bb07b398 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -1686,7 +1686,7 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data, t = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE); OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC; - for_stmt = gimple_build_omp_for (NULL, t, 1, NULL); + for_stmt = gimple_build_omp_for (NULL, GF_OMP_FOR_KIND_FOR, t, 1, NULL); gimple_set_location (for_stmt, loc); gimple_omp_for_set_index (for_stmt, 0, initvar); gimple_omp_for_set_initial (for_stmt, 0, cvar_init); diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index 2bdf9dcd232..ace9e22ebd1 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -2347,6 +2347,27 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, pp_string (buffer, "#pragma omp distribute"); goto dump_omp_loop; + case OMP_TEAMS: + pp_string (buffer, "#pragma omp teams"); + dump_omp_clauses (buffer, OMP_TEAMS_CLAUSES (node), spc, flags); + goto dump_omp_body; + + case OMP_TARGET_DATA: + pp_string (buffer, "#pragma omp target data"); + dump_omp_clauses (buffer, OMP_TARGET_DATA_CLAUSES (node), spc, flags); + goto dump_omp_body; + + case OMP_TARGET: + pp_string (buffer, "#pragma omp target"); + dump_omp_clauses (buffer, OMP_TARGET_CLAUSES (node), spc, flags); + goto dump_omp_body; + + case OMP_TARGET_UPDATE: + pp_string (buffer, "#pragma omp target update"); + dump_omp_clauses (buffer, OMP_TARGET_UPDATE_CLAUSES (node), spc, flags); + is_expr = false; + break; + dump_omp_loop: dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags); diff --git a/gcc/tree.def b/gcc/tree.def index 147b6805b0a..a2e53e65f72 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -1042,6 +1042,21 @@ DEFTREECODE (OMP_FOR_SIMD, "omp_for_simd", tcc_statement, 6) Operands like for OMP_FOR. */ DEFTREECODE (OMP_DISTRIBUTE, "omp_distribute", tcc_statement, 6) +/* OpenMP - #pragma omp teams [clause1 ... clauseN] + Operand 0: OMP_TEAMS_BODY: Teams body. + Operand 1: OMP_TEAMS_CLAUSES: List of clauses. */ +DEFTREECODE (OMP_TEAMS, "omp_teams", tcc_statement, 2) + +/* OpenMP - #pragma omp target data [clause1 ... clauseN] + Operand 0: OMP_TARGET_DATA_BODY: Target data construct body. + Operand 1: OMP_TARGET_DATA_CLAUSES: List of clauses. */ +DEFTREECODE (OMP_TARGET_DATA, "omp_target_data", tcc_statement, 2) + +/* OpenMP - #pragma omp target [clause1 ... clauseN] + Operand 0: OMP_TARGET_BODY: Target construct body. + Operand 1: OMP_TARGET_CLAUSES: List of clauses. */ +DEFTREECODE (OMP_TARGET, "omp_target", tcc_statement, 2) + /* OpenMP - #pragma omp sections [clause1 ... clauseN] Operand 0: OMP_SECTIONS_BODY: Sections body. Operand 1: OMP_SECTIONS_CLAUSES: List of clauses. */ @@ -1069,6 +1084,10 @@ DEFTREECODE (OMP_ORDERED, "omp_ordered", tcc_statement, 1) Operand 1: OMP_CRITICAL_NAME: Identifier for critical section. */ DEFTREECODE (OMP_CRITICAL, "omp_critical", tcc_statement, 2) +/* OpenMP - #pragma omp target update [clause1 ... clauseN] + Operand 0: OMP_TARGET_UPDATE_CLAUSES: List of clauses. */ +DEFTREECODE (OMP_TARGET_UPDATE, "omp_target_update", tcc_statement, 1) + /* OMP_ATOMIC through OMP_ATOMIC_CAPTURE_NEW must be consecutive, or OMP_ATOMIC_SEQ_CST needs adjusting. */ diff --git a/gcc/tree.h b/gcc/tree.h index 49da30a3186..f2a58a09e0d 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1863,6 +1863,20 @@ extern void protected_set_expr_location (tree, location_t); #define OMP_CRITICAL_BODY(NODE) TREE_OPERAND (OMP_CRITICAL_CHECK (NODE), 0) #define OMP_CRITICAL_NAME(NODE) TREE_OPERAND (OMP_CRITICAL_CHECK (NODE), 1) +#define OMP_TEAMS_BODY(NODE) TREE_OPERAND (OMP_TEAMS_CHECK (NODE), 0) +#define OMP_TEAMS_CLAUSES(NODE) TREE_OPERAND (OMP_TEAMS_CHECK (NODE), 1) + +#define OMP_TARGET_DATA_BODY(NODE) \ + TREE_OPERAND (OMP_TARGET_DATA_CHECK (NODE), 0) +#define OMP_TARGET_DATA_CLAUSES(NODE)\ + TREE_OPERAND (OMP_TARGET_DATA_CHECK (NODE), 1) + +#define OMP_TARGET_BODY(NODE) TREE_OPERAND (OMP_TARGET_CHECK (NODE), 0) +#define OMP_TARGET_CLAUSES(NODE) TREE_OPERAND (OMP_TARGET_CHECK (NODE), 1) + +#define OMP_TARGET_UPDATE_CLAUSES(NODE)\ + TREE_OPERAND (OMP_TARGET_UPDATE_CHECK (NODE), 0) + #define OMP_CLAUSE_CHAIN(NODE) TREE_CHAIN (OMP_CLAUSE_CHECK (NODE)) #define OMP_CLAUSE_DECL(NODE) \ OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \ |