Re: [Patch][OpenMP][Fortran] Support absent optional args with use_device_{ptr, addr} (+ OpenACC's use_device clause)

2020-04-29 Thread Thomas Schwinge
Hi!

On 2019-11-11T13:14:43+0100, I wrote:
> On 2019-11-08T16:41:23+0100, Tobias Burnus  wrote:
>> --- /dev/null
>> +++ b/libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-2.f90
>
> When adding '{ dg-do run }' for torture testing (please remember to), I
> see the '-O0' and '-O1' execution testing FAIL, complaining that
> "libgomp: use_device_ptr pointer wasn't mapped".

That'd gotten resolved in the mean time, so I've now myself pushed to
master branch in commit b9dc11b6730a8030cfc85f0222cef523c9c5d27c "Torture
testing: 'libgomp.fortran/use_device_ptr-optional-2.f90'", see attached.


Grüße
 Thomas


-
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander 
Walter
>From b9dc11b6730a8030cfc85f0222cef523c9c5d27c Mon Sep 17 00:00:00 2001
From: Thomas Schwinge 
Date: Mon, 11 Nov 2019 11:30:33 +0100
Subject: [PATCH] Torture testing:
 'libgomp.fortran/use_device_ptr-optional-2.f90'

Fix-up for commit a2c26c50310a336361d8129ecdd43d3001d6cb3a (r278046) "Fortran]
Support absent optional args with use_device_{ptr,addr}".

	libgomp/
	* testsuite/libgomp.fortran/use_device_ptr-optional-2.f90: Add
	'dg-do run'.
---
 libgomp/ChangeLog| 5 +
 .../testsuite/libgomp.fortran/use_device_ptr-optional-2.f90  | 1 +
 2 files changed, 6 insertions(+)

diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index ee1764d4ae31..53bb8d23fa15 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,8 @@
+2020-04-29  Thomas Schwinge  
+
+	* testsuite/libgomp.fortran/use_device_ptr-optional-2.f90: Add
+	'dg-do run'.
+
 2020-04-23  Andrew Stubbs  
 
 	PR other/94629
diff --git a/libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-2.f90 b/libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-2.f90
index 641ebd98962a..7a4aaae52cbd 100644
--- a/libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-2.f90
@@ -1,3 +1,4 @@
+! { dg-do run }
 ! Check whether absent optional arguments are properly
 ! handled with use_device_{addr,ptr}.
 program main
-- 
2.26.2



Re: [Patch][OpenMP][Fortran] Support absent optional args with use_device_{ptr,addr} (+ OpenACC's use_device clause)

2019-11-11 Thread Thomas Schwinge
Hi Tobias!

Thanks for looking into this mess ;-) of Fortran optional arguments
support for OMP, based on what Kwok has already developed.


On 2019-11-08T16:41:23+0100, Tobias Burnus  wrote:
> --- /dev/null
> +++ b/libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-2.f90

When adding '{ dg-do run }' for torture testing (please remember to), I
see the '-O0' and '-O1' execution testing FAIL, complaining that
"libgomp: use_device_ptr pointer wasn't mapped".


Grüße
 Thomas


> @@ -0,0 +1,33 @@
> +! Check whether absent optional arguments are properly
> +! handled with use_device_{addr,ptr}.
> +program main
> + implicit none (type, external)
> + call foo()
> +contains
> +  subroutine foo(v, w, x, y, z)
> +integer, target, optional, value :: v
> +integer, target, optional :: w
> +integer, target, optional :: x(:)
> +integer, target, optional, allocatable :: y
> +integer, target, optional, allocatable :: z(:)
> +integer :: d
> +
> +!$omp target data map(d) use_device_addr(v, w, x, y, z)
> +  if(present(v)) stop 1
> +  if(present(w)) stop 2
> +  if(present(x)) stop 3
> +  if(present(y)) stop 4
> +  if(present(z)) stop 5
> +!$omp end target data
> +
> +! Using 'v' in use_device_ptr gives an ICE
> +! TODO: Find out what the OpenMP spec permits for use_device_ptr
> +
> +!$omp target data map(d) use_device_ptr(w, x, y, z)
> +  if(present(w)) stop 6
> +  if(present(x)) stop 7
> +  if(present(y)) stop 8
> +  if(present(z)) stop 9
> +!$omp end target data
> +  end subroutine foo
> +end program main


signature.asc
Description: PGP signature


Re: [Patch][OpenMP][Fortran] Support absent optional args with use_device_{ptr,addr} (+ OpenACC's use_device clause)

2019-11-08 Thread Jakub Jelinek
On Fri, Nov 08, 2019 at 04:41:23PM +0100, Tobias Burnus wrote:
> With DECL_ARTIFICIAL added and also_value replaced:
> Build on x86-64-gnu-linux. OK once regtested?

Almost.

> - gimplify_assign (x, var, );
> + if (do_optional_check && omp_check_optional_argument (ovar, true))
 
Do you need true here when just testing for non-NULL?
If yes, it would be better to call it just once, so that e.g. the
DECL_ARGUMENTS list is not walked twice.  So perhaps:

tree present;
present = (do_optional_check
   ? omp_check_optional_argument (ovar, true) : NULL_TREE);
if (present)
  {

> +   {
> + tree null_label = create_artificial_label (UNKNOWN_LOCATION);
> + tree notnull_label = create_artificial_label (UNKNOWN_LOCATION);
> + tree opt_arg_label = create_artificial_label (UNKNOWN_LOCATION);

I this this is already too long, so needs line wrapping before =.

> + tree new_x = unshare_expr (x);
> + tree present = omp_check_optional_argument (ovar, true);

And not call it here again.

> + gimplify_expr (, , NULL, is_gimple_val,
> +fb_rvalue);
> + gcond *cond = gimple_build_cond_from_tree (present,
> +notnull_label,
> +null_label);
> + gimple_seq_add_stmt (, cond);
> + gimple_seq_add_stmt (, gimple_build_label (null_label));
> + gimplify_assign (new_x, null_pointer_node, );
> + gimple_seq_add_stmt (, gimple_build_goto (opt_arg_label));

And here similarly.

> + if (do_optional_check
> + && omp_check_optional_argument (OMP_CLAUSE_DECL (c), true))
> +   {
> + tree null_label = create_artificial_label (UNKNOWN_LOCATION);
> + tree notnull_label = create_artificial_label (UNKNOWN_LOCATION);
> + tree opt_arg_label = create_artificial_label (UNKNOWN_LOCATION);
> + glabel *null_glabel = gimple_build_label (null_label);
> + glabel *notnull_glabel = gimple_build_label (notnull_label);
> + ggoto *opt_arg_ggoto = gimple_build_goto (opt_arg_label);
> + gimplify_expr (, _body, NULL, is_gimple_val,
> +fb_rvalue);
> + tree present = omp_check_optional_argument (OMP_CLAUSE_DECL (c),
> + true);

Similarly to the above.

Otherwise LGTM.

Jakub



Re: [Patch][OpenMP][Fortran] Support absent optional args with use_device_{ptr,addr} (+ OpenACC's use_device clause)

2019-11-08 Thread Tobias Burnus

Hi Jakub,

thanks for the review.

On 11/8/19 3:39 PM, Jakub Jelinek wrote:

+  /* Walk function argument list to find the hidden arg.  */
+  decl = DECL_ARGUMENTS (DECL_CONTEXT (decl));
+  for ( ; decl != NULL_TREE; decl = TREE_CHAIN (decl))
+   if (DECL_NAME (decl) == tree_name)
+ break;

Is this reliable?  I mean, consider -fallow-leading-underscore with:
subroutine foo (a, _a)


I also assume that this will break; unlikely in real-world code but still.


Not really sure if additional DECL_ARTIFICIAL (decl) test would be enough.


At least, I cannot quickly come up with a case where it will break. – I 
have now added it; also to the existing trans-expr.c function – which 
uses the used and, hence, same algorithm.



+omp_check_optional_argument (tree decl, bool also_value)

Why is the argument called for_present_check in the langhook and
also_value here?  Looks inconsistent.


Because I initially was thinking only of the VALUE attribute until I 
realized that assumed-shape arrays have the same issue; they use a local 
variable for the data – and make the actual array descriptor available 
via lang-specific field. – As the use is either an extra deref is needed 
or a check whether the variable is present, I changed the meaning – 
seemingly, three places survived with the old name.


With DECL_ARTIFICIAL added and also_value replaced:
Build on x86-64-gnu-linux. OK once regtested?

Tobias

2019-11-08  Tobias Burnus  
	Kwok Cheung Yeung  

	gcc/
	* langhooks-def.h (LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT):
	Renamed from LANG_HOOKS_OMP_IS_OPTIONAL_ARGUMENT; update define.
	(LANG_HOOKS_DECLS): Rename also here.
	* langhooks.h (lang_hooks_for_decls): Rename
	omp_is_optional_argument to omp_check_optional_argument; take
	additional bool argument.
	* omp-general.h (omp_check_optional_argument): Likewise.
	* omp-general.h (omp_check_optional_argument): Likewise.
	* omp-low.c (lower_omp_target): Update calls; handle absent
	Fortran optional arguments with USE_DEVICE_ADDR/USE_DEVICE_PTR.

	gcc/fortran/
	* trans-expr.c (gfc_conv_expr_present): Check for DECL_ARTIFICIAL
	for the VALUE hidden argument avoiding -fallow-underscore issues.
	* trans-decl.c (create_function_arglist): Also set
	GFC_DECL_OPTIONAL_ARGUMENT for per-value arguments.
	* f95-lang.c (LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT):
	Renamed from LANG_HOOKS_OMP_IS_OPTIONAL_ARGUMENT; point
	to gfc_omp_check_optional_argument.
	* trans.h (gfc_omp_check_optional_argument): Subsitutes
	gfc_omp_is_optional_argument declaration.
	* trans-openmp.c (gfc_omp_is_optional_argument): Make static.
	(gfc_omp_check_optional_argument): New function.

	libgomp/
	* testsuite/libgomp.fortran/use_device_ptr-optional-1.f90: Extend.
	* testsuite/libgomp.fortran/use_device_ptr-optional-2.f90: New.

 gcc/fortran/f95-lang.c |   4 +-
 gcc/fortran/trans-decl.c   |   3 +-
 gcc/fortran/trans-expr.c   |   3 +-
 gcc/fortran/trans-openmp.c |  63 ++-
 gcc/fortran/trans.h|   2 +-
 gcc/langhooks-def.h|   4 +-
 gcc/langhooks.h|  13 ++-
 gcc/omp-general.c  |  14 ++-
 gcc/omp-general.h  |   2 +-
 gcc/omp-low.c  | 117 -
 .../libgomp.fortran/use_device_ptr-optional-1.f90  |  22 
 .../libgomp.fortran/use_device_ptr-optional-2.f90  |  33 ++
 12 files changed, 232 insertions(+), 48 deletions(-)

diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index 0684c3b99cf..c7b592dbfe2 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -115,7 +115,7 @@ static const struct attribute_spec gfc_attribute_table[] =
 #undef LANG_HOOKS_INIT_TS
 #undef LANG_HOOKS_OMP_ARRAY_DATA
 #undef LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR
-#undef LANG_HOOKS_OMP_IS_OPTIONAL_ARGUMENT
+#undef LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT
 #undef LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE
 #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
 #undef LANG_HOOKS_OMP_REPORT_DECL
@@ -150,7 +150,7 @@ static const struct attribute_spec gfc_attribute_table[] =
 #define LANG_HOOKS_INIT_TS		gfc_init_ts
 #define LANG_HOOKS_OMP_ARRAY_DATA		gfc_omp_array_data
 #define LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR	gfc_omp_is_allocatable_or_ptr
-#define LANG_HOOKS_OMP_IS_OPTIONAL_ARGUMENT	gfc_omp_is_optional_argument
+#define LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT	gfc_omp_check_optional_argument
 #define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE	gfc_omp_privatize_by_reference
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING	gfc_omp_predetermined_sharing
 #define LANG_HOOKS_OMP_REPORT_DECL		gfc_omp_report_decl
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index ffa6316..80ef45d892e 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -2691,9 +2691,8 @@ 

Re: [Patch][OpenMP][Fortran] Support absent optional args with use_device_{ptr,addr} (+ OpenACC's use_device clause)

2019-11-08 Thread Jakub Jelinek
On Thu, Nov 07, 2019 at 11:42:22AM +0100, Tobias Burnus wrote:
> +  /* For VALUE, the scalar variable is passed as is but a hidden argument
> + denotes the value.  Cf. trans-expr.c.  */
> +  if (TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
> +{
> +  char name[GFC_MAX_SYMBOL_LEN + 2];
> +  tree tree_name;
> +
> +  name[0] = '_';
> +  strcpy ([1], IDENTIFIER_POINTER (DECL_NAME (decl)));
> +  tree_name = get_identifier (name);
> +
> +  /* Walk function argument list to find the hidden arg.  */
> +  decl = DECL_ARGUMENTS (DECL_CONTEXT (decl));
> +  for ( ; decl != NULL_TREE; decl = TREE_CHAIN (decl))
> + if (DECL_NAME (decl) == tree_name)
> +   break;
> +
> +  gcc_assert (decl);
> +  return decl;
> +}

Is this reliable?  I mean, consider -fallow-leading-underscore with:
subroutine foo (a, _a)
  integer, optional, value :: a
  logical(kind=1), value :: _a
...
end subroutine foo
and whatever OpenMP clause is affected in ...
In GIMPLE dump I certainly see:
foo (integer(kind=4) a, logical(kind=1) _a, logical(kind=1) _a)
and I bet the above would pick the wrong one.

Not really sure if additional DECL_ARTIFICIAL (decl) test would be enough.

> --- a/gcc/omp-general.c
> +++ b/gcc/omp-general.c
> @@ -63,12 +63,18 @@ omp_is_allocatable_or_ptr (tree decl)
>return lang_hooks.decls.omp_is_allocatable_or_ptr (decl);
>  }
>  
> -/* Return true if DECL is a Fortran optional argument.  */
> +/* Check whether this DECL belongs to a Fortran optional argument.
> +   With 'for_present_check' set to false, decls which are optional parameters
> +   themselve are returned as tree - or a NULL_TREE otherwise. Those decls are
> +   always pointers.  With 'for_present_check' set to true, the decl for 
> checking
> +   whether an argument is present is returned; for arguments with value
> +   attribute this is the hidden argument and of BOOLEAN_TYPE.  If the decl is
> +   unrelated to optional arguments, NULL_TREE is returned.  */
>  
> -bool
> -omp_is_optional_argument (tree decl)
> +tree
> +omp_check_optional_argument (tree decl, bool also_value)

Why is the argument called for_present_check in the langhook and
also_value here?  Looks inconsistent.

> --- a/gcc/omp-general.h
> +++ b/gcc/omp-general.h
> @@ -74,7 +74,7 @@ struct omp_for_data
>  
>  extern tree omp_find_clause (tree clauses, enum omp_clause_code kind);
>  extern bool omp_is_allocatable_or_ptr (tree decl);
> -extern bool omp_is_optional_argument (tree decl);
> +extern tree omp_check_optional_argument (tree decl, bool also_value);
>  extern bool omp_is_reference (tree decl);
>  extern void omp_adjust_for_condition (location_t loc, enum tree_code 
> *cond_code,
> tree *n2, tree v, tree step);

Here too.

Jakub



Re: [Patch][OpenMP][Fortran] Support absent optional args with use_device_{ptr,addr} (+ OpenACC's use_device clause)

2019-11-07 Thread Tobias Burnus
Thinking about the patch over night, I have now updated it a bit: 
Namely, I only add the "if(present-check)" condition, if the original 
variable is dereferenced. There is no need for code like


  omp_data_arr.c = c == NULL ? NULL : c;

and then, after the libgomp call, code like "c_2 = c == NULL ? NULL : 
omp_data_arr.c;"; due to the libgomp call, the latter cannot even be 
optimized away.


Hence, I added 'do_optional_check'; additionally, I had a 
libgomp.fortran/use_device_ptr-optional-1.f90 change floating around, 
which I included. Otherwise unchanged.


Retested. OK for the trunk?

Cheers,

Tobias

On 11/6/19 4:04 PM, Tobias Burnus wrote:

This patch is based on Kwok's patch, posted as (4/5) at 
https://gcc.gnu.org/ml/gcc-patches/2019-07/msg00964.html – which is 
targeting OpenACC's use_device* – but it also applies to OpenMP 
use_device_{ptr,addr}.


I added an OpenMP test case. It showed that for arguments with value 
attribute and for assumed-shape array, one needs to do more — as the 
decl cannot be directly used for the is-argument-present check.


(For 'value', a hidden boolean '_' + arg-name is passed in addition; 
for assumed-shape arrays, the array descriptor "x" is replaced by the 
local variable "x.0" (with "x.0 = x->data") and the original decl "x" 
is in GFC_DECL_SAVED_DESCRIPTOR. Especially for assumed-shape arrays, 
the new decl cannot be used unconditionally as it is uninitialized 
when the argument is absent.)


Bootstrapped and regtested on x86_64-gnu-linux without offloading + 
with nvptx.

OK?

Cheers,

Tobias

*The OpenACC test cases are in 5/5 and depend on some other changes. 
Submission of {1,missing one line of 2,3,5}/5 is planned next.
PPS: For fully absent-optional support, mapping needs to be handled 
for OpenACC (see Kwok's …/5 patches) and OpenMP (which is quite 
different on FE level) – and OpenMP also needs changes for the share 
clauses.]


2019-11-07  Tobias Burnus  
	Kwok Cheung Yeung  

	gcc/
	* langhooks-def.h (LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT):
	Renamed from LANG_HOOKS_OMP_IS_OPTIONAL_ARGUMENT; update define.
	(LANG_HOOKS_DECLS): Rename also here.
	* langhooks.h (lang_hooks_for_decls): Rename
	omp_is_optional_argument to omp_check_optional_argument; take
	additional bool argument.
	* omp-general.h (omp_check_optional_argument): Likewise.
	* omp-general.h (omp_check_optional_argument): Likewise.
	* omp-low.c (lower_omp_target): Update calls; handle absent
	Fortran optional arguments with USE_DEVICE_ADDR/USE_DEVICE_PTR.

	gcc/fortran/
	* trans-decl.c (create_function_arglist): Also set
	GFC_DECL_OPTIONAL_ARGUMENT for per-value arguments.
	* f95-lang.c (LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT):
	Renamed from LANG_HOOKS_OMP_IS_OPTIONAL_ARGUMENT; point
	to gfc_omp_check_optional_argument.
	* trans.h (gfc_omp_check_optional_argument): Subsitutes
	gfc_omp_is_optional_argument declaration.
	* trans-openmp.c (gfc_omp_is_optional_argument): Make static.
	(gfc_omp_check_optional_argument): New function.

	libgomp/
	* testsuite/libgomp.fortran/use_device_ptr-optional-1.f90: Extend.
	* testsuite/libgomp.fortran/use_device_ptr-optional-2.f90: New.

 gcc/fortran/f95-lang.c  |   4 ++--
 gcc/fortran/trans-decl.c|   3 +--
 gcc/fortran/trans-openmp.c  |  62 +-
 gcc/fortran/trans.h |   2 +-
 gcc/langhooks-def.h |   4 ++--
 gcc/langhooks.h |  13 -
 gcc/omp-general.c   |  14 ++
 gcc/omp-general.h   |   2 +-
 gcc/omp-low.c   | 117 -
 libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-1.f90 |  22 ++
 libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-2.f90 |  33 +
 11 files changed, 229 insertions(+), 47 deletions(-)

diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index 0684c3b99cf..c7b592dbfe2 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -115,7 +115,7 @@ static const struct attribute_spec gfc_attribute_table[] =
 #undef LANG_HOOKS_INIT_TS
 #undef LANG_HOOKS_OMP_ARRAY_DATA
 #undef LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR
-#undef LANG_HOOKS_OMP_IS_OPTIONAL_ARGUMENT
+#undef LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT
 #undef LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE
 #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
 #undef LANG_HOOKS_OMP_REPORT_DECL
@@ -150,7 +150,7 @@ static const struct attribute_spec gfc_attribute_table[] =
 #define LANG_HOOKS_INIT_TS		gfc_init_ts
 #define LANG_HOOKS_OMP_ARRAY_DATA