From patchwork Thu Jul 7 10:34:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Stubbs X-Patchwork-Id: 1653457 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4LdtCD1N8Fz9s07 for ; Thu, 7 Jul 2022 20:37:28 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3A16F386CE61 for ; Thu, 7 Jul 2022 10:37:24 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa1.mentor.iphmx.com (esa1.mentor.iphmx.com [68.232.129.153]) by sourceware.org (Postfix) with ESMTPS id 5ED2238485B9 for ; Thu, 7 Jul 2022 10:37:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5ED2238485B9 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com X-IronPort-AV: E=Sophos;i="5.92,252,1650960000"; d="scan'208";a="81112769" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa1.mentor.iphmx.com with ESMTP; 07 Jul 2022 02:37:11 -0800 IronPort-SDR: L7hVmE722WAMiMUrGc5hHCzlUz3QX5IJoWhqN0ohKaM7KCuF09KW00pTNsjRUFqdXZoyBIcgYV Rfw3tin8eFBK+dGr/16KetTdKvx7EnhQBxgGBkeT8iWp4OavTRXh/X2h72I7oO/lkgayA5zXdh 84TEs5yTMi2BE3qToV8ioRqLZh7oq0RcbnUGZNV2UDrwXYuCXmdKB899iug1LqyoaLz/HdZAMG Z9tVzsdSiFtAkb1/t111Vh4QAVL+WyS0mGFeCZxk9unnSTMZdjaYWUiQ2FrepC2jvmtl0Oc3c7 5T0= From: Andrew Stubbs To: Subject: [PATCH 12/17] Handle cleanup of omp allocated variables (OpenMP 5.0). Date: Thu, 7 Jul 2022 11:34:43 +0100 Message-ID: X-Mailer: git-send-email 2.33.0 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-10.mgc.mentorg.com (139.181.222.10) To svr-ies-mbx-11.mgc.mentorg.com (139.181.222.11) X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.29 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 Sender: "Gcc-patches" Currently we are only handling omp allocate directive that is associated with an allocate statement. This statement results in malloc and free calls. The malloc calls are easy to get to as they are in the same block as allocate directive. But the free calls come in a separate cleanup block. To help any later passes finding them, an allocate directive is generated in the cleanup block with kind=free. The normal allocate directive is given kind=allocate. gcc/fortran/ChangeLog: * gfortran.h (struct access_ref): Declare new members omp_allocated and omp_allocated_end. * openmp.cc (gfc_match_omp_allocate): Set new_st.resolved_sym to NULL. (prepare_omp_allocated_var_list_for_cleanup): New function. (gfc_resolve_omp_allocate): Call it. * trans-decl.cc (gfc_trans_deferred_vars): Process omp_allocated. * trans-openmp.cc (gfc_trans_omp_allocate): Set kind for the stmt generated for allocate directive. gcc/ChangeLog: * tree-core.h (struct tree_base): Add comments. * tree-pretty-print.cc (dump_generic_node): Handle allocate directive kind. * tree.h (OMP_ALLOCATE_KIND_ALLOCATE): New define. (OMP_ALLOCATE_KIND_FREE): Likewise. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/allocate-6.f90: Test kind of allocate directive. --- gcc/fortran/gfortran.h | 1 + gcc/fortran/openmp.cc | 30 +++++++++++++++++++ gcc/fortran/trans-decl.cc | 20 +++++++++++++ gcc/fortran/trans-openmp.cc | 6 ++++ gcc/testsuite/gfortran.dg/gomp/allocate-6.f90 | 3 +- gcc/tree-core.h | 6 ++++ gcc/tree-pretty-print.cc | 4 +++ gcc/tree.h | 4 +++ 8 files changed, 73 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 755469185a6..c6f58341cf3 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1829,6 +1829,7 @@ typedef struct gfc_symbol gfc_array_spec *as; struct gfc_symbol *result; /* function result symbol */ gfc_component *components; /* Derived type components */ + gfc_omp_namelist *omp_allocated, *omp_allocated_end; /* Defined only for Cray pointees; points to their pointer. */ struct gfc_symbol *cp_pointer; diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 38003890bb0..4c94bc763b5 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -6057,6 +6057,7 @@ gfc_match_omp_allocate (void) new_st.op = EXEC_OMP_ALLOCATE; new_st.ext.omp_clauses = c; + new_st.resolved_sym = NULL; gfc_free_expr (allocator); return MATCH_YES; } @@ -9548,6 +9549,34 @@ gfc_resolve_oacc_routines (gfc_namespace *ns) } } +static void +prepare_omp_allocated_var_list_for_cleanup (gfc_omp_namelist *cn, locus loc) +{ + gfc_symbol *proc = cn->sym->ns->proc_name; + gfc_omp_namelist *p, *n; + + for (n = cn; n; n = n->next) + { + if (n->sym->attr.allocatable && !n->sym->attr.save + && !n->sym->attr.result && !proc->attr.is_main_program) + { + p = gfc_get_omp_namelist (); + p->sym = n->sym; + p->expr = gfc_copy_expr (n->expr); + p->where = loc; + p->next = NULL; + if (proc->omp_allocated == NULL) + proc->omp_allocated_end = proc->omp_allocated = p; + else + { + proc->omp_allocated_end->next = p; + proc->omp_allocated_end = p; + } + + } + } +} + static void check_allocate_directive_restrictions (gfc_symbol *sym, gfc_expr *omp_al, gfc_namespace *ns, locus loc) @@ -9678,6 +9707,7 @@ gfc_resolve_omp_allocate (gfc_code *code, gfc_namespace *ns) code->loc); } } + prepare_omp_allocated_var_list_for_cleanup (cn, code->loc); } diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index 6493cc2f6b1..326365f22fc 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -4588,6 +4588,26 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block) } } + /* Generate a dummy allocate pragma with free kind so that cleanup + of those variables which were allocated using the allocate statement + associated with an allocate clause happens correctly. */ + + if (proc_sym->omp_allocated) + { + gfc_clear_new_st (); + new_st.op = EXEC_OMP_ALLOCATE; + gfc_omp_clauses *c = gfc_get_omp_clauses (); + c->lists[OMP_LIST_ALLOCATOR] = proc_sym->omp_allocated; + new_st.ext.omp_clauses = c; + /* This is just a hacky way to convey to handler that we are + dealing with cleanup here. Saves us from using another field + for it. */ + new_st.resolved_sym = proc_sym->omp_allocated->sym; + gfc_add_init_cleanup (block, NULL, + gfc_trans_omp_directive (&new_st)); + gfc_free_omp_clauses (c); + proc_sym->omp_allocated = NULL; + } /* Initialize the INTENT(OUT) derived type dummy arguments. This should be done here so that the offsets and lbounds of arrays diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index 3ee63e416ed..ab3c0c620b7 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -5019,6 +5019,12 @@ gfc_trans_omp_allocate (gfc_code *code) OMP_ALLOCATE_CLAUSES (stmt) = gfc_trans_omp_clauses (&block, clauses, code->loc, false, true); + if (code->next == NULL && code->block == NULL + && code->resolved_sym != NULL) + OMP_ALLOCATE_KIND_FREE (stmt) = 1; + else + OMP_ALLOCATE_KIND_ALLOCATE (stmt) = 1; + gfc_add_expr_to_block (&block, stmt); gfc_merge_block_scope (&block); return gfc_finish_block (&block); diff --git a/gcc/testsuite/gfortran.dg/gomp/allocate-6.f90 b/gcc/testsuite/gfortran.dg/gomp/allocate-6.f90 index 2de2b52ee44..0eb35178e03 100644 --- a/gcc/testsuite/gfortran.dg/gomp/allocate-6.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/allocate-6.f90 @@ -69,4 +69,5 @@ end type allocate(pii, parr(5)) end subroutine -! { dg-final { scan-tree-dump-times "#pragma omp allocate" 6 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp allocate \\(kind=allocate\\)" 6 "original" } } +! { dg-final { scan-tree-dump "#pragma omp allocate \\(kind=free\\)" "original" } } diff --git a/gcc/tree-core.h b/gcc/tree-core.h index 774bf0d7658..b0d5c074552 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -1257,6 +1257,9 @@ struct GTY(()) tree_base { EXPR_LOCATION_WRAPPER_P in NON_LVALUE_EXPR, VIEW_CONVERT_EXPR + OMP_ALLOCATE_KIND_ALLOCATE in + OMP_ALLOCATE + private_flag: TREE_PRIVATE in @@ -1283,6 +1286,9 @@ struct GTY(()) tree_base { ENUM_IS_OPAQUE in ENUMERAL_TYPE + OMP_ALLOCATE_KIND_FREE in + OMP_ALLOCATE + protected_flag: TREE_PROTECTED in diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc index 4d21babbd34..23dd45de556 100644 --- a/gcc/tree-pretty-print.cc +++ b/gcc/tree-pretty-print.cc @@ -3541,6 +3541,10 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags, case OMP_ALLOCATE: pp_string (pp, "#pragma omp allocate "); + if (OMP_ALLOCATE_KIND_ALLOCATE (node)) + pp_string (pp, "(kind=allocate) "); + else if (OMP_ALLOCATE_KIND_FREE (node)) + pp_string (pp, "(kind=free) "); dump_omp_clauses (pp, OMP_ALLOCATE_CLAUSES (node), spc, flags); break; diff --git a/gcc/tree.h b/gcc/tree.h index b2575c18693..1b67505f974 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1467,6 +1467,10 @@ class auto_suppress_location_wrappers TREE_OPERAND (OACC_UPDATE_CHECK (NODE), 0) #define OMP_ALLOCATE_CLAUSES(NODE) TREE_OPERAND (OMP_ALLOCATE_CHECK (NODE), 0) +#define OMP_ALLOCATE_KIND_ALLOCATE(NODE) \ + (OMP_ALLOCATE_CHECK (NODE)->base.public_flag) +#define OMP_ALLOCATE_KIND_FREE(NODE) \ + (OMP_ALLOCATE_CHECK (NODE)->base.private_flag) #define OMP_PARALLEL_BODY(NODE) TREE_OPERAND (OMP_PARALLEL_CHECK (NODE), 0) #define OMP_PARALLEL_CLAUSES(NODE) TREE_OPERAND (OMP_PARALLEL_CHECK (NODE), 1)