From patchwork Tue Oct 24 09:15:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tobias Burnus X-Patchwork-Id: 1854256 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SF5yC3dw2z23jV for ; Tue, 24 Oct 2023 20:15:46 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A9A9F3858418 for ; Tue, 24 Oct 2023 09:15:44 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa4.mentor.iphmx.com (esa4.mentor.iphmx.com [68.232.137.252]) by sourceware.org (Postfix) with ESMTPS id 6CD1E3858D37; Tue, 24 Oct 2023 09:15:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6CD1E3858D37 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6CD1E3858D37 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=68.232.137.252 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698138922; cv=none; b=nXXYRvA9K3A+yH7PXfbUSoM30dplculdt7oSUkPIhQiZEdLW4fsqr+RlbK8avGCs0v31T0UaInrGmNQ+YeppfgDVBDEur/Fe29KjnU8PchAlwmN5D7hQzok5qrY5awcRErkfC3DWkusKdPGillm9qrcobiWpLQdN234wZ0dkATU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698138922; c=relaxed/simple; bh=tRwiQbP4/KMJxyt8eIDiYTPYfK4RN4/B2uImCmeS5Lc=; h=Message-ID:Date:MIME-Version:To:From:Subject; b=pvYmgO1a5XE0Mwh+IURSl/biZoYtlcofnHBqLetuvTMeyLGFfHUpXTGA7ad4HikOdlh9gKP499Ni9bDoawy1g379ma0E1fdxS0ElnlLJWU1dUX1SUpowyRvgyPzwIBAAhHXkcF4RQbN3GrZ+p+rZ6uDTVbkNIFbBGP8SGNXGXTY= ARC-Authentication-Results: i=1; server2.sourceware.org X-CSE-ConnectionGUID: M3HDGqPnSmOBruT00kElCg== X-CSE-MsgGUID: BEwRxo3kQX+cFc9tMi/a8A== X-IronPort-AV: E=Sophos;i="6.03,247,1694764800"; d="diff'?scan'208";a="20556166" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa4.mentor.iphmx.com with ESMTP; 24 Oct 2023 01:15:18 -0800 IronPort-SDR: RV2gXqOfw6C0uupNf7aBXxa9sHcx22poMuTKxXASb9OrXa9FSVPcWm9H0lvgKMpkFe7UHbhv19 EoVqqkxhY0+C28IXt3mVz/EUR9iRC99cVTStJzXv4wcVINXK+zpVA3OpLM74T6MVr3xLQaI50m EcwyL3jh2N+lc2PFtFrH5ZtI3KQbGHmYS+zgSy57Eb/Hc1h2YDG/XUyTmd8algrAo5PstpQVIn Nmxrz4C7iYEjJZNMIE0948fEeFOTVRqiGXGFhqk4m0Gxg5m2fDA7eacLdpZGzJJM9xoWYb0WnH GJA= Message-ID: <056bcafa-6767-42fb-8a3b-8e1dc57a41fa@codesourcery.com> Date: Tue, 24 Oct 2023 11:15:12 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: gcc-patches , fortran From: Tobias Burnus Subject: [Patch] OpenMP/Fortran: Handle unlisted items in 'omp allocators' + exec. 'omp allocate' X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-11.mgc.mentorg.com (139.181.222.11) To svr-ies-mbx-12.mgc.mentorg.com (139.181.222.12) X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org This patch assumes that EXEC_OMP_ALLOCATE/EXEC_OMP_ALLOCATORS is/will be later handled as currently done in OG13, https://github.com/gcc-mirror/gcc/blob/devel/omp/gcc-13/gcc/fortran/trans-openmp.cc Depending how we want to handle it in mainline, the patch still could make sense - or parts should be modified, e.g. we might want to handle standard Fortran allocation (malloc) and OpenMP one (GOMP_alloc) directly in trans-sstmt.cc; if so, we might want to skip adding another allocate-stmt. - We probably still want to do the 'allocate' and diagnostic hanlding in openmp.cc in all cases. In any case, we surely need to handle on mainline: * the dump-parse-tree.cc patch is surely needed and without removing the empty entry (n->sym == NULL), it needs an additional fix in order not to crash. * Rejecting coarrays in the empty-list case, which presumably makes most sense inside openmp.cc. * * * On mainline, an executable '!$omp allocate' / '!$omp allocators' stops in trans-openmp.cc with a sorry, not yet implemented. However, OG13 has some implementation for executable '!$omp allocate'; trying to merge mainline into OG13, I found the following issues: * -fdump-parse-tree did not dump the clauses (trivial issue) (simple oversight) * The not-specified items should be better handled => done now during resolution in openmp.cc. * * * While -fdump-tree-original can be used to test it, the "sorry" makes it hard to write a testsuite test. Some testcases exist like gfortran.dg/gomp/allocate-5.f90, which contains code similar to the last example, but it is only a parse + 'sorry'-shows-up testcase. (Well, the two new 'error:' cases can be tested and are tested but they are more boring.) * * * The spec states: For !$omp allocators allocate(align(4):a,b) allocate(a,b,c,d) only a and b are allocated with an OpenMP allocator (→ omp_get_default_allocator()) and alignment of 4. - 'c' and 'd' are allocated in the normal Fortran way. The deprecated works as follows: !$omp allocate(a,b) align(4) !$omp allocate align(16) ! not: no list argument after 'allocate') allocate(a,b,c,d) where a and b will be allocated with an alignment of 4 and the rest, here, c and d, with the settings of the directive without argument list, i.e. c and d are allocated with an alignment of 16. The question is what is supposed to happen for: !$omp allocate(a,b) align(4) allocate(a,b,c,d) Should that use the default allocator for c and d, i.e. the same as !$omp allocate(a,b) align(4) !$omp allocate allocate(a,b,c,d) Or should it use the normal Fortran allocator, following what 'allocators' does? The spec does not really tell (and that syntax is deprecated in 5.2, removed in TR11/OpenMP 6). Thus, GCC now prints an error. However, it would be trivial to choose either of the other variants. * * * The attached patch now handles the not-specified items: * It adds them in the last case to the list; namelist->sym == NULL is the no-arguments case; this item is also removed, avoiding n->sym == NULL special cases later on. * For the first two cases, a new Fortran ALLOCATE statement is created, containing the non-treated items. Comments, suggestions, remarks? Tobias ----------------- Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955 OpenMP: Handle unlisted items in 'omp allocators' + exec. 'omp allocate' gcc/fortran/ChangeLog: * dump-parse-tree.cc (show_omp_node): Show clauses for EXEC_OMP_ALLOCATE and EXEC_OMP_ALLOCATORS. * openmp.cc (resolve_omp_clauses): Process nonlisted items for EXEC_OMP_ALLOCATE and EXEC_OMP_ALLOCATORS. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/allocate-14.f90: Add new checks. * gfortran.dg/gomp/allocate-5.f90: Remove items from an allocate-stmt that are not explicitly/implicited listed in 'omp allocate'. gcc/fortran/dump-parse-tree.cc | 2 + gcc/fortran/openmp.cc | 112 ++++++++++++++++++++++++- gcc/testsuite/gfortran.dg/gomp/allocate-14.f90 | 41 +++++++++ gcc/testsuite/gfortran.dg/gomp/allocate-5.f90 | 4 +- 4 files changed, 155 insertions(+), 4 deletions(-) diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc index 68122e3e6fd..1440524f971 100644 --- a/gcc/fortran/dump-parse-tree.cc +++ b/gcc/fortran/dump-parse-tree.cc @@ -2241,6 +2241,8 @@ show_omp_node (int level, gfc_code *c) case EXEC_OACC_CACHE: case EXEC_OACC_ENTER_DATA: case EXEC_OACC_EXIT_DATA: + case EXEC_OMP_ALLOCATE: + case EXEC_OMP_ALLOCATORS: case EXEC_OMP_ASSUME: case EXEC_OMP_CANCEL: case EXEC_OMP_CANCELLATION_POINT: diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 1cc65d7fa49..95e0aaafa58 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -7924,10 +7924,14 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, && code->block->next->op == EXEC_ALLOCATE) { gfc_alloc *a; + gfc_omp_namelist *n_null = NULL; for (n = omp_clauses->lists[OMP_LIST_ALLOCATE]; n; n = n->next) { if (n->sym == NULL) - continue; + { + n_null = n; + continue; + } if (n->sym->attr.codimension) gfc_error ("Unexpected coarray %qs in % at %L", n->sym->name, &n->where); @@ -7940,8 +7944,112 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, "in the associated ALLOCATE statement", n->sym->name, &n->where); } + /* If there is an ALLOCATE directive without list argument, a + namelist with its allocator/align clauses and n->sym = NULL is + created during parsing; here, we add all not otherwise specified + items from the Fortran allocate to that list. + For an ALLOCATORS directive, not listed items use the normal + Fortran way. + The behavior of an ALLOCATE directive that does not list all + arguments but there is no directive without list argument is not + well specified. Thus, we reject such code below. In OpenMP 5.2 + the executable ALLOCATE directive is deprecated and in 6.0 + deleted such that no spec clarification is to be expected. */ + gfc_alloc *a_prev = NULL; + gfc_alloc *extra_alloc = NULL, *extra_alloc_last = NULL; + for (a = code->block->next->ext.alloc.list; a; ) + { + if (a->expr->expr_type == EXPR_VARIABLE) + { + for (n = omp_clauses->lists[OMP_LIST_ALLOCATE]; n; n = n->next) + if (a->expr->symtree->n.sym == n->sym) + break; + if (n == NULL && n_null == NULL) + { + if (!extra_alloc) + extra_alloc = extra_alloc_last = a; + else + { + extra_alloc_last->next = a; + extra_alloc_last = a; + } + a = a->next; + if (code->block->next->ext.alloc.list == extra_alloc_last) + code->block->next->ext.alloc.list = a; + else + a_prev->next = a; + extra_alloc_last->next = NULL; + continue; + } + if (n == NULL) + { + if (a->expr->symtree->n.sym->attr.codimension) + gfc_error ("Unexpected coarray %qs in % at " + "%L, implicitly listed in %" + " at %L", a->expr->symtree->n.sym->name, + &a->expr->where, &n_null->where); + if (n_null->sym == NULL) + n_null->sym = a->expr->symtree->n.sym; + else + { + n = n_null->next; + n_null->next = gfc_get_omp_namelist (); + n_null->next->next = n; + n_null->next->sym = a->expr->symtree->n.sym; + n_null->next->u2.allocator = n_null->u2.allocator; + n_null->next->u.align + = gfc_copy_expr (n_null->u.align); + n_null->next->where = n_null->where; + n_null = n_null->next; + } + } + } + a_prev = a; + a = a->next; + } + if (n_null && n_null->sym == NULL) + { + if (n_null == omp_clauses->lists[OMP_LIST_ALLOCATE]) + omp_clauses->lists[OMP_LIST_ALLOCATE] = n_null->next; + else + { + for (n = omp_clauses->lists[OMP_LIST_ALLOCATE]; n; + n = n->next) + if (n->next == n_null) + break; + n->next = n_null->next; + n_null->next = NULL; + gfc_free_omp_namelist (n_null, false, true, false); + } + } + if (extra_alloc) + { + /* Unspecified whether that should use the default allocator + of OpenMP or the Fortran allocator. Thus, just reject it. */ + if (code->op == EXEC_OMP_ALLOCATE) + gfc_error ("%qs listed in % statement at %L but " + "it is neither explicitly in listed in the " + "% directive nor exists a directive" + " without argument list", + extra_alloc->expr->symtree->n.sym->name, + &extra_alloc->expr->where); + gfc_code *c = code->block->next; + gfc_code *cn = code->next; + code->next = gfc_get_code (c->op); + code->next->next = cn; + cn = code->next; + cn->loc = c->loc; + cn->expr1 = gfc_copy_expr (cn->expr1); + cn->expr2 = gfc_copy_expr (cn->expr2); + cn->expr3 = gfc_copy_expr (cn->expr3); + cn->ext.alloc.ts = cn->ext.alloc.ts; + cn->ext.alloc.list = extra_alloc; + cn->ext.alloc.arr_spec_from_expr3 + = c->ext.alloc.arr_spec_from_expr3; + cn->ext.alloc.expr3_not_explicit + = c->ext.alloc.expr3_not_explicit; + } } - } /* OpenACC reductions. */ diff --git a/gcc/testsuite/gfortran.dg/gomp/allocate-14.f90 b/gcc/testsuite/gfortran.dg/gomp/allocate-14.f90 index 8ff9c252e49..4fed19249a3 100644 --- a/gcc/testsuite/gfortran.dg/gomp/allocate-14.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/allocate-14.f90 @@ -93,3 +93,44 @@ subroutine c_and_func_ptrs !$omp allocate(cfunptr) ! OK? A normal derived-type var? !$omp allocate(p) ! { dg-error "Argument 'p' at .1. to declarative !.OMP ALLOCATE directive must be a variable" } end + + +subroutine coarray_2 + use m + implicit none + integer :: x + integer, allocatable :: a, b, c[:], d + x = 5 ! executable stmt + !$omp allocate(a,b) align(16) + !$omp allocate ! { dg-error "Unexpected coarray 'c' in 'allocate' at .1., implicitly listed in '!.OMP ALLOCATE' at .2." } + !$omp allocate(d) align(32) + allocate(a,b,c[*],d) ! { dg-error "Unexpected coarray 'c' in 'allocate' at .1., implicitly listed in '!.OMP ALLOCATE' at .2." } +end + + +subroutine coarray_3 + use m + implicit none + integer :: x + integer, allocatable :: a, b, c[:], d + x = 5 ! executable stmt + !$omp allocators allocate(align(16): a,b) allocate(align(32) : d) + allocate(a,b,c[*],d) ! OK - Fortran allocator used for 'C' +end + + +subroutine unclear + use m + implicit none + integer :: x + integer, allocatable :: a, b, c[:], d + + ! OpenMP is unclear which allocator is used for 'C' - the fortran one or the OpenMP one. + ! GCC therefore rejects it. + + x = 5 ! executable stmt + + !$omp allocate(a,b) align(16) + !$omp allocate(d) align(32) + allocate(a,b,c[*],d) ! { dg-error "'c' listed in 'allocate' statement at .1. but it is neither explicitly in listed in the '!.OMP ALLOCATE' directive nor exists a directive without argument list" } +end diff --git a/gcc/testsuite/gfortran.dg/gomp/allocate-5.f90 b/gcc/testsuite/gfortran.dg/gomp/allocate-5.f90 index bf9c781dcc5..35c7b1ba5bf 100644 --- a/gcc/testsuite/gfortran.dg/gomp/allocate-5.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/allocate-5.f90 @@ -46,8 +46,8 @@ subroutine two(c,x2,y2) !$omp flush ! some executable statement !$omp allocate(a) ! { dg-message "not yet supported" } - allocate(a,b(4),c(3,4)) - deallocate(a,b,c) + allocate(a) + deallocate(a) !$omp allocate(x1,y1,x2,y2) ! { dg-message "not yet supported" } allocate(x1,y1,x2(5),y2(5))