From patchwork Fri Sep 30 16:37:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1599 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp575871wrs; Fri, 30 Sep 2022 09:39:11 -0700 (PDT) X-Google-Smtp-Source: AMsMyM7V3kVHS21lmuNsnrOafCzqRoTcLyJK4XsxG8ZgLxeKSUYnk2pftp0hnpd0E/iTqFlIKrO8 X-Received: by 2002:a17:907:1c0b:b0:788:4c5:32d7 with SMTP id nc11-20020a1709071c0b00b0078804c532d7mr2968128ejc.223.1664555951007; Fri, 30 Sep 2022 09:39:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664555951; cv=none; d=google.com; s=arc-20160816; b=ymqrF6JQVe+uVQaDjC/QaDpONZDOdh5isDNuvpuB1/oC9FXf452Hf5fXo5RRzWjvKE 5qkfn8GjMY+ns94CgRN1+IgXA0OPPrYoYuTVKU2BLCfalC3uTZRi7L85HgVTND53fsnT LskfGAixyzUzEbcENyykENd1iZK3+c2FM9HOxkzIVT74hKZUV4tKanv4YAhsBOT8Jqci Nz1KA/BzMDCz4tTMCqGn3VBmQOHwE9rYr+EJrmGqnq6+o0m9T3DB0vh+srLHW792QCzh iSeqGiSVNHq/eSv3VmGJuG0W7B6biTORv7Y0NXFq1wdK74sIxeQvW9BnFSKkyzHBh6qq 8j0A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :content-disposition:mime-version:message-id:subject:to:date :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=KktzyTBG+tu9+6V5ZHyyMuHfiPE9BpqRi2udOb8YoDI=; b=Y2KpSPm260kLDSOOzv8vhT6x5vNjvJKwecddIE2Mlct9E4WqRSfN7VgHqNK8J0I1r4 beP0HQrUNiA6xPVMJ5jo47gU+mD0j1144qAahdn+VSgMugk158ZcFOxua4uf8zIoQ4yU shtFPZ4zZkA1aKSQZPka8iscjvm9JvS1sThHb3lc8xFchPUFM914CfsePrJmt+kmxVcy eXIy324n1uxW1OKSLUSenzhid43AqT8WK9ZH6rwFvymVgclgFUs6axaJxzID6U8Y/3gY EZ3Jym0HwtlFgnypOgZQUJ3BIqYMFRQZo/yotx01PAD9FL9d4vgSvLWSUR4wjk1xdROO m1Cw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=rT8NKjpN; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id bj26-20020a170906b05a00b0073d5b605cefsi1896134ejb.261.2022.09.30.09.39.10 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Sep 2022 09:39:10 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=rT8NKjpN; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CEB6D3854161 for ; Fri, 30 Sep 2022 16:39:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CEB6D3854161 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1664555948; bh=KktzyTBG+tu9+6V5ZHyyMuHfiPE9BpqRi2udOb8YoDI=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=rT8NKjpNvpzIEmfCNNa3pGwQAQ3iu+928RzuQiCV01IZ++eMZDNjULJWlUVRanTtC +ob8Rv92L3CbIgi5+xyzJjRAhvGt8uAwi9ADTwvfPvJ/HJpZjNpiEe30K8e9RtZfM4 pik+IqQpgtTPim5kXZvwb120LMMMIk7Pzx77Hjo8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 97866385415A for ; Fri, 30 Sep 2022 16:38:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 97866385415A Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-581-TpbjfWcFNMqoGR7gKe3V1A-1; Fri, 30 Sep 2022 12:38:03 -0400 X-MC-Unique: TpbjfWcFNMqoGR7gKe3V1A-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 448F485A59D; Fri, 30 Sep 2022 16:38:03 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.194]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BEA282087440; Fri, 30 Sep 2022 16:38:02 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 28UGbxem071604 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 30 Sep 2022 18:38:00 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 28UGbxrH071603; Fri, 30 Sep 2022 18:37:59 +0200 Date: Fri, 30 Sep 2022 18:37:58 +0200 To: Tobias Burnus Subject: [PATCH] openmp: Add begin declare target support Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-25.0 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Cc: gcc-patches@gcc.gnu.org Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1745413420661426557?= X-GMAIL-MSGID: =?utf-8?q?1745413420661426557?= Hi! The following patch adds support for the begin declare target construct, which is another spelling for declare target construct without clauses (where it needs paired end declare target), but unlike that one accepts clauses. This is an OpenMP 5.1 feature, implemented with 5.2 clarification because in 5.1 we had a restriction in the declare target chapter shared by declare target and begin declare target that if there are any clauses specified at least one of them needs to be to or link. But that was of course meant just for declare target and not begin declare target, because begin declare target doesn't even allow to/link/enter clauses. In addition to that, the patch also makes device_type clause duplication an error (as stated in 5.1) and similarly makes declare target with just device_type clause an error rather than warning. What this patch doesn't do is: 1) OpenMP 5.1 also added an indirect clause, we don't support that neither on declare target nor begin declare target and I couldn't find it in our features pages (neither libgomp.texi nor web) 2) I think device_type(nohost)/device_type(host) support can't work for variables (in 5.0 it only talked about procedures so this could be also thought as 5.1 feature that we should just add to the list and implement) 3) I don't see any use of the "omp declare target nohost" attribute, so I'm not sure if device_type(nohost) works at all Will commit this tomorrow if bootstrap/regtest succeeds. 2022-09-30 Jakub Jelinek gcc/c-family/ * c-omp.cc (c_omp_directives): Uncomment begin declare target entry. gcc/c/ * c-lang.h (struct c_omp_declare_target_attr): New type. (current_omp_declare_target_attribute): Change type from int to vec *. * c-parser.cc (c_parser_translation_unit): Adjust for that change. If last pushed directive was begin declare target, use different wording and simplify format strings for easier translations. (c_parser_omp_clause_device_type): Uncomment check_no_duplicate_clause call. (c_parser_omp_declare_target): Adjust for the current_omp_declare_target_attribute type change, push { -1 }. Use error_at rather than warning_at for declare target with only device_type clauses. (OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK): Define. (c_parser_omp_begin): Add begin declare target support. (c_parser_omp_end): Adjust for the current_omp_declare_target_attribute type change, adjust diagnostics wording and simplify format strings for easier translations. * c-decl.cc (current_omp_declare_target_attribute): Change type from int to vec *. (c_decl_attributes): Adjust for the current_omp_declare_target_attribute type change. If device_type was present on begin declare target, add "omp declare target host" and/or "omp declare target nohost" attributes. gcc/cp/ * cp-tree.h (struct omp_declare_target_attr): Rename to ... (cp_omp_declare_target_attr): ... this. Add device_type member. (omp_begin_assumes_data): Rename to ... (cp_omp_begin_assumes_data): ... this. (struct saved_scope): Change types of omp_declare_target_attribute and omp_begin_assumes. * parser.cc (cp_parser_omp_clause_device_type): Uncomment check_no_duplicate_clause call. (cp_parser_omp_all_clauses): Fix up pasto, c_name for OMP_CLAUSE_LINK should be "link" rather than "to". (cp_parser_omp_declare_target): Adjust for omp_declare_target_attr to cp_omp_declare_target_attr changes, push -1 as device_type. Use error_at rather than warning_at for declare target with only device_type clauses. (OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK): Define. (cp_parser_omp_begin): Add begin declare target support. Adjust for omp_begin_assumes_data to cp_omp_begin_assumes_data change. (cp_parser_omp_end): Adjust for the omp_declare_target_attr to cp_omp_declare_target_attr and omp_begin_assumes_data to cp_omp_begin_assumes_data type changes, adjust diagnostics wording and simplify format strings for easier translations. * semantics.cc (finish_translation_unit): Likewise. * decl2.cc (cplus_decl_attributes): If device_type was present on begin declare target, add "omp declare target host" and/or "omp declare target nohost" attributes. gcc/testsuite/ * c-c++-common/gomp/declare-target-4.c: Move tests that are now rejected into declare-target-7.c. * c-c++-common/gomp/declare-target-6.c: Adjust expected diagnostics. * c-c++-common/gomp/declare-target-7.c: New test. * c-c++-common/gomp/begin-declare-target-1.c: New test. * c-c++-common/gomp/begin-declare-target-2.c: New test. * c-c++-common/gomp/begin-declare-target-3.c: New test. * c-c++-common/gomp/begin-declare-target-4.c: New test. * g++.dg/gomp/attrs-9.C: Add begin declare target tests. * g++.dg/gomp/attrs-18.C: New test. libgomp/ * libgomp.texi (Support begin/end declare target syntax in C/C++): Mark as implemented. Jakub --- gcc/c-family/c-omp.cc.jj 2022-09-28 13:47:00.256269262 +0200 +++ gcc/c-family/c-omp.cc 2022-09-30 14:46:08.270564545 +0200 @@ -3112,8 +3112,8 @@ const struct c_omp_directive c_omp_direc C_OMP_DIR_STANDALONE, false }, { "begin", "assumes", nullptr, PRAGMA_OMP_BEGIN, C_OMP_DIR_INFORMATIONAL, false }, - /* { "begin", "declare", "target", PRAGMA_OMP_BEGIN, - C_OMP_DIR_DECLARATIVE, false }, */ + { "begin", "declare", "target", PRAGMA_OMP_BEGIN, + C_OMP_DIR_DECLARATIVE, false }, /* { "begin", "declare", "variant", PRAGMA_OMP_BEGIN, C_OMP_DIR_DECLARATIVE, false }, */ /* { "begin", "metadirective", nullptr, PRAGMA_OMP_BEGIN, --- gcc/c/c-lang.h.jj 2022-09-28 13:47:00.258269235 +0200 +++ gcc/c/c-lang.h 2022-09-30 17:08:47.260880045 +0200 @@ -60,9 +60,14 @@ struct GTY(()) language_function { int warn_about_return_type; }; +struct GTY(()) c_omp_declare_target_attr { + int device_type; +}; + /* If non-zero, implicit "omp declare target" attribute is added into the attribute lists. */ -extern GTY(()) int current_omp_declare_target_attribute; +extern GTY(()) vec + *current_omp_declare_target_attribute; /* Similarly whether we are in between #pragma omp begin assumes and #pragma omp end assumes (and how many times when nested). */ extern GTY(()) int current_omp_begin_assumes; --- gcc/c/c-parser.cc.jj 2022-09-28 13:47:00.260269208 +0200 +++ gcc/c/c-parser.cc 2022-09-30 17:17:24.875790544 +0200 @@ -1675,18 +1675,22 @@ c_parser_translation_unit (c_parser *par if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node) error ("storage size of %q+D isn%'t known", decl); - if (current_omp_declare_target_attribute) + if (vec_safe_length (current_omp_declare_target_attribute)) { + c_omp_declare_target_attr + a = current_omp_declare_target_attribute->pop (); if (!errorcount) - error ("%<#pragma omp declare target%> without corresponding " - "%<#pragma omp end declare target%>"); - current_omp_declare_target_attribute = 0; + error ("%qs without corresponding %qs", + a.device_type >= 0 ? "#pragma omp begin declare target" + : "#pragma omp declare target", + "#pragma omp end declare target"); + vec_safe_truncate (current_omp_declare_target_attribute, 0); } if (current_omp_begin_assumes) { if (!errorcount) - error ("%<#pragma omp begin assumes%> without corresponding " - "%<#pragma omp end assumes%>"); + error ("%qs without corresponding %qs", + "#pragma omp begin assumes", "#pragma omp end assumes"); current_omp_begin_assumes = 0; } } @@ -16818,8 +16822,8 @@ c_parser_omp_clause_device_type (c_parse else goto invalid_kind; - /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, - "device_type"); */ + 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); @@ -22351,7 +22355,8 @@ c_parser_omp_declare_target (c_parser *p else { c_parser_skip_to_pragma_eol (parser); - current_omp_declare_target_attribute++; + c_omp_declare_target_attr attr = { -1 }; + vec_safe_push (current_omp_declare_target_attribute, attr); return; } for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) @@ -22429,12 +22434,17 @@ c_parser_omp_declare_target (c_parser *p } } if (device_type && only_device_type) - warning_at (OMP_CLAUSE_LOCATION (clauses), 0, - "directive with only % clauses ignored"); + error_at (OMP_CLAUSE_LOCATION (clauses), + "directive with only % clause"); } /* OpenMP 5.1 - #pragma omp begin assumes clauses[optseq] new-line */ + #pragma omp begin assumes clauses[optseq] new-line + + #pragma omp begin declare target clauses[optseq] new-line */ + +#define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \ + (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) static void c_parser_omp_begin (c_parser *parser) @@ -22443,7 +22453,33 @@ c_parser_omp_begin (c_parser *parser) c_parser_consume_pragma (parser); if (c_parser_next_token_is (parser, CPP_NAME)) p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); - if (strcmp (p, "assumes") == 0) + if (strcmp (p, "declare") == 0) + { + c_parser_consume_token (parser); + p = ""; + if (c_parser_next_token_is (parser, CPP_NAME)) + p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); + if (strcmp (p, "target") == 0) + { + c_parser_consume_token (parser); + tree clauses + = c_parser_omp_all_clauses (parser, + OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK, + "#pragma omp begin declare target"); + int device_type = 0; + 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); + c_omp_declare_target_attr attr = { device_type }; + vec_safe_push (current_omp_declare_target_attribute, attr); + } + else + { + c_parser_error (parser, "expected %"); + c_parser_skip_to_pragma_eol (parser); + } + } + else if (strcmp (p, "assumes") == 0) { c_parser_consume_token (parser); c_parser_omp_assumption_clauses (parser, false); @@ -22451,7 +22487,7 @@ c_parser_omp_begin (c_parser *parser) } else { - c_parser_error (parser, "expected %"); + c_parser_error (parser, "expected % or %"); c_parser_skip_to_pragma_eol (parser); } } @@ -22484,19 +22520,20 @@ c_parser_omp_end (c_parser *parser) return; } c_parser_skip_to_pragma_eol (parser); - if (!current_omp_declare_target_attribute) + if (!vec_safe_length (current_omp_declare_target_attribute)) error_at (loc, "%<#pragma omp end declare target%> without " - "corresponding %<#pragma omp declare target%>"); + "corresponding %<#pragma omp declare target%> or " + "%<#pragma omp begin declare target%>"); else - current_omp_declare_target_attribute--; + current_omp_declare_target_attribute->pop (); } else if (strcmp (p, "assumes") == 0) { c_parser_consume_token (parser); c_parser_skip_to_pragma_eol (parser); if (!current_omp_begin_assumes) - error_at (loc, "%<#pragma omp end assumes%> without " - "corresponding %<#pragma omp begin assumes%>"); + error_at (loc, "%qs without corresponding %qs", + "#pragma omp end assumes", "#pragma omp begin assumes"); else current_omp_begin_assumes--; } --- gcc/c/c-decl.cc.jj 2022-09-30 14:12:44.299063275 +0200 +++ gcc/c/c-decl.cc 2022-09-30 17:11:46.135454719 +0200 @@ -153,9 +153,9 @@ static int warn_about_return_type; static bool undef_nested_function; -/* If non-zero, implicit "omp declare target" attribute is added into the - attribute lists. */ -int current_omp_declare_target_attribute; +/* Vector of implicit "omp declare target" attributes to be added into + the attribute lists. */ +vec *current_omp_declare_target_attribute; /* If non-zero, we are inside of #pragma omp begin assumes ... #pragma omp end assumes region. */ @@ -5105,7 +5105,7 @@ static tree c_decl_attributes (tree *node, tree attributes, int flags) { /* Add implicit "omp declare target" attribute if requested. */ - if (current_omp_declare_target_attribute + if (vec_safe_length (current_omp_declare_target_attribute) && ((VAR_P (*node) && is_global_var (*node)) || TREE_CODE (*node) == FUNCTION_DECL)) { @@ -5119,6 +5119,22 @@ c_decl_attributes (tree *node, tree attr attributes = tree_cons (get_identifier ("omp declare target block"), NULL_TREE, attributes); } + if (TREE_CODE (*node) == FUNCTION_DECL) + { + int device_type + = current_omp_declare_target_attribute->last ().device_type; + device_type = MAX (device_type, 0); + if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0 + && !lookup_attribute ("omp declare target host", attributes)) + attributes + = tree_cons (get_identifier ("omp declare target host"), + NULL_TREE, attributes); + if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0 + && !lookup_attribute ("omp declare target nohost", attributes)) + attributes + = tree_cons (get_identifier ("omp declare target nohost"), + NULL_TREE, attributes); + } } /* Look up the current declaration with all the attributes merged --- gcc/cp/cp-tree.h.jj 2022-09-30 14:12:44.410061751 +0200 +++ gcc/cp/cp-tree.h 2022-09-30 17:08:58.114732884 +0200 @@ -1855,11 +1855,12 @@ union GTY((desc ("cp_tree_node_structure }; -struct GTY(()) omp_declare_target_attr { +struct GTY(()) cp_omp_declare_target_attr { bool attr_syntax; + int device_type; }; -struct GTY(()) omp_begin_assumes_data { +struct GTY(()) cp_omp_begin_assumes_data { bool attr_syntax; }; @@ -1909,8 +1910,8 @@ struct GTY(()) saved_scope { cp_binding_level *bindings; hash_map *GTY((skip)) x_local_specializations; - vec *omp_declare_target_attribute; - vec *omp_begin_assumes; + vec *omp_declare_target_attribute; + vec *omp_begin_assumes; struct saved_scope *prev; }; --- gcc/cp/parser.cc.jj 2022-09-29 18:11:34.858666499 +0200 +++ gcc/cp/parser.cc 2022-09-30 17:20:12.787471853 +0200 @@ -40315,8 +40315,8 @@ cp_parser_omp_clause_device_type (cp_par goto resync_fail; c = build_omp_clause (location, OMP_CLAUSE_DEVICE_TYPE); - /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, "device_type", - location); */ + check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, "device_type", + location); OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind; OMP_CLAUSE_CHAIN (c) = list; return c; @@ -40840,7 +40840,7 @@ cp_parser_omp_all_clauses (cp_parser *pa break; case PRAGMA_OMP_CLAUSE_LINK: clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_LINK, clauses); - c_name = "to"; + c_name = "link"; break; case PRAGMA_OMP_CLAUSE_TO: if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0) @@ -46737,8 +46737,8 @@ cp_parser_omp_declare_target (cp_parser } else { - struct omp_declare_target_attr a - = { parser->lexer->in_omp_attribute_pragma }; + cp_omp_declare_target_attr a + = { parser->lexer->in_omp_attribute_pragma, -1 }; vec_safe_push (scope_chain->omp_declare_target_attribute, a); cp_parser_require_pragma_eol (parser, pragma_tok); return; @@ -46763,12 +46763,17 @@ cp_parser_omp_declare_target (cp_parser device_type); } if (device_type && only_device_type) - warning_at (OMP_CLAUSE_LOCATION (clauses), 0, - "directive with only % clauses ignored"); + error_at (OMP_CLAUSE_LOCATION (clauses), + "directive with only % clause"); } /* OpenMP 5.1 - #pragma omp begin assumes clauses[optseq] new-line */ + # pragma omp begin assumes clauses[optseq] new-line + + # pragma omp begin declare target clauses[optseq] new-line */ + +#define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \ + (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) static void cp_parser_omp_begin (cp_parser *parser, cp_token *pragma_tok) @@ -46780,16 +46785,47 @@ cp_parser_omp_begin (cp_parser *parser, tree id = cp_lexer_peek_token (parser->lexer)->u.value; p = IDENTIFIER_POINTER (id); } - if (strcmp (p, "assumes") == 0) + if (strcmp (p, "declare") == 0) + { + cp_lexer_consume_token (parser->lexer); + p = ""; + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + p = IDENTIFIER_POINTER (id); + } + if (strcmp (p, "target") == 0) + { + cp_lexer_consume_token (parser->lexer); + tree clauses + = cp_parser_omp_all_clauses (parser, + OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK, + "#pragma omp begin declare target", + pragma_tok); + int device_type = 0; + 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); + cp_omp_declare_target_attr a + = { in_omp_attribute_pragma, device_type }; + vec_safe_push (scope_chain->omp_declare_target_attribute, a); + } + else + { + cp_parser_error (parser, "expected %"); + cp_parser_skip_to_pragma_eol (parser, pragma_tok); + } + } + else if (strcmp (p, "assumes") == 0) { cp_lexer_consume_token (parser->lexer); cp_parser_omp_assumption_clauses (parser, pragma_tok, false); - struct omp_begin_assumes_data a = { in_omp_attribute_pragma }; + cp_omp_begin_assumes_data a = { in_omp_attribute_pragma }; vec_safe_push (scope_chain->omp_begin_assumes, a); } else { - cp_parser_error (parser, "expected %"); + cp_parser_error (parser, "expected % or %"); cp_parser_skip_to_pragma_eol (parser, pragma_tok); } } @@ -46831,21 +46867,28 @@ cp_parser_omp_end (cp_parser *parser, cp if (!vec_safe_length (scope_chain->omp_declare_target_attribute)) error_at (pragma_tok->location, "%<#pragma omp end declare target%> without corresponding " - "%<#pragma omp declare target%>"); + "%<#pragma omp declare target%> or " + "%<#pragma omp begin declare target%>"); else { - omp_declare_target_attr + cp_omp_declare_target_attr a = scope_chain->omp_declare_target_attribute->pop (); if (a.attr_syntax != in_omp_attribute_pragma) { if (a.attr_syntax) error_at (pragma_tok->location, - "% in attribute syntax terminated " - "with % in pragma syntax"); + "%qs in attribute syntax terminated " + "with %qs in pragma syntax", + a.device_type >= 0 ? "begin declare target" + : "declare target", + "end declare target"); else error_at (pragma_tok->location, - "% in pragma syntax terminated " - "with % in attribute syntax"); + "%qs in pragma syntax terminated " + "with %qs in attribute syntax", + a.device_type >= 0 ? "begin declare target" + : "declare target", + "end declare target"); } } } @@ -46855,22 +46898,24 @@ cp_parser_omp_end (cp_parser *parser, cp cp_parser_require_pragma_eol (parser, pragma_tok); if (!vec_safe_length (scope_chain->omp_begin_assumes)) error_at (pragma_tok->location, - "%<#pragma omp end assumes%> without corresponding " - "%<#pragma omp begin assumes%>"); + "%qs without corresponding %qs", + "#pragma omp end assumes", "#pragma omp begin assumes"); else { - omp_begin_assumes_data + cp_omp_begin_assumes_data a = scope_chain->omp_begin_assumes->pop (); if (a.attr_syntax != in_omp_attribute_pragma) { if (a.attr_syntax) error_at (pragma_tok->location, - "% in attribute syntax terminated " - "with % in pragma syntax"); + "%qs in attribute syntax terminated " + "with %qs in pragma syntax", + "begin assumes", "end assumes"); else error_at (pragma_tok->location, - "% in pragma syntax terminated " - "with % in attribute syntax"); + "%qs in pragma syntax terminated " + "with %qs in attribute syntax", + "begin assumes", "end assumes"); } } } --- gcc/cp/semantics.cc.jj 2022-09-29 18:11:34.869666349 +0200 +++ gcc/cp/semantics.cc 2022-09-30 17:13:38.046922818 +0200 @@ -3358,16 +3358,20 @@ finish_translation_unit (void) if (vec_safe_length (scope_chain->omp_declare_target_attribute)) { + cp_omp_declare_target_attr + a = scope_chain->omp_declare_target_attribute->pop (); if (!errorcount) - error ("%<#pragma omp declare target%> without corresponding " - "%<#pragma omp end declare target%>"); + error ("%qs without corresponding %qs", + a.device_type >= 0 ? "#pragma omp begin declare target" + : "#pragma omp declare target", + "#pragma omp end declare target"); vec_safe_truncate (scope_chain->omp_declare_target_attribute, 0); } if (vec_safe_length (scope_chain->omp_begin_assumes)) { if (!errorcount) - error ("%<#pragma omp begin assumes%> without corresponding " - "%<#pragma omp end assumes%>"); + error ("%qs without corresponding %qs", + "#pragma omp begin assumes", "#pragma omp end assumes"); vec_safe_truncate (scope_chain->omp_begin_assumes, 0); } } --- gcc/cp/decl2.cc.jj 2022-09-28 13:47:00.263269168 +0200 +++ gcc/cp/decl2.cc 2022-09-30 17:11:14.230887302 +0200 @@ -1652,17 +1652,40 @@ cplus_decl_attributes (tree *decl, tree && DECL_CLASS_SCOPE_P (*decl)) error ("%q+D static data member inside of declare target directive", *decl); - else if (VAR_P (*decl) - && (processing_template_decl - || !omp_mappable_type (TREE_TYPE (*decl)))) - attributes = tree_cons (get_identifier ("omp declare target implicit"), - NULL_TREE, attributes); else { - attributes = tree_cons (get_identifier ("omp declare target"), - NULL_TREE, attributes); - attributes = tree_cons (get_identifier ("omp declare target block"), - NULL_TREE, attributes); + if (VAR_P (*decl) + && (processing_template_decl + || !omp_mappable_type (TREE_TYPE (*decl)))) + attributes + = tree_cons (get_identifier ("omp declare target implicit"), + NULL_TREE, attributes); + else + { + attributes = tree_cons (get_identifier ("omp declare target"), + NULL_TREE, attributes); + attributes + = tree_cons (get_identifier ("omp declare target block"), + NULL_TREE, attributes); + } + if (TREE_CODE (*decl) == FUNCTION_DECL) + { + cp_omp_declare_target_attr &last + = scope_chain->omp_declare_target_attribute->last (); + int device_type = MAX (last.device_type, 0); + if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0 + && !lookup_attribute ("omp declare target host", + attributes)) + attributes + = tree_cons (get_identifier ("omp declare target host"), + NULL_TREE, attributes); + if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0 + && !lookup_attribute ("omp declare target nohost", + attributes)) + attributes + = tree_cons (get_identifier ("omp declare target nohost"), + NULL_TREE, attributes); + } } } --- gcc/testsuite/c-c++-common/gomp/declare-target-4.c.jj 2020-01-12 11:54:37.012404372 +0100 +++ gcc/testsuite/c-c++-common/gomp/declare-target-4.c 2022-09-30 15:25:42.880123901 +0200 @@ -1,8 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-fopenmp" } */ -#pragma omp declare target device_type (any) /* { dg-warning "directive with only 'device_type' clauses ignored" } */ - void f1 (void) {} void f2 (void); #pragma omp declare target to (f1) device_type (any) to (f2) @@ -38,7 +36,3 @@ void f13 (void) {} void f14 (void) {} #pragma omp declare target device_type (nohost) to (f14) #pragma omp declare target device_type (any) to (f14) -void f15 (void) {} -#pragma omp declare target device_type (host) to (f15) device_type (nohost) -void f16 (void) {} -#pragma omp declare target device_type (any) to (f15) device_type (any) --- gcc/testsuite/c-c++-common/gomp/declare-target-6.c.jj 2022-09-27 08:22:37.073635313 +0200 +++ gcc/testsuite/c-c++-common/gomp/declare-target-6.c 2022-09-30 15:28:46.858609049 +0200 @@ -1,2 +1,2 @@ -#pragma omp end declare target /* { dg-error "'#pragma omp end declare target' without corresponding '#pragma omp declare target'" } */ +#pragma omp end declare target /* { dg-error "'#pragma omp end declare target' without corresponding '#pragma omp declare target' or '#pragma omp begin declare target'" } */ void foo (void); --- gcc/testsuite/c-c++-common/gomp/declare-target-7.c.jj 2022-09-30 15:23:01.362331741 +0200 +++ gcc/testsuite/c-c++-common/gomp/declare-target-7.c 2022-09-30 15:27:01.105054620 +0200 @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +#pragma omp declare target device_type (any) /* { dg-error "directive with only 'device_type' clause" } */ + +void f1 (void) {} +#pragma omp declare target device_type (host) to (f1) device_type (nohost) /* { dg-error "too many 'device_type' clauses" } */ +#pragma omp declare target device_type (any) to (f1) device_type (any) /* { dg-error "too many 'device_type' clauses" } */ --- gcc/testsuite/c-c++-common/gomp/begin-declare-target-1.c.jj 2022-09-30 16:40:28.777857628 +0200 +++ gcc/testsuite/c-c++-common/gomp/begin-declare-target-1.c 2022-09-30 16:47:08.064466814 +0200 @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +extern int a; +#pragma omp begin declare target device_type (host) +int b; +#pragma omp begin declare target device_type (any) +char d; +#pragma omp end declare target +#pragma omp end declare target +#pragma omp begin declare target +long c; +#pragma omp end declare target +#pragma omp declare target +int foo (void) { return 0; } +#pragma omp begin declare target device_type (any) +int bar (void) { return 0; } +#pragma omp end declare target +#pragma omp end declare target +#pragma omp begin declare target device_type (any) +int baz (void) { return 0; } +#pragma omp declare target +int qux (void) { return 0; } +#pragma omp end declare target +#pragma omp end declare target --- gcc/testsuite/c-c++-common/gomp/begin-declare-target-2.c.jj 2022-09-30 16:41:12.091272843 +0200 +++ gcc/testsuite/c-c++-common/gomp/begin-declare-target-2.c 2022-09-30 16:50:16.109927990 +0200 @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +extern int a; +#pragma omp begin declare target +#pragma omp declare target to (a) +#pragma omp end declare target +int b; +#pragma omp begin declare target to (b) /* { dg-error "'to' is not valid for '#pragma omp begin declare target'" } */ +#pragma omp end declare target +int c; +#pragma omp begin declare target link (c) /* { dg-error "'link' is not valid for '#pragma omp begin declare target'" } */ +#pragma omp end declare target +int m; +#pragma omp begin declare target device_type (host) device_type (any) /* { dg-error "too many 'device_type' clauses" } */ +#pragma omp end declare target +#pragma omp begin declare target +#pragma omp end declare target to (p) /* { dg-error "expected end of line before .to." } */ --- gcc/testsuite/c-c++-common/gomp/begin-declare-target-3.c.jj 2022-09-30 18:01:22.422193659 +0200 +++ gcc/testsuite/c-c++-common/gomp/begin-declare-target-3.c 2022-09-30 16:45:57.768415887 +0200 @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +#pragma omp begin declare target +int a[] = { 1, 2, 3 }; +extern int b[]; /* { dg-error "'b' in declare target directive does not have mappable type" } */ +extern int c[]; /* { dg-error "'c' in declare target directive does not have mappable type" } */ +extern int d[]; /* { dg-error "'d' in declare target directive does not have mappable type" } */ +int d[3]; +#pragma omp end declare target +int c[3]; +#pragma omp begin declare target device_type (host) +int e[] = { 1, 2, 3 }; +extern int f[]; /* { dg-error "'f' in declare target directive does not have mappable type" } */ +extern int g[]; /* { dg-error "'g' in declare target directive does not have mappable type" } */ +extern int h[]; /* { dg-error "'h' in declare target directive does not have mappable type" } */ +int h[3]; +#pragma omp end declare target +int g[3]; --- gcc/testsuite/c-c++-common/gomp/begin-declare-target-4.c.jj 2022-09-30 16:47:44.763971326 +0200 +++ gcc/testsuite/c-c++-common/gomp/begin-declare-target-4.c 2022-09-30 17:32:49.370548159 +0200 @@ -0,0 +1,2 @@ +#pragma omp begin declare target +void foo (void); /* { dg-error "'#pragma omp begin declare target' without corresponding '#pragma omp end declare target'" } */ --- gcc/testsuite/g++.dg/gomp/attrs-9.C.jj 2022-09-27 08:22:37.164634077 +0200 +++ gcc/testsuite/g++.dg/gomp/attrs-9.C 2022-09-30 17:36:48.220575918 +0200 @@ -14,6 +14,21 @@ int b, c, e; int d; [[omp::directive (end declare target)]]; [[omp::directive (end declare target)]]; +[[omp::directive (begin declare target, device_type (any))]]; +[[omp::directive (begin declare target)]]; +int f; +[[omp::directive (end declare target)]]; +[[omp::directive (end declare target)]]; +[[omp::directive (begin declare target device_type (host))]]; +[[omp::directive (declare target)]]; +int g; +[[omp::directive (end declare target)]]; +[[omp::directive (end declare target)]]; +[[omp::directive (declare target)]]; +[[omp::directive (begin declare target, device_type (nohost))]]; +int h; +[[omp::directive (end declare target)]]; +[[omp::directive (end declare target)]]; [[omp::directive (nothing)]]; [[omp::directive (begin assumes no_openmp no_openmp_routines no_parallelism absent (atomic, barrier, cancel, cancellation point) --- gcc/testsuite/g++.dg/gomp/attrs-18.C.jj 2022-09-30 17:37:26.173944723 +0200 +++ gcc/testsuite/g++.dg/gomp/attrs-18.C 2022-09-30 17:38:58.603407551 +0200 @@ -0,0 +1,41 @@ +// { dg-do compile { target c++11 } } + +#pragma omp begin declare target +#pragma omp begin declare target device_type (any) +[[omp::directive (begin declare target, device_type (host))]]; +int a; +[[omp::directive (end declare target)]]; +#pragma omp end declare target +#pragma omp end declare target +[[omp::directive (begin declare target device_type (nohost))]]; +int b; +#pragma omp end declare target // { dg-error "'begin declare target' in attribute syntax terminated with 'end declare target' in pragma syntax" } +#pragma omp begin declare target +int c; +[[omp::directive (end declare target)]];// { dg-error "'begin declare target' in pragma syntax terminated with 'end declare target' in attribute syntax" } +#pragma omp begin declare target device_type (host) +[[omp::directive (begin declare target)]]; +int d; +#pragma omp end declare target // { dg-error "'begin declare target' in attribute syntax terminated with 'end declare target' in pragma syntax" } +#pragma omp begin declare target +int e; +[[omp::directive (end declare target)]];// { dg-error "'begin declare target' in pragma syntax terminated with 'end declare target' in attribute syntax" } +#pragma omp end declare target +[[omp::directive (begin declare target device_type (any))]]; +[[omp::directive (begin declare target)]]; +int f; +#pragma omp end declare target // { dg-error "'begin declare target' in attribute syntax terminated with 'end declare target' in pragma syntax" } +#pragma omp begin declare target +int g; +[[omp::directive (end declare target)]];// { dg-error "'begin declare target' in pragma syntax terminated with 'end declare target' in attribute syntax" } +[[omp::directive (end declare target)]]; +[[omp::directive (begin declare target)]]; +#pragma omp begin declare target +int h; +#pragma omp end declare target +#pragma omp end declare target // { dg-error "'begin declare target' in attribute syntax terminated with 'end declare target' in pragma syntax" } +#pragma omp begin declare target +[[omp::directive (begin declare target)]]; +int i; +[[omp::directive (end declare target)]]; +[[omp::directive (end declare target)]];// { dg-error "'begin declare target' in pragma syntax terminated with 'end declare target' in attribute syntax" } --- libgomp/libgomp.texi.jj 2022-09-28 13:47:07.681169256 +0200 +++ libgomp/libgomp.texi 2022-09-30 17:41:57.535431793 +0200 @@ -345,7 +345,7 @@ The OpenMP 4.5 specification is fully su @item Support of structured block sequences in C/C++ @tab Y @tab @item @code{unconstrained} and @code{reproducible} modifiers on @code{order} clause @tab Y @tab -@item Support @code{begin/end declare target} syntax in C/C++ @tab N @tab +@item Support @code{begin/end declare target} syntax in C/C++ @tab Y @tab @item Pointer predetermined firstprivate getting initialized to address of matching mapped list item per 5.1, Sect. 2.21.7.2 @tab N @tab @item For Fortran, diagnose placing declarative before/between @code{USE},