diff options
Diffstat (limited to 'gcc/c/c-parser.c')
-rw-r--r-- | gcc/c/c-parser.c | 93 |
1 files changed, 87 insertions, 6 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 055e650..81919a8 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -11720,6 +11720,8 @@ c_parser_omp_clause_name (c_parser *parser) result = PRAGMA_OACC_CLAUSE_DEVICEPTR; else if (!strcmp ("device_resident", p)) result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT; + else if (!strcmp ("device_type", p)) + result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE; else if (!strcmp ("dist_schedule", p)) result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE; break; @@ -14863,6 +14865,50 @@ c_parser_omp_clause_proc_bind (c_parser *parser, tree list) return list; } +/* OpenMP 5.0: + device_type ( host | nohost | any ) */ + +static tree +c_parser_omp_clause_device_type (c_parser *parser, tree list) +{ + location_t clause_loc = c_parser_peek_token (parser)->location; + enum omp_clause_device_type_kind kind; + tree c; + + matching_parens parens; + if (!parens.require_open (parser)) + return list; + + if (c_parser_next_token_is (parser, CPP_NAME)) + { + const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); + if (strcmp ("host", p) == 0) + kind = OMP_CLAUSE_DEVICE_TYPE_HOST; + else if (strcmp ("nohost", p) == 0) + kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST; + else if (strcmp ("any", p) == 0) + kind = OMP_CLAUSE_DEVICE_TYPE_ANY; + else + goto invalid_kind; + } + else + goto invalid_kind; + + /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, + "device_type"); */ + c_parser_consume_token (parser); + parens.skip_until_found_close (parser); + c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE); + OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind; + OMP_CLAUSE_CHAIN (c) = list; + return c; + + invalid_kind: + c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>"); + parens.skip_until_found_close (parser); + return list; +} + /* OpenMP 4.0: to ( variable-list ) */ @@ -15350,6 +15396,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask, clauses = c_parser_omp_clause_proc_bind (parser, clauses); c_name = "proc_bind"; break; + case PRAGMA_OMP_CLAUSE_DEVICE_TYPE: + clauses = c_parser_omp_clause_device_type (parser, clauses); + c_name = "device_type"; + break; case PRAGMA_OMP_CLAUSE_SAFELEN: clauses = c_parser_omp_clause_safelen (parser, clauses); c_name = "safelen"; @@ -18997,13 +19047,15 @@ c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms, #define OMP_DECLARE_TARGET_CLAUSE_MASK \ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \ - | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)) static void c_parser_omp_declare_target (c_parser *parser) { - location_t loc = c_parser_peek_token (parser)->location; tree clauses = NULL_TREE; + int device_type = 0; + bool only_device_type = true; if (c_parser_next_token_is (parser, CPP_NAME)) clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK, "#pragma omp declare target"); @@ -19020,16 +19072,18 @@ c_parser_omp_declare_target (c_parser *parser) current_omp_declare_target_attribute++; return; } - if (current_omp_declare_target_attribute) - error_at (loc, "%<#pragma omp declare target%> with clauses in between " - "%<#pragma omp declare target%> without clauses and " - "%<#pragma omp end declare target%>"); + for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE) + device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c); for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) { + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE) + continue; tree t = OMP_CLAUSE_DECL (c), id; tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t)); tree at2 = lookup_attribute ("omp declare target link", DECL_ATTRIBUTES (t)); + only_device_type = false; if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK) { id = get_identifier ("omp declare target link"); @@ -19062,7 +19116,34 @@ c_parser_omp_declare_target (c_parser *parser) } } } + if (TREE_CODE (t) != FUNCTION_DECL) + continue; + if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0) + { + tree at3 = lookup_attribute ("omp declare target host", + DECL_ATTRIBUTES (t)); + if (at3 == NULL_TREE) + { + id = get_identifier ("omp declare target host"); + DECL_ATTRIBUTES (t) + = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); + } + } + if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0) + { + tree at3 = lookup_attribute ("omp declare target nohost", + DECL_ATTRIBUTES (t)); + if (at3 == NULL_TREE) + { + id = get_identifier ("omp declare target nohost"); + DECL_ATTRIBUTES (t) + = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); + } + } } + if (device_type && only_device_type) + warning_at (OMP_CLAUSE_LOCATION (clauses), 0, + "directive with only %<device_type%> clauses ignored"); } static void |