Re: [PATCH v7 2/5] OpenMP/OpenACC: Rework clause expansion and nested struct handling

2023-11-29 Thread Tobias Burnus

Hi Julian,

On 29.11.23 12:43, Julian Brown wrote:

Here is a patch incorporating your initial review comments
(hopefully!).


Thanks.

The patch LGTM - with the two remarks below addressed.

(i.e. fixing one testcase and filing two PRs (or common PR) about the features
missing and exposed by the two test cases, referencing also to those testcases
- and for the lvalues mentioning the OpenMP spec issue number.)

* * *

BTW: The 1/5 has been several times approved and is just reindenting - and
is obviously still OK.


(Review wise, 3/5, 4/5 and 5/5 still has to be done.

I think the patch can go in before - given the huge improvements, even though
it regresses for a few cases (xfail added for 2 Fortran testcases). 3/5 
un-xfails
one and a half of the textcases, 5/5 un-xfails the remaining half and all of 
{3,4,5}/5
contain very useful improvements besides this. - But maybe waiting for at least 
3/5
makes sense.

In either case, I try to review the remaining patches soon.)

* * *

Question regarding the following:
(a) The dg-xfail-run-if looks bogus as this an OpenMP test and not an OpenACC 
test
(b) If there is shared memory, using 'omp target' should be fine.

Namely, given that:


--- /dev/null +++ b/libgomp/testsuite/libgomp.c++/target-49.C @@ -0,0
+1,37 @@ +#include  +#include  + +struct s { + int
()[10]; + s(int ()[10]) : a(a0) {} +}; + +int +main (int argc,
char *argv[]) +{ + int la[10]; + s v_real(la); + s *v = _real; + +
memset (la, 0, sizeof la); + + #pragma omp target enter data map(to:
v) + + /* Copying the whole v[0] here DOES NOT WORK yet because the
reference 'a' is + not copied "as if" it was mapped explicitly as a
member. FIXME. */ + #pragma omp target enter data map(to: v[0]) + +
//#pragma omp target + { + v->a[5]++; + } + + #pragma omp target exit
data map(release: v[0]) + #pragma omp target exit data map(from: v) +
+ assert (v->a[5] == 1); + + return 0; +} + +// { dg-xfail-run-if
"TODO" { *-*-* } { "-DACC_MEM_SHARED=0" } }

Shouldn't the XFAIL not be based on '{ target offload_device_nonshared_as }'
and the 'omp target' be uncommented?

And I wonder whether we need to file a PR about this issue - I guess it is not
addressed by any of the follow-up issues and might get forgotten unless there 
is PR.


* * *

libgomp/testsuite/libgomp.c++/baseptrs-4.C ... // Needs map clause
"lvalue"-parsing support. //#define REF2ARRAY_DECL_BASE


There is an open OpenMP issue to disallow some lvalues, namely:
OpenMP Issue 2618 ("Clarify behavior of mapping lvalues on target construct")
talks about code like the following

  map(*p = 10)
  map(x = 20)
  map(x ? y[0] : p[1])
  map(f(y))

is valid or not. The sentiment was to require that a 'map' clause list item
must have a base pointer or a base variable.


However, it looks as your examples would be valid in this regard. Can you file
a PR about this one? Referencing both to this testcase and to the OpenMP issue?

(I do note that Clang and GCC reject the lvalue examples from the OpenMP issue
but not your reference examples; those are accepted by clang++-14.)


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


Re: [PATCH v7 2/5] OpenMP/OpenACC: Rework clause expansion and nested struct handling

2023-11-14 Thread Tobias Burnus

Hi Julian,

first round of comments - I think I need a second pass as the patch is
long and complex. The depth of review also was decreasing, hence, I
assume I will spot things in later parts of the compiler.

In any case, I think the patch is a huge leap forward and very useful!

Contrary to previous iterations of the patch series, it looks as if
{1,2}/5 could be sensibly applied before {3,4,5}/5. However, those are
smaller or tiny, it should be way quicker to review them!

* * *

CROSS REFS

This patch is part of the patch set
"[PATCH v7 0/5] OpenMP/OpenACC: map clause and OMP gimplify rework"
https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627895.html

This patch set in turn is required for the follow-up patch set
https://gcc.gnu.org/pipermail/gcc-patches/2023-September/629363.html
'[PATCH 0/8] OpenMP: lvalue parsing and "declare mapper" support'

and it looks as if it would be very useful for some other WIP patches
like map+iterator.

* * *

The patch 1/5 is just an indentation patch to make the following patch
smaller - and it has been approved multiple times.

This patch can be found at
  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627897.html
in case someone wants to read the full patch or Julian's patch-intro
comments.

* * *

I do note that all 5 patches of this patch set apply cleanly with some
fuzzy line matching, but:

WARNING: at least for this patch (2/5), code gets wrongly applied
in (c-)parser.cc - see below.

On 19.08.23 00:47, Julian Brown wrote:

This patch reworks clause expansion in the C, C++ and (to a lesser
extent) Fortran front ends for OpenMP and OpenACC mapping nodes used in
GPU offloading support.

At present a single clause may be turned into several mapping nodes,
or have its mapping type changed, in several places scattered through
the front- and middle-end.  The analysis relating to which particular
transformations are needed for some given expression has become quite hard
to follow.  Briefly, we manipulate clause types in the following places:


[...]

[As the patch is very large, I copied the interesting bits out of the patch
and comment on them - I hope that preserves enough context to be useful.]


  tree c_omp_address_inspector::get_address ()


This class member function is unused. It returns 'orig' and that member variable
is used a couple of times in the member functions - but not this function.

I think it can be removed. (I also find the name slightly misleading.)

* * *


+c_omp_address_inspector::maybe_zero_length_array_section (tree clause)
+{
+  switch (OMP_CLAUSE_MAP_KIND (clause))
+{
+case GOMP_MAP_ALLOC:
+case GOMP_MAP_IF_PRESENT:
+case GOMP_MAP_TO:
+case GOMP_MAP_FROM:
+case GOMP_MAP_TOFROM:
+case GOMP_MAP_ALWAYS_TO:
+case GOMP_MAP_ALWAYS_FROM:
+case GOMP_MAP_ALWAYS_TOFROM:
+case GOMP_MAP_RELEASE:
+case GOMP_MAP_DELETE:
+case GOMP_MAP_FORCE_TO:
+case GOMP_MAP_FORCE_FROM:
+case GOMP_MAP_FORCE_TOFROM:
+case GOMP_MAP_FORCE_PRESENT:

Shouldn't this also include:

GOMP_MAP_ALWAYS_PRESENT_TO:
GOMP_MAP_ALWAYS_PRESENT_FROM:
GOMP_MAP_ALWAYS_PRESENT_TOFROM:
GOMP_MAP_PRESENT_ALLOC:
GOMP_MAP_PRESENT_TO:

?

* * *

+omp_expand_access_chain (tree c, tree expr, vec _tokens,
+unsigned *idx)
+{
+  using namespace omp_addr_tokenizer;
+  location_t loc = OMP_CLAUSE_LOCATION (c);
+  unsigned i = *idx;
+  tree c2 = NULL_TREE;
+  gomp_map_kind kind
+= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM
+   || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
+  && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FROM
+  || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DELETE
+  || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_RELEASE
+  || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_FROM
+  || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_FROM
+  || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_PRESENT_FROM)))
+  ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH;

GOMP_MAP_ALWAYS_PRESENT_FROM  missing?

And I personally find it more readable to have
  if (...
  ...
  ...)
kind = GOMP_MAP_DETACH;
  else
kind = GOMP_MAP_ATTACH;

as in the assignment above, the lhs is in this case really far from the rhs.


* * *

I do see in omp_expand_access_chain, which is shared by C and C++, that the 
following
accesses are handled:

  ACCESS_POINTER,
  ACCESS_POINTER_OFFSET,
  ACCESS_INDEXED_ARRAY,

But not:
  ACCESS_REF_TO_POINTER,
  ACCESS_REF_TO_POINTER_OFFSET,
  ACCESS_INDEXED_REF_TO_ARRAY

Do those need to be handled as well?

SIDENOTE: As Fortran allocatable components, reference-type variables in a C++ 
class ('class', 'struct')
are automatically be copied when doing 'map(var)' - contrary to pointer members 
that need to be explicitly
be mapped (either at mapping side or via a mapper). (And contrary to Fortran 
allocatables, reference-type members
are always "there" - not like with allocatables can change from unallocated to 
allocated - with all compilations
of