[Patch,v4] Fortran/OpenMP: Fix mapping of array descriptors and deferred-length strings

2023-03-23 Thread Tobias Burnus

[GCC 13 vs GCC 14]
I am unsure whether this should still go to GCC 13 or not. It is somewhat larger
albeit well contained (Fortran, only OpenMP, ...) and fixes real-world bugs,
but it is not a regression - and we are meanwhile slowly approaching the 
release.

An alternative would be to go to GCC 14 and then be eventually backported to 
GCC 14
(albeit I am not sure whether early testing would be better). Or just to GCC 
14, hmm.

Thoughts?

* * *

Another update - fixing an independent issue which makes sense to be part of 
this
patch.

Allocatable/pointer scalars are currently mapped as:

 #pragma omp target enter data map(to:*var.1_1 [len: 4]) map(alloc:var [pointer 
assign, bias: 0])
 #pragma omp target exit data map(from:*var.2_2 [len: 4])

where 'GOMP_MAP_POINTER' is removed in gimplify.cc. In v3 (and v4) of this 
patch,
this kind of handling moved from gimplify.cc to fortran/trans-openmp.cc; 
however,
v3 has the same problem. For allocatable arrays, we have PSET + POINTER and
the PSET part is changed/set to RELEASE/DELETE for 'exit data'

But for scalars, the map was still left on the stack. Besides having a stale 
map,
this could lead to fails when the stack was popped, especially when attempting
to later map another stack variable with the same stack address, partially
overlapping with the stale POINTER.

Side remark:
I found this for testcase that is part of an upcoming deep-mapping follow-up 
patch;
that test failed with -O1 but worked with -O0/-Og due to changed stack usage.
(Deep-mapping of allocatable components is on the OG12 branch; it is scheduled
for mainline integration after stage1 opened.)


The updated mainline patch is included; map-10.f90 is the new testcase.
If anyone wants to see it separately, the patch has been committed to OG12 as
https://gcc.gnu.org/g:8ea805840200f7dfd2c11b37abf5fbfe479c2fe2

Comments/thoughts/remarks to this patch?

Tobias

PS: For the rest of the patch, see a short description below - or with some 
longer
remarks previous in this thread.

On 27.02.23 13:15, Tobias Burnus wrote:

And another re-diff for GCC 13/mainline, updating gcc/testsuite/

(The last change is related to the "[OG12,committed] Update dg-dump-scan
for ..." discussion + OG12 https://gcc.gnu.org/g:e4de87a2309 /
https://gcc.gnu.org/pipermail/gcc-patches/2023-February/612871.html )

On 23.02.23 17:42, Tobias Burnus wrote:

On 21.02.23 12:57, Tobias Burnus wrote:

This patch moves some generic code for Fortran out of gimplify.cc
to trans-openmp.cc and fixes several issues related to mapping.

Tested with nvptx offloading.
OK for mainline?

Tobias

Caveats:

Besides the issues shown in the comment-out code, there remains also an
issue with implicit mapping - at least for deferred-length strings,
but I wouldn't be surprised if - at least depending on the used
'defaultmap' value (e.g. 'alloc') - there are also issues with array
descriptors.

Note:

Regarding the declare target check for mapping: Without declare
target, my assumption is that the hidden length variable will
get implicitly mapped if needed. Independent of deferred-length
or not, there is probably an issue with 'defaultmap(none)' and
the hidden variable. - In any case, I prefer to defer all those
issues to later (by having them captured in one/several PR).


Tobias

PS: This patch is a follow up to
  [Patch] Fortran/OpenMP: Fix DT struct-component with 'alloc' and
array descr
https://gcc.gnu.org/pipermail/gcc-patches/2022-November/604887.html
which fixed part of the problems. But as discussed on IRC, it did
treat 'alloc'
as special and missed some other map types. - In addition, this patch
has a
much extended test coverage and fixes some more issues found that way.

-
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
Fortran/OpenMP: Fix mapping of array descriptors and deferred-length strings

Previously, array descriptors might have been mapped as 'alloc'
instead of 'to' for 'alloc', not updating the array bounds. The
'alloc' could also appear for 'data exit', failing with a libgomp
assert. In some cases, either array descriptors or deferred-length
string's length variable was not mapped. And, finally, some offset
calculations with array-sections mappings went wrong.

Additionally, the patch now unmaps for scalar allocatables/pointers
the GOMP_MAP_POINTER, avoiding stale mappings.

The testcases contain some comment-out tests which require follow-up
work and for which PR exist. Those mostly relate to deferred-length
strings which have several issues beyong OpenMP support.

gcc/fortran/ChangeLog:

	* trans-decl.cc (gfc_get_symbol_decl): Add attributes
	such as 'declare target' also to hidden artificial
	variable for deferred-length character variables.
	* trans-openmp.cc (gfc_trans_omp_array_section,
	gfc_trans_omp_clauses, gfc_

[OG12][committed] Fortran: Add attr.class_ok check for generate_callback_wrapper

2023-03-23 Thread Tobias Burnus

On OG12, the OpenMP deep-mapping support added a callback procedure to the 
vtable.
That one did not handle error recovery well (ICE when a CLASS component as not 
(class_)ok.

The attached patch has been committed as 
https://gcc.gnu.org/g:9c18db65914a751e4a1d9330ccc1659fe5ef270d
and applies only to OG12 (= git branch devel/omp/gcc-12) as mainline does not 
have this
code (yet).

* * *

The plan is to upstream the deep-mapping support, i.e. mapping of allocatable 
components.
The current OG12 implementation handles both mapping the declared type and the 
dynamic type,
the latter requires the wrapper, generated by generate_callback_wrapper.

I plan to upstream first the static part - and only then think about the 
wrapper. I think
the wrapper could be useful for coarrays as well - namely, for the user-defined 
reduction,
but I have not fully thought about it. It would break the ABI as the vtable 
gets another
entry before the type-bound procedures, which is why I am a bit hesitant; it it 
gets merged,
we it would be the opportunity to change some other things as well - like: 
generating the
CLASS functions/vtable only when used. (→ weak symbols to permit it in multiple 
translation
units; storing the fact that it has been generated in the module.)
But that's offtopic.

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
commit 9c18db65914a751e4a1d9330ccc1659fe5ef270d
Author: Tobias Burnus 
Date:   Thu Mar 23 14:29:00 2023 +0100

Fortran: Add attr.class_ok check for generate_callback_wrapper

Proper variables/components of type BT_CLASS have 'class_ok' set; check
for that to avoid an ICE on invalid code for gfortran.dg/pr108434.f90.

gcc/fortran/
* class.cc (generate_callback_wrapper): Add attr.class_ok check.
* resolve.cc (resolve_fl_derived): Likewise.

diff --git a/gcc/fortran/ChangeLog.omp b/gcc/fortran/ChangeLog.omp
index 663102d9329..f7d1f91f178 100644
--- a/gcc/fortran/ChangeLog.omp
+++ b/gcc/fortran/ChangeLog.omp
@@ -1,3 +1,8 @@
+2023-03-23  Tobias Burnus  
+
+	* class.cc (generate_callback_wrapper): Add attr.class_ok check.
+	* resolve.cc (resolve_fl_derived): Likewise.
+
 2023-03-23  Tobias Burnus  
 
 	* trans-openmp.cc (gfc_trans_omp_clauses): Fix unmapping of
diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index 35dc35d2ee6..7ab6923523f 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -2550,6 +2550,9 @@ generate_callback_wrapper (gfc_symbol *vtab, gfc_symbol *derived,
 	 cb (token, comp->var(.data), size, 0, var's cb fn);  */
   for (gfc_component *comp = derived->components; comp; comp = comp->next)
 {
+  if (__builtin_expect (comp->ts.type == BT_CLASS
+			&& !comp->attr.class_ok, 0))
+	continue;
   bool pointer = (comp->ts.type == BT_CLASS
 		  ? CLASS_DATA (comp)->attr.pointer : comp->attr.pointer);
   bool proc_ptr = comp->attr.proc_pointer;
@@ -2590,7 +2593,7 @@ generate_callback_wrapper (gfc_symbol *vtab, gfc_symbol *derived,
 	  size->where = gfc_current_locus;
 	}
 
-  if (!proc_ptr && comp->ts.type == BT_CLASS)
+  if (!proc_ptr && comp->ts.type == BT_CLASS && comp->attr.class_ok)
 	{
 	  gfc_add_data_component (expr);
 	  if (comp->attr.dimension)
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index aaeaf396b91..15db1252366 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -15173,7 +15173,8 @@ resolve_fl_derived (gfc_symbol *sym)
   gfc_component *c = (sym->attr.is_class
 		  ? CLASS_DATA (sym->components) : sym->components);
   for ( ; c; c = c->next)
-if ((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
+if ((c->ts.type == BT_DERIVED
+	|| (c->ts.type == BT_CLASS && c->attr.class_ok))
 	&& !c->ts.u.derived->resolve_symbol_called)
   {
 	if (c->ts.u.derived->components == NULL


[OG12][committed] Fortran/OpenMP: Fix 'alloc' and 'from' mapping for allocatable components

2023-03-23 Thread Tobias Burnus

This is about OpenMP's "deep mapping" of allocatable components of derived 
types.

The basic feature is on OG12 (and OG11) but yet in GCC mainline. The old
submissions are at 
https://gcc.gnu.org/pipermail/gcc-patches/2022-April/593704.html

My plan is to get the whole feature into GCC 14 once trunk has opened (and
after some simpler pending patches have been merged). It requires some
re-diffing to be more digestible.

* * *

OG12: This patch as been committed to the devel/omp/gcc-12 branch as
https://gcc.gnu.org/g:a63735b8034db65a33c359633462accd9d71d3b5

* * *

This patch fixes an issue with 'map(alloc:' and 'map(from:' with
deep mapping of allocatable components - namely:

* For unmapping/coping to the host, the state of unallocated allocatables
  needs to be preservered.
* For mapping to the device ('alloc' and 'from'), we still need to copy
  data to the device to have the array bounds correctly set.

The data pointer (of allocated allocatables) is set as part of allocating
memory on the device ('attach'); thus, this part works.

As described in the patch (cf. comment above the checking function), we
could either copy only the descriptor data (and the NULL for pointers)
or we copy everything (shallowly) which includes this data. As there is
no means to do the former (without changing the refcount), we do the latter.

NOTE: The actual data to which the scalar/array allocatable points to is
not 'to' mapped but only 'alloc'. As that is supposed to be the large data,
copying everything should™ not cause a large performance penalty with real-world
code; it could be even faster than, let's say, copying 5 descriptors separately.

OpenMP spec side: It is not completely clear how the OpenMP spec expects
the copy out to work. Hence, I filed OpenMP Spec Issue #3545.
-
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
commit a63735b8034db65a33c359633462accd9d71d3b5
Author: Tobias Burnus 
Date:   Thu Mar 23 18:04:17 2023 +0100

Fortran/OpenMP: Fix 'alloc' and 'from' mapping for allocatable components

Even with 'alloc' and map-entering 'from' mapping, the following should hold.
For explicit mapping, that's already the case, this handles the automatical
deep mapping of allocatable components. Namely:
* On the device, the array bounds (of allocated allocatables) must match the
  host, implying 'to' (or 'tofrom') mapping.
* On map exiting, the copying out shall not destroy the unallocated allocation
  status (nor the pointer address of allocated allocatables).

The latter was not a problem for allocated allocatables as for those a pointer
was GOMP_MAP_ATTACHed; however, for unallocated allocatables, before it copied
back device-allocated memory which might not be nullified.

While 'alloc' was not deep-mapped at all, for map-entering 'from', the array
bounds were not set, making allocated derived-type components inaccessible on
the device (and wrong on the host on copy back).

The solution is, first, to deep-map 'alloc' as well and to copy to the device
even with 'alloc' and (map-entering) 'from'. This copying is only done if there
is a scalar (for the unallocated case) or array allocatable directly in the
derived type and then it is shallowly copied; the data pointed to is then again
only alloc'ed, unless it contains in turn allocatables.

gcc/fortran/

* trans-openmp.cc (gfc_has_alloc_comps): Add 'bool
shallow_alloc_only=false' arg.
(gfc_omp_replace_alloc_by_to_mapping): New, call it.
(gfc_omp_deep_map_kind_p): Return 'true' also for '(present,)alloc'.
(gfc_omp_deep_mapping_item, gfc_omp_deep_mapping_do): On map entering,
replace shallowly 'alloc'/'from' by '(from)to' mapping if there are
allocatable components.

libgomp/

* testsuite/libgomp.fortran/map-alloc-comp-8.f90: New test.
---
 gcc/fortran/ChangeLog.omp  |  10 +
 gcc/fortran/trans-openmp.cc|  96 +++-
 libgomp/ChangeLog.omp  |   4 +
 .../testsuite/libgomp.fortran/map-alloc-comp-8.f90 | 268 +
 4 files changed, 371 insertions(+), 7 deletions(-)

diff --git a/gcc/fortran/ChangeLog.omp b/gcc/fortran/ChangeLog.omp
index f7d1f91f178..e3ab2254215 100644
--- a/gcc/fortran/ChangeLog.omp
+++ b/gcc/fortran/ChangeLog.omp
@@ -1,3 +1,13 @@
+2023-03-23  Tobias Burnus  
+
+	* trans-openmp.cc (gfc_has_alloc_comps): Add 'bool
+	shallow_alloc_only=false' arg.
+	(gfc_omp_replace_alloc_by_to_mapping): New, call it.
+	(gfc_omp_deep_map_kind_p): Return 'true' also for '(present,)alloc'.
+	(gfc_omp_deep_mapping_item, gfc_omp_deep_mapping_do): On map entering,
+	repla

Re: [PATCH][stage1] Remove conditionals around free()

2023-03-23 Thread NightStrike via Fortran
On Fri, Mar 3, 2023 at 10:14 PM Jerry D via Fortran  wrote:

> I am certainly not a C++ expert but it seems to me this all begs for
> automatic finalization where one would not have to invoke free at all.
> I suspect the gfortran frontend is not designed for such things.

+1 for RAII