[PATCH] Fortran: Fix incompatible types between INTEGER(8) and TYPE(c_ptr)

2023-10-20 Thread Paul-Antoine Arras

Hi all,

The attached patch fixes a bug that causes valid OpenMP declare variant 
directive and functions to be rejected with the following error (see 
testcase):


c_ptr.f90:41:37:

   41 | !$omp declare variant(foo_variant)  &
  | 1
Error: variant ‘foo_variant’ and base ‘foo’ at (1) have incompatible 
types: Type mismatch in argument 'c_bv' (INTEGER(8)/TYPE(c_ptr))


The fix consists in special-casing this situation in gfc_compare_types().

OK for mainline?

Thanks,
--
PA
From 8e5fa4828678a1388e75795de2a1f253d9f0ec95 Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Fri, 20 Oct 2023 12:42:49 +0200
Subject: [PATCH] Fortran: Fix incompatible types between INTEGER(8) and
 TYPE(c_ptr)

In the context of an OpenMP declare variant directive, arguments of type C_PTR
are sometimes recognised as C_PTR in the base function and as INTEGER(8) in the
variant - or the other way around, depending on the parsing order.
This patch prevents such situation from turning into a compile error.

2023-10-20  Paul-Antoine Arras  
	Tobias Burnus  

gcc/fortran/ChangeLog:

	* interface.cc (gfc_compare_types): Return true in this situation.

gcc/testsuite/ChangeLog:

	* gfortran.dg/c_ptr_tests_20.f90: New test.
---
 gcc/fortran/ChangeLog.omp|  5 ++
 gcc/fortran/interface.cc | 17 +++---
 gcc/testsuite/ChangeLog.omp  |  4 ++
 gcc/testsuite/gfortran.dg/c_ptr_tests_20.f90 | 56 
 4 files changed, 76 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/c_ptr_tests_20.f90

diff --git a/gcc/fortran/ChangeLog.omp b/gcc/fortran/ChangeLog.omp
index 62a33475ee5..299223ceaa7 100644
--- a/gcc/fortran/ChangeLog.omp
+++ b/gcc/fortran/ChangeLog.omp
@@ -1,3 +1,8 @@
+2023-10-20  Paul-Antoine Arras  
+	Tobias Burnus  
+
+	* interface.cc (gfc_compare_types): Return true in this situation.
+
 2023-09-19  Tobias Burnus  
 
 	Backported from master:
diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index e9843e9549c..8bd35fd6d22 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -705,12 +705,17 @@ gfc_compare_types (gfc_typespec *ts1, gfc_typespec *ts2)
 
   /* Special case for our C interop types.  FIXME: There should be a
  better way of doing this.  When ISO C binding is cleared up,
- this can probably be removed.  See PR 57048.  */
-
-  if (((ts1->type == BT_INTEGER && ts2->type == BT_DERIVED)
-   || (ts1->type == BT_DERIVED && ts2->type == BT_INTEGER))
-  && ts1->u.derived && ts2->u.derived
-  && ts1->u.derived == ts2->u.derived)
+ this can probably be removed.  See PR 57048.
+ Note that this does not distinguish between c_ptr and c_funptr.  */
+
+  if ((ts1->type == BT_INTEGER && ts2->type == BT_DERIVED
+   && ts1->f90_type == BT_VOID
+   && ts2->u.derived->ts.is_iso_c
+   && ts2->u.derived->ts.u.derived->ts.f90_type == BT_VOID)
+  || (ts2->type == BT_INTEGER && ts1->type == BT_DERIVED
+	  && ts2->f90_type == BT_VOID
+	  && ts1->u.derived->ts.is_iso_c
+	  && ts1->u.derived->ts.u.derived->ts.f90_type == BT_VOID))
 return true;
 
   /* The _data component is not always present, therefore check for its
diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index e9f4d1c63e6..1fc9b0606dc 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,7 @@
+2023-10-20  Paul-Antoine Arras  
+
+	* gfortran.dg/c_ptr_tests_20.f90: New test.
+
 2023-09-20  Tobias Burnus  
 
 	Backported from master:
diff --git a/gcc/testsuite/gfortran.dg/c_ptr_tests_20.f90 b/gcc/testsuite/gfortran.dg/c_ptr_tests_20.f90
new file mode 100644
index 000..777181cece0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/c_ptr_tests_20.f90
@@ -0,0 +1,56 @@
+! { dg-do compile }
+!
+! This failed to compile the declare variant directive due to the C_PTR 
+! arguments to foo being recognised as INTEGER(8)
+
+program adjust_args
+  use iso_c_binding, only: c_loc
+  implicit none
+
+  integer, parameter :: N = 1024
+  real, allocatable, target :: av(:), bv(:), cv(:)
+
+  call foo(c_loc(bv), c_loc(av), N)
+
+  !$omp target data map(to: av(:N)) map(from: cv(:N))
+  !$omp parallel
+  call foo(c_loc(cv), c_loc(av), N)
+  !$omp end parallel
+  !$omp end target data
+
+contains
+  subroutine foo_variant(c_d_bv, c_d_av, n)
+use iso_c_binding, only: c_ptr, c_f_pointer
+type(c_ptr), intent(in) :: c_d_bv, c_d_av
+integer, intent(in) :: n
+real, pointer :: f_d_bv(:)
+real, pointer :: f_d_av(:)
+integer :: i
+  
+call c_f_pointer(c_d_bv, f_d_bv, [n])
+call c_f_pointer(c_d_av, f_d_av, [n])
+!$omp target teams loop is_device_ptr(f_d_bv, f_d_av)
+do i = 1, n
+

Re: [PATCH] Fortran: Fix incompatible types between INTEGER(8) and TYPE(c_ptr)

2023-10-26 Thread Paul-Antoine Arras

Hi Tobias,

Please see the updated patch attached incorporating your input and 
details below.


On 24/10/2023 18:12, you wrote:

On 20.10.23 16:02, Paul-Antoine Arras wrote:

gcc/fortran/ChangeLog:

  * interface.cc (gfc_compare_types): Return true in this situation.


That's a bad description. It makes sense when reading the commit log but 
if you

only read gcc/fortran/ChangeLog, 'this situation' is a dangling reference.


Updated Changelog with a more helpful description.


  gcc/fortran/ChangeLog.omp    |  5 ++
  gcc/testsuite/ChangeLog.omp  |  4 ++


On mainline, the ChangeLog not ChangeLog.omp is used. This changelog is 
automatically
filled by the data in the commit log. Thus, no need to include it in the 
patch.


Removed ChangeLog.omp from the patch.


See attached patch for a combined version, which checks now
whether from_intmod == INTMOD_ISO_C_BINDING and then compares
the names (to distinguish c_ptr and c_funptr). Those are unaffected
by 'use' renames, hence, we should be fine.


Added the proposed diff for interface.cc and misc.cc to the patch.


Additionally, I think it would be good to have a testcase which checks for
   c_funptr vs. c_ptr
mismatch.


Added new testcase c_ptr_tests_21.f90 to check that incompatibilities 
between c_funptr vs. c_ptr are properly reported.


Is this latest revision ready to commit?

Thanks,
--
PA
From 691d1050ce39c27231dc610b799bf180871820b8 Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Fri, 20 Oct 2023 12:42:49 +0200
Subject: [PATCH] Fortran: Fix incompatible types between INTEGER(8) and
 TYPE(c_ptr)

In the context of an OpenMP declare variant directive, arguments of type C_PTR
are sometimes recognised as C_PTR in the base function and as INTEGER(8) in the
variant - or the other way around, depending on the parsing order.
This patch prevents such situation from turning into a compile error.

2023-10-20  Paul-Antoine Arras  
	Tobias Burnus  

gcc/fortran/ChangeLog:

	* interface.cc (gfc_compare_types): Return true if one type is C_PTR
	and the other is a compatible INTEGER(8).
	* misc.cc (gfc_typename): Handle the case where an INTEGER(8) actually
	holds a TYPE(C_PTR).

gcc/testsuite/ChangeLog:

	* gfortran.dg/c_ptr_tests_20.f90: New test, checking that INTEGER(8)
	and TYPE(C_PTR) are recognised as compatible.
	* gfortran.dg/c_ptr_tests_21.f90: New test, exercising the error
	detection for C_FUNPTR.
---
 gcc/fortran/interface.cc | 16 --
 gcc/fortran/misc.cc  |  7 ++-
 gcc/testsuite/gfortran.dg/c_ptr_tests_20.f90 | 57 
 gcc/testsuite/gfortran.dg/c_ptr_tests_21.f90 | 57 
 4 files changed, 132 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/c_ptr_tests_20.f90
 create mode 100644 gcc/testsuite/gfortran.dg/c_ptr_tests_21.f90

diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index e9843e9549c..ed1613b16fb 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -707,10 +707,18 @@ gfc_compare_types (gfc_typespec *ts1, gfc_typespec *ts2)
  better way of doing this.  When ISO C binding is cleared up,
  this can probably be removed.  See PR 57048.  */
 
-  if (((ts1->type == BT_INTEGER && ts2->type == BT_DERIVED)
-   || (ts1->type == BT_DERIVED && ts2->type == BT_INTEGER))
-  && ts1->u.derived && ts2->u.derived
-  && ts1->u.derived == ts2->u.derived)
+  if ((ts1->type == BT_INTEGER
+   && ts2->type == BT_DERIVED
+   && ts1->f90_type == BT_VOID
+   && ts2->u.derived->from_intmod == INTMOD_ISO_C_BINDING
+   && ts1->u.derived
+   && strcmp (ts1->u.derived->name, ts2->u.derived->name) == 0)
+  || (ts2->type == BT_INTEGER
+	  && ts1->type == BT_DERIVED
+	  && ts2->f90_type == BT_VOID
+	  && ts1->u.derived->from_intmod == INTMOD_ISO_C_BINDING
+	  && ts2->u.derived
+	  && strcmp (ts1->u.derived->name, ts2->u.derived->name) == 0))
 return true;
 
   /* The _data component is not always present, therefore check for its
diff --git a/gcc/fortran/misc.cc b/gcc/fortran/misc.cc
index bae6d292dc5..edffba07013 100644
--- a/gcc/fortran/misc.cc
+++ b/gcc/fortran/misc.cc
@@ -138,7 +138,12 @@ gfc_typename (gfc_typespec *ts, bool for_hash)
   switch (ts->type)
 {
 case BT_INTEGER:
-  sprintf (buffer, "INTEGER(%d)", ts->kind);
+  if (ts->f90_type == BT_VOID
+	  && ts->u.derived
+	  && ts->u.derived->from_intmod == INTMOD_ISO_C_BINDING)
+	sprintf (buffer, "TYPE(%s)", ts->u.derived->name);
+  else
+	sprintf (buffer, "INTEGER(%d)", ts->kind);
   break;
 case BT_REAL:
   sprintf (buffer, "REAL(%d)", ts->ki

Re: [PATCH] Fortran: Fix incompatible types between INTEGER(8) and TYPE(c_ptr)

2023-10-26 Thread Paul-Antoine Arras

Hi Thomas,

On 26/10/2023 18:16, you wrote:

Hi!

On 2023-10-26T13:24:04+0200, Paul-Antoine Arras  wrote:

--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/c_ptr_tests_20.f90
@@ -0,0 +1,57 @@
+! { dg-do compile }
+! { dg-additional-options "-fopenmp" }
+[...]



--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/c_ptr_tests_21.f90
@@ -0,0 +1,57 @@
+! { dg-do compile }
+! { dg-additional-options "-fopenmp" }
+[...]


OpenMP is not universally supported across different GCC configurations,
so this will FAIL for some.  Therefore, please either guard with
effective target:

 @item fopenmp
 Target supports OpenMP via @option{-fopenmp}.



Would the following be enough?


diff --git gcc/testsuite/gfortran.dg/c_ptr_tests_20.f90 
gcc/testsuite/gfortran.dg/c_ptr_tests_20.f90
index 7dd510400f3..131603d3819 100644
--- gcc/testsuite/gfortran.dg/c_ptr_tests_20.f90
+++ gcc/testsuite/gfortran.dg/c_ptr_tests_20.f90
@@ -1,4 +1,5 @@
 ! { dg-do compile }
+! { dg-require-effective-target fopenmp }
 ! { dg-additional-options "-fopenmp" }
 !
 ! This failed to compile the declare variant directive due to the C_PTR 
diff --git gcc/testsuite/gfortran.dg/c_ptr_tests_21.f90 gcc/testsuite/gfortran.dg/c_ptr_tests_21.f90

index 05ccb771eee..060d29d0275 100644
--- gcc/testsuite/gfortran.dg/c_ptr_tests_21.f90
+++ gcc/testsuite/gfortran.dg/c_ptr_tests_21.f90
@@ -1,4 +1,5 @@
 ! { dg-do compile }
+! { dg-require-effective-target fopenmp }
 ! { dg-additional-options "-fopenmp" }
 !
 ! Ensure that C_PTR and C_FUNPTR are reported as incompatible types in variant 


Thanks,
--
PA



[PATCH] amdgcn: Add instruction patterns for conditional min/max operations

2023-03-01 Thread Paul-Antoine Arras

This patch introduces instruction patterns for conditional min and max
operations (cond_{f|s|u}{max|min}) in the GCN machine description. It 
also allows the exec register to be saved in SGPRs to avoid spilling to 
memory.

Tested on GCN3 Fiji gfx803.

OK for trunk?
--
PA
From 1cd86b4420d9d42bcde83d0ac52a03a07d4aa819 Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Wed, 1 Mar 2023 17:20:21 +0100
Subject: [PATCH] amdgcn: Add instruction patterns for conditional min/max
 operations

gcc/ChangeLog:

	* config/gcn/gcn-valu.md (3_exec): Add patterns for
	{s|u}{max|min} in QI, HI and DI modes.
	(3): Add pattern for {s|u}{max|min} in DI mode.
	(cond_): Add pattern for cond_f{max|min}.
	(cond_): Add pattern for cond_{s|u}{max|min}.
	* config/gcn/gcn.cc (gcn_spill_class): Allow the exec register to be
	saved in SGPRs.

gcc/testsuite/ChangeLog:

	* gcc.target/gcn/cond_fmaxnm_1.c: New test.
	* gcc.target/gcn/cond_fmaxnm_1_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_2.c: New test.
	* gcc.target/gcn/cond_fmaxnm_2_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_3.c: New test.
	* gcc.target/gcn/cond_fmaxnm_3_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_4.c: New test.
	* gcc.target/gcn/cond_fmaxnm_4_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_5.c: New test.
	* gcc.target/gcn/cond_fmaxnm_5_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_6.c: New test.
	* gcc.target/gcn/cond_fmaxnm_6_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_7.c: New test.
	* gcc.target/gcn/cond_fmaxnm_7_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_8.c: New test.
	* gcc.target/gcn/cond_fmaxnm_8_run.c: New test.
	* gcc.target/gcn/cond_fminnm_1.c: New test.
	* gcc.target/gcn/cond_fminnm_1_run.c: New test.
	* gcc.target/gcn/cond_fminnm_2.c: New test.
	* gcc.target/gcn/cond_fminnm_2_run.c: New test.
	* gcc.target/gcn/cond_fminnm_3.c: New test.
	* gcc.target/gcn/cond_fminnm_3_run.c: New test.
	* gcc.target/gcn/cond_fminnm_4.c: New test.
	* gcc.target/gcn/cond_fminnm_4_run.c: New test.
	* gcc.target/gcn/cond_fminnm_5.c: New test.
	* gcc.target/gcn/cond_fminnm_5_run.c: New test.
	* gcc.target/gcn/cond_fminnm_6.c: New test.
	* gcc.target/gcn/cond_fminnm_6_run.c: New test.
	* gcc.target/gcn/cond_fminnm_7.c: New test.
	* gcc.target/gcn/cond_fminnm_7_run.c: New test.
	* gcc.target/gcn/cond_fminnm_8.c: New test.
	* gcc.target/gcn/cond_fminnm_8_run.c: New test.
	* gcc.target/gcn/cond_smax_1.c: New test.
	* gcc.target/gcn/cond_smax_1_run.c: New test.
	* gcc.target/gcn/cond_smin_1.c: New test.
	* gcc.target/gcn/cond_smin_1_run.c: New test.
	* gcc.target/gcn/cond_umax_1.c: New test.
	* gcc.target/gcn/cond_umax_1_run.c: New test.
	* gcc.target/gcn/cond_umin_1.c: New test.
	* gcc.target/gcn/cond_umin_1_run.c: New test.
	* gcc.target/gcn/smax_1.c: New test.
	* gcc.target/gcn/smax_1_run.c: New test.
	* gcc.target/gcn/smin_1.c: New test.
	* gcc.target/gcn/smin_1_run.c: New test.
	* gcc.target/gcn/umax_1.c: New test.
	* gcc.target/gcn/umax_1_run.c: New test.
	* gcc.target/gcn/umin_1.c: New test.
	* gcc.target/gcn/umin_1_run.c: New test.
---
 gcc/config/gcn/gcn-valu.md| 134 +-
 gcc/config/gcn/gcn.cc |   2 +-
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_1.c  |  36 +
 .../gcc.target/gcn/cond_fmaxnm_1_run.c|  32 +
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_2.c  |  35 +
 .../gcc.target/gcn/cond_fmaxnm_2_run.c|  31 
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_3.c  |  37 +
 .../gcc.target/gcn/cond_fmaxnm_3_run.c|  32 +
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_4.c  |  37 +
 .../gcc.target/gcn/cond_fmaxnm_4_run.c|  32 +
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_5.c  |   9 ++
 .../gcc.target/gcn/cond_fmaxnm_5_run.c|   4 +
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_6.c  |   9 ++
 .../gcc.target/gcn/cond_fmaxnm_6_run.c|   4 +
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_7.c  |   9 ++
 .../gcc.target/gcn/cond_fmaxnm_7_run.c|   4 +
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_8.c  |   9 ++
 .../gcc.target/gcn/cond_fmaxnm_8_run.c|   4 +
 gcc/testsuite/gcc.target/gcn/cond_fminnm_1.c  |  10 ++
 .../gcc.target/gcn/cond_fminnm_1_run.c|   5 +
 gcc/testsuite/gcc.target/gcn/cond_fminnm_2.c  |  10 ++
 .../gcc.target/gcn/cond_fminnm_2_run.c|   5 +
 gcc/testsuite/gcc.target/gcn/cond_fminnm_3.c  |  12 ++
 .../gcc.target/gcn/cond_fminnm_3_run.c|   5 +
 gcc/testsuite/gcc.target/gcn/cond_fminnm_4.c  |  12 ++
 .../gcc.target/gcn/cond_fminnm_4_run.c|   5 +
 gcc/testsuite/gcc.target/gcn/cond_fminnm_5.c  |  10 ++
 .../gcc.target/gcn/cond_fminnm_5_run.c|   4 +
 gcc/testsuite/gcc.target/gcn/cond_fminnm_6.c  |  10 ++
 .../gcc.target/gcn/cond_fminnm_6_run.c|   4 +
 gcc/testsuite/gcc.target/gcn/cond_fminnm_7.c  |  10 ++
 .../gcc.target/gcn/cond_fminnm_7_run.c|   4 +
 gcc/testsuite/gcc.target/gcn/cond_fminnm_8.c  |  10 ++
 .../gcc.target/gcn/cond_fminnm_8_run.c|   4 +
 gcc/testsuite

Re: [PATCH] amdgcn: Add instruction patterns for conditional min/max operations

2023-03-03 Thread Paul-Antoine Arras

Le 02/03/2023 à 18:18, Andrew Stubbs a écrit :

On 01/03/2023 16:56, Paul-Antoine Arras wrote:

This patch introduces instruction patterns for conditional min and max
operations (cond_{f|s|u}{max|min}) in the GCN machine description. It 
also allows the exec register to be saved in SGPRs to avoid spilling 
to memory.

Tested on GCN3 Fiji gfx803.

OK for trunk?


Not quite yet, but it's only a few cosmetic issues, I think.


+(define_insn_and_split "3"
+  [(set (match_operand:V_DI 0 "register_operand"  "=  v")
+    (minmaxop:V_DI
+  (match_operand:V_DI 1 "gcn_alu_operand" "%  v")
+  (match_operand:V_DI 2 "gcn_alu_operand" "   v")))
+    (clobber (reg:DI VCC_REG))]


No need to make it commutative when the two operands have the same 
constraints. There's a few more instances of this later.



+    if ( == smin ||  == smax)
+  emit_insn (gen_vec_cmpdi (vcc, minp ? gen_rtx_LT 
(VOIDmode, 0, 0) :
+    gen_rtx_GT (VOIDmode, 0, 0), 
operands[1], operands[2]));

+    else
+  emit_insn (gen_vec_cmpdi (vcc, minp ? gen_rtx_LTU 
(VOIDmode, 0, 0) :
+    gen_rtx_GTU (VOIDmode, 0, 0), 
operands[1], operands[2]));

+


Long lines need to be wrapped, here and elsewhere.


The amended patch attached should fix those issues. Let me know if it 
looks good to you.

--
PA
From cdb2d170091d87b0a5968cca49fc34ac434bb54c Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Wed, 1 Mar 2023 17:20:21 +0100
Subject: [PATCH] amdgcn: Add instruction patterns for conditional min/max
 operations

gcc/ChangeLog:

	* config/gcn/gcn-valu.md (3_exec): Add patterns for
	{s|u}{max|min} in QI, HI and DI modes.
	(3): Add pattern for {s|u}{max|min} in DI mode.
	(cond_): Add pattern for cond_f{max|min}.
	(cond_): Add pattern for cond_{s|u}{max|min}.
	* config/gcn/gcn.cc (gcn_spill_class): Allow the exec register to be
	saved in SGPRs.

gcc/testsuite/ChangeLog:

	* gcc.target/gcn/cond_fmaxnm_1.c: New test.
	* gcc.target/gcn/cond_fmaxnm_1_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_2.c: New test.
	* gcc.target/gcn/cond_fmaxnm_2_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_3.c: New test.
	* gcc.target/gcn/cond_fmaxnm_3_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_4.c: New test.
	* gcc.target/gcn/cond_fmaxnm_4_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_5.c: New test.
	* gcc.target/gcn/cond_fmaxnm_5_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_6.c: New test.
	* gcc.target/gcn/cond_fmaxnm_6_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_7.c: New test.
	* gcc.target/gcn/cond_fmaxnm_7_run.c: New test.
	* gcc.target/gcn/cond_fmaxnm_8.c: New test.
	* gcc.target/gcn/cond_fmaxnm_8_run.c: New test.
	* gcc.target/gcn/cond_fminnm_1.c: New test.
	* gcc.target/gcn/cond_fminnm_1_run.c: New test.
	* gcc.target/gcn/cond_fminnm_2.c: New test.
	* gcc.target/gcn/cond_fminnm_2_run.c: New test.
	* gcc.target/gcn/cond_fminnm_3.c: New test.
	* gcc.target/gcn/cond_fminnm_3_run.c: New test.
	* gcc.target/gcn/cond_fminnm_4.c: New test.
	* gcc.target/gcn/cond_fminnm_4_run.c: New test.
	* gcc.target/gcn/cond_fminnm_5.c: New test.
	* gcc.target/gcn/cond_fminnm_5_run.c: New test.
	* gcc.target/gcn/cond_fminnm_6.c: New test.
	* gcc.target/gcn/cond_fminnm_6_run.c: New test.
	* gcc.target/gcn/cond_fminnm_7.c: New test.
	* gcc.target/gcn/cond_fminnm_7_run.c: New test.
	* gcc.target/gcn/cond_fminnm_8.c: New test.
	* gcc.target/gcn/cond_fminnm_8_run.c: New test.
	* gcc.target/gcn/cond_smax_1.c: New test.
	* gcc.target/gcn/cond_smax_1_run.c: New test.
	* gcc.target/gcn/cond_smin_1.c: New test.
	* gcc.target/gcn/cond_smin_1_run.c: New test.
	* gcc.target/gcn/cond_umax_1.c: New test.
	* gcc.target/gcn/cond_umax_1_run.c: New test.
	* gcc.target/gcn/cond_umin_1.c: New test.
	* gcc.target/gcn/cond_umin_1_run.c: New test.
	* gcc.target/gcn/smax_1.c: New test.
	* gcc.target/gcn/smax_1_run.c: New test.
	* gcc.target/gcn/smin_1.c: New test.
	* gcc.target/gcn/smin_1_run.c: New test.
	* gcc.target/gcn/umax_1.c: New test.
	* gcc.target/gcn/umax_1_run.c: New test.
	* gcc.target/gcn/umin_1.c: New test.
	* gcc.target/gcn/umin_1_run.c: New test.
---
 gcc/config/gcn/gcn-valu.md| 137 +-
 gcc/config/gcn/gcn.cc |   2 +-
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_1.c  |  33 +
 .../gcc.target/gcn/cond_fmaxnm_1_run.c|  32 
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_2.c  |  33 +
 .../gcc.target/gcn/cond_fmaxnm_2_run.c|  31 
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_3.c  |  35 +
 .../gcc.target/gcn/cond_fmaxnm_3_run.c|  32 
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_4.c  |  35 +
 .../gcc.target/gcn/cond_fmaxnm_4_run.c|  32 
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_5.c  |   9 ++
 .../gcc.target/gcn/cond_fmaxnm_5_run.c|   4 +
 gcc/testsuite/gcc.target/gcn/cond_fmaxnm_6.c  |   9 ++
 ...

[OG12][PATCH] OpenMP: Fix ICE with OMP metadirectives

2022-09-21 Thread Paul-Antoine Arras

Hello,

Here is a patch that fixes an ICE in gfortran triggered by an invalid 
end statement at the end of an OMP metadirective:


```
!$OMP metadirective ...
...
!$OMP end ...
```

Does this fix look correct?

Thanks,
--
Paul-Antoine ArrasFrom 73ecbc2672a5352a08260f7a9d0de6d2c29ea2b6 Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Wed, 21 Sep 2022 15:52:56 +
Subject: [PATCH] OpenMP: Fix ICE with OMP metadirectives

Problem: ending an OpenMP metadirective block with an OMP end statement
results in an internal compiler error.
Solution: reject invalid end statements and issue a proper diagnostic.

Also add a new test to check this behaviour.

gcc/fortran/ChangeLog:

* parse.cc (parse_omp_metadirective_body): Reject OMP end statements
at the end of an OMP metadirective.

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/metadirective-9.f90: New test.
---
 gcc/fortran/ChangeLog.omp |  5 
 gcc/fortran/parse.cc  | 14 +
 gcc/testsuite/ChangeLog.omp   |  4 +++
 .../gfortran.dg/gomp/metadirective-9.f90  | 29 +++
 4 files changed, 52 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/metadirective-9.f90

diff --git gcc/fortran/ChangeLog.omp gcc/fortran/ChangeLog.omp
index 8c89cd5bd43..7b253608bf8 100644
--- gcc/fortran/ChangeLog.omp
+++ gcc/fortran/ChangeLog.omp
@@ -1,3 +1,8 @@
+2022-09-21  Paul-Antoine Arras  
+
+* parse.cc (parse_omp_metadirective_body): Reject OMP end statements
+at the end of an OMP metadirective.
+
 2022-09-09  Tobias Burnus  
 
Backport from mainline:
diff --git gcc/fortran/parse.cc gcc/fortran/parse.cc
index b35d76a4f6b..1f1fa0eba0e 100644
--- gcc/fortran/parse.cc
+++ gcc/fortran/parse.cc
@@ -5863,6 +5863,20 @@ parse_omp_metadirective_body (gfc_statement omp_st)
  break;
}
 
+  if (gfc_state_stack->state == COMP_OMP_METADIRECTIVE
+ && startswith (gfc_ascii_statement (st), "!$OMP END "))
+   {
+ for (gfc_state_data *p = gfc_state_stack; p; p = p->previous)
+   if (p->state == COMP_OMP_STRUCTURED_BLOCK)
+ goto finish;
+ gfc_error (
+   "Unexpected %s statement in an OMP METADIRECTIVE block at %C",
+   gfc_ascii_statement (st));
+ reject_statement ();
+ st = next_statement ();
+   }
+finish:
+
   gfc_in_metadirective_body = old_in_metadirective_body;
 
   if (gfc_state_stack->head)
diff --git gcc/testsuite/ChangeLog.omp gcc/testsuite/ChangeLog.omp
index e0c8c138620..f075354af4d 100644
--- gcc/testsuite/ChangeLog.omp
+++ gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,7 @@
+2022-09-21  Paul-Antoine Arras  
+
+* gfortran.dg/gomp/metadirective-9.f90: New test.
+
 2022-09-09  Paul-Antoine Arras  
 
Backport from mainline:
diff --git gcc/testsuite/gfortran.dg/gomp/metadirective-9.f90 
gcc/testsuite/gfortran.dg/gomp/metadirective-9.f90
new file mode 100644
index 000..4db37dd0ef9
--- /dev/null
+++ gcc/testsuite/gfortran.dg/gomp/metadirective-9.f90
@@ -0,0 +1,29 @@
+! { dg-do compile }
+
+program OpenMP_Metadirective_WrongEnd_Test
+
+  integer :: &
+iV, jV, kV
+  integer, dimension ( 3 ) :: &
+lV, uV
+  logical :: &
+UseDevice
+
+!$OMP metadirective &
+!$OMP   when ( user = { condition ( UseDevice ) } &
+!$OMP : target teams distribute parallel do simd collapse ( 3 ) &
+!$OMP private ( iaVS ) ) &
+!$OMP   default ( parallel do simd collapse ( 3 ) private ( iaVS ) )
+do kV = lV ( 3 ), uV ( 3 )
+  do jV = lV ( 2 ), uV ( 2 )
+do iV = lV ( 1 ), uV ( 1 )
+
+
+end do
+  end do
+end do
+!$OMP end target teams distribute parallel do simd ! { dg-error 
"Unexpected !.OMP END TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD statement in an 
OMP METADIRECTIVE block at .1." }
+
+
+end program
+
-- 
2.31.1



[committed] MAINTAINERS: Add myself to Write After Approval

2022-09-23 Thread Paul-Antoine Arras

Hello,

I just added myself to the Write After Approval section of MAINTAINERS file.
--
PAFrom d10308ff618e036d6c3d1a8c491ca4755b257612 Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Fri, 23 Sep 2022 10:21:48 +
Subject: [PATCH] MAINTAINERS: Add myself to Write After Approval

ChangeLog:

* MAINTAINERS (Write After Approval): Add myself.
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git MAINTAINERS MAINTAINERS
index be146855ed8..f63de226609 100644
--- MAINTAINERS
+++ MAINTAINERS
@@ -316,6 +316,7 @@ from other maintainers or reviewers.
 
 Mark G. Adams  
 Pedro Alves
+Paul-Antoine Arras 
 Raksit Ashok   
 Matt Austern   
 David Ayers
-- 
2.31.1



Re: [OG12][PATCH] OpenMP: Fix ICE with OMP metadirectives

2022-09-28 Thread Paul-Antoine Arras

Hi Tobias,

Thanks for your review.

Here is a revised patch resulting from your comments.

The only issue that I could not easily fix is the following code 
triggering an ICE:


```
   !$OMP begin metadirective &
   !$OMP   when ( user = { condition ( UseDevice ) } &
   !$OMP : nothing ) &
   !$OMP   default ( parallel )
   block
  call foo()
   end block
   call bar()   <--- ICE
   !$omp end metadirective
```

I filed a PR on Bugzilla: 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107067


Is it OK for you?
--
PAFrom 03476214bda71c6581b7978cf9fd5b701896a052 Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Wed, 21 Sep 2022 15:52:56 +
Subject: [PATCH] OpenMP: Fix ICE with OMP metadirectives

Problem: ending an OpenMP metadirective block with an OMP end statement
results in an internal compiler error.
Solution: reject invalid end statements and issue a proper diagnostic.

This revision also fixes a couple of minor metadirective issues and adds
related test cases.

gcc/fortran/ChangeLog:

* parse.cc (gfc_ascii_statement): Missing $ in !$OMP END METADIRECTIVE.
(parse_omp_structured_block): Fix handling of OMP end metadirective.
(parse_omp_metadirective_body): Reject OMP end statements
at the end of an OMP metadirective.

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/metadirective-1.f90: Match !$OMP END METADIRECTIVE.
* gfortran.dg/gomp/metadirective-10.f90: New test.
* gfortran.dg/gomp/metadirective-11.f90: New xfail test.
* gfortran.dg/gomp/metadirective-9.f90: New test.
---
 gcc/fortran/ChangeLog.omp |  7 
 gcc/fortran/parse.cc  | 32 ++-
 gcc/testsuite/ChangeLog.omp   |  7 
 .../gfortran.dg/gomp/metadirective-1.f90  |  2 +-
 .../gfortran.dg/gomp/metadirective-10.f90 | 40 +++
 .../gfortran.dg/gomp/metadirective-11.f90 | 33 +++
 .../gfortran.dg/gomp/metadirective-9.f90  | 30 ++
 7 files changed, 141 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/metadirective-10.f90
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/metadirective-11.f90
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/metadirective-9.f90

diff --git gcc/fortran/ChangeLog.omp gcc/fortran/ChangeLog.omp
index 8c89cd5bd43..14f897e8fec 100644
--- gcc/fortran/ChangeLog.omp
+++ gcc/fortran/ChangeLog.omp
@@ -1,3 +1,10 @@
+2022-09-21  Paul-Antoine Arras  
+
+   * parse.cc (gfc_ascii_statement): Missing $ in !$OMP END METADIRECTIVE.
+   (parse_omp_structured_block): Fix handling of OMP end metadirective.
+   (parse_omp_metadirective_body): Reject OMP end statements
+   at the end of an OMP metadirective.
+
 2022-09-09  Tobias Burnus  
 
Backport from mainline:
diff --git gcc/fortran/parse.cc gcc/fortran/parse.cc
index b35d76a4f6b..fc88111a7ad 100644
--- gcc/fortran/parse.cc
+++ gcc/fortran/parse.cc
@@ -2517,7 +2517,7 @@ gfc_ascii_statement (gfc_statement st)
   p = "!$OMP END MASTER TASKLOOP SIMD";
   break;
 case ST_OMP_END_METADIRECTIVE:
-  p = "!OMP END METADIRECTIVE";
+  p = "!$OMP END METADIRECTIVE";
   break;
 case ST_OMP_END_ORDERED:
   p = "!$OMP END ORDERED";
@@ -5643,9 +5643,15 @@ parse_omp_structured_block (gfc_statement omp_st, bool 
workshare_stmts_only)
   np->block = NULL;
 
   omp_end_st = gfc_omp_end_stmt (omp_st, false, true);
-  if (omp_st == ST_NONE)
+  if (omp_end_st == ST_NONE)
 gcc_unreachable ();
 
+  /* If handling a metadirective variant, treat 'omp end metadirective'
+ as the expected end statement for the current construct.  */
+  if (gfc_state_stack->previous != NULL
+  && gfc_state_stack->previous->state == COMP_OMP_BEGIN_METADIRECTIVE)
+omp_end_st = ST_OMP_END_METADIRECTIVE;
+
   bool block_construct = false;
   gfc_namespace *my_ns = NULL;
   gfc_namespace *my_parent = NULL;
@@ -5744,13 +5750,6 @@ parse_omp_structured_block (gfc_statement omp_st, bool 
workshare_stmts_only)
   else
st = parse_executable (st);
 
-  /* If handling a metadirective variant, treat 'omp end metadirective'
-as the expected end statement for the current construct.  */
-  if (st == ST_OMP_END_METADIRECTIVE
- && gfc_state_stack->previous != NULL
- && gfc_state_stack->previous->state == COMP_OMP_BEGIN_METADIRECTIVE)
-   st = omp_end_st;
-
   if (st == ST_NONE)
unexpected_eof ();
   else if (st == ST_OMP_SECTION
@@ -5863,6 +5862,21 @@ parse_omp_metadirective_body (gfc_statement omp_st)
  break;
}
 
+  if (gfc_state_stack->state == COMP_OMP_METADIRECTIVE
+ && startswith (gfc_ascii_statement (st), "!$OMP END "))
+   {
+ for (gfc_state_data *p = gfc_state_stack; p; p = p->previo

[OG12][PATCH] openmp: Fix handling of target constructs in static member

2022-09-13 Thread Paul-Antoine Arras

Hello,

This patch intends to backport e90af965e5c by Jakub Jelinek to 
devel/omp/gcc-12.
The original patch was described here: 
https://gcc.gnu.org/pipermail/gcc-patches/2022-September/601189.html


Thanks,
--
Paul-Antoine ArrasFrom c1fb6ff897d0b929807d52cf52d4894e252e7d96 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek 
Date: Wed, 7 Sep 2022 08:54:13 +0200
Subject: [PATCH] openmp: Fix handling of target constructs in static member
 functions [PR106829]

Just calling current_nonlambda_class_type in static member functions returns
non-NULL, but something that isn't *this and if unlucky can match part of the
IL and can be added to target clauses.
  if (DECL_NONSTATIC_MEMBER_P (decl)
  && current_class_ptr)
is a guard used elsewhere (in check_accessibility_of_qualified_id).

2022-09-07  Jakub Jelinek  

PR c++/106829
* semantics.cc (finish_omp_target_clauses): If current_function_decl
isn't a nonstatic member function, don't set data.current_object to
non-NULL.

* g++.dg/gomp/pr106829.C: New test.

(cherry picked from commit e90af965e5c858ba02c0cdfbac35d0a19da1c2f6)
---
 gcc/cp/ChangeLog.omp | 10 ++
 gcc/cp/semantics.cc  | 17 -
 gcc/testsuite/ChangeLog.omp  |  8 
 gcc/testsuite/g++.dg/gomp/pr106829.C | 15 +++
 4 files changed, 41 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/gomp/pr106829.C

diff --git gcc/cp/ChangeLog.omp gcc/cp/ChangeLog.omp
index 35504f4c92b..c3214f31252 100644
--- gcc/cp/ChangeLog.omp
+++ gcc/cp/ChangeLog.omp
@@ -1,3 +1,13 @@
+2022-09-09  Paul-Antoine Arras  
+
+   Backport from mainline:
+   2022-09-07  Jakub Jelinek  
+
+   PR c++/106829
+   * semantics.cc (finish_omp_target_clauses): If current_function_decl
+   isn't a nonstatic member function, don't set data.current_object to
+   non-NULL.
+
 2022-09-07  Tobias Burnus  
 
Backport from mainline:
diff --git gcc/cp/semantics.cc gcc/cp/semantics.cc
index 7717a820f0d..dad04dc4757 100644
--- gcc/cp/semantics.cc
+++ gcc/cp/semantics.cc
@@ -9727,16 +9727,15 @@ finish_omp_target_clauses (location_t loc, tree body, 
tree *clauses_ptr)
 {
   omp_target_walk_data data;
   data.this_expr_accessed = false;
+  data.current_object = NULL_TREE;
 
-  tree ct = current_nonlambda_class_type ();
-  if (ct)
-{
-  tree object = maybe_dummy_object (ct, NULL);
-  object = maybe_resolve_dummy (object, true);
-  data.current_object = object;
-}
-  else
-data.current_object = NULL_TREE;
+  if (DECL_NONSTATIC_MEMBER_P (current_function_decl) && current_class_ptr)
+if (tree ct = current_nonlambda_class_type ())
+  {
+   tree object = maybe_dummy_object (ct, NULL);
+   object = maybe_resolve_dummy (object, true);
+   data.current_object = object;
+  }
 
   if (DECL_LAMBDA_FUNCTION_P (current_function_decl))
 {
diff --git gcc/testsuite/ChangeLog.omp gcc/testsuite/ChangeLog.omp
index ed42b20b099..9ca4d936ff5 100644
--- gcc/testsuite/ChangeLog.omp
+++ gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,11 @@
+2022-09-09  Paul-Antoine Arras  
+
+   Backport from mainline:
+   2022-09-07  Jakub Jelinek  
+
+   PR c++/106829
+   * g++.dg/gomp/pr106829.C: New test.
+
 2022-09-07  Tobias Burnus  
 
Backport from mainline:
diff --git gcc/testsuite/g++.dg/gomp/pr106829.C 
gcc/testsuite/g++.dg/gomp/pr106829.C
new file mode 100644
index 000..0295efb88ee
--- /dev/null
+++ gcc/testsuite/g++.dg/gomp/pr106829.C
@@ -0,0 +1,15 @@
+// PR c++/106829
+
+namespace std
+{
+  template  class complex;
+  template <> struct complex { complex (double); _Complex double d; };
+}
+struct S { void static foo (); };
+
+void
+S::foo ()
+{
+#pragma omp target
+  std::complex c = 0.0;
+}
-- 
2.31.1



[wwwdocs, committed] git: Move current devel/omp/gcc branch to 14

2024-06-28 Thread Paul-Antoine Arras

Committed as debf3885965604c81541a549d531ec450f498058
https://gcc.gnu.org/git.html#general
--
PAcommit debf3885965604c81541a549d531ec450f498058
Author: Paul-Antoine Arras 
Date:   Fri Jun 28 12:08:57 2024 +0200

git: Move current devel/omp/gcc branch to 14

diff --git htdocs/git.html htdocs/git.html
index a6e88566..b5c2737a 100644
--- htdocs/git.html
+++ htdocs/git.html
@@ -280,17 +280,17 @@ in Git.
   Makarov vmaka...@redhat.com.
   
 
-  https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;a=shortlog;h=refs/heads/devel/omp/gcc-13";>devel/omp/gcc-13
+  https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;a=shortlog;h=refs/heads/devel/omp/gcc-14";>devel/omp/gcc-14
   This branch is for collaborative development of
   https://gcc.gnu.org/wiki/OpenACC";>OpenACC and
   https://gcc.gnu.org/wiki/openmp";>OpenMP support and related
   functionality, such
   as https://gcc.gnu.org/wiki/Offloading";>offloading support (OMP:
   offloading and multi processing).
-  The branch is based on releases/gcc-13.
-  Please send patch emails with a short-hand [og13] tag in the
+  The branch is based on releases/gcc-14.
+  Please send patch emails with a short-hand [og14] tag in the
   subject line, and use ChangeLog.omp files. (Likewise but now
-  stale branches exists for the prior GCC releases 9 to 12.)
+  stale branches exists for the prior GCC releases 9 to 13.)
 
   unified-autovect
   This branch is for work on improving effectiveness and generality of GCC's
@@ -897,14 +897,15 @@ merged.
   https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;a=shortlog;h=refs/heads/devel/omp/gcc-9";>devel/omp/gcc-9
   https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;a=shortlog;h=refs/heads/devel/omp/gcc-10";>devel/omp/gcc-10
   https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;a=shortlog;h=refs/heads/devel/omp/gcc-11";>devel/omp/gcc-11
+  https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;a=shortlog;h=refs/heads/devel/omp/gcc-12";>devel/omp/gcc-12
+  https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;a=shortlog;h=refs/heads/devel/omp/gcc-13";>devel/omp/gcc-13
   These branches were used for collaborative development of
   https://gcc.gnu.org/wiki/OpenACC";>OpenACC and
   https://gcc.gnu.org/wiki/openmp";>OpenMP support and related
   functionality as the successors to openacc-gcc-9-branch after the move to
   Git.
-  The branches were based on releases/gcc-9, releases/gcc-10 and
-  releases/gcc-11 respectively.
-  Development has now moved to the devel/omp/gcc-12 branch.
+  The branches were based on releases/gcc-9, releases/gcc-10, etc.
+  Development has now moved to the devel/omp/gcc-14 branch.
 
   hammer-3_3-branch
   The goal of this branch was to have a stable compiler based on GCC 3.3


[PATCH v2 1/8] Fix warnings for tree formats in gfc_error

2024-07-12 Thread Paul-Antoine Arras
This enables proper warnings for formats like %qD.

gcc/c-family/ChangeLog:

* c-format.cc (gcc_gfc_char_table): Add formats for tree objects.
---
 gcc/c-family/c-format.cc | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/c-family/c-format.cc b/gcc/c-family/c-format.cc
index 5bfd2fc4469..f4163c9cbc0 100644
--- a/gcc/c-family/c-format.cc
+++ b/gcc/c-family/c-format.cc
@@ -847,6 +847,10 @@ static const format_char_info gcc_gfc_char_table[] =
   /* This will require a "locus" at runtime.  */
   { "L",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN  }, "", "R", NULL },
 
+  /* These will require a "tree" at runtime.  */
+  { "DFTV", 1, STD_C89, { T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN, 
 BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "'",   NULL },
+  { "E",   1, STD_C89, { T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  
BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "",   NULL },
+
   /* These will require nothing.  */
   { "<>",0, STD_C89, NOARGUMENTS, "",  "",   NULL },
   { NULL,  0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
-- 
2.45.2



[PATCH v2 6/8] OpenMP: common C/C++ testcases for dispatch + adjust_args

2024-07-12 Thread Paul-Antoine Arras
gcc/testsuite/ChangeLog:

* c-c++-common/gomp/declare-variant-2.c: Adjust dg-error directives.
* c-c++-common/gomp/adjust-args-1.c: New test.
* c-c++-common/gomp/adjust-args-2.c: New test.
* c-c++-common/gomp/dispatch-1.c: New test.
* c-c++-common/gomp/dispatch-2.c: New test.
* c-c++-common/gomp/dispatch-3.c: New test.
* c-c++-common/gomp/dispatch-4.c: New test.
* c-c++-common/gomp/dispatch-5.c: New test.
* c-c++-common/gomp/dispatch-6.c: New test.
* c-c++-common/gomp/dispatch-7.c: New test.
---
 .../c-c++-common/gomp/adjust-args-1.c | 30 +
 .../c-c++-common/gomp/adjust-args-2.c | 31 +
 .../c-c++-common/gomp/declare-variant-2.c |  4 +-
 gcc/testsuite/c-c++-common/gomp/dispatch-1.c  | 65 +++
 gcc/testsuite/c-c++-common/gomp/dispatch-2.c  | 28 
 gcc/testsuite/c-c++-common/gomp/dispatch-3.c  | 15 +
 gcc/testsuite/c-c++-common/gomp/dispatch-4.c  | 18 +
 gcc/testsuite/c-c++-common/gomp/dispatch-5.c  | 26 
 gcc/testsuite/c-c++-common/gomp/dispatch-6.c  | 19 ++
 gcc/testsuite/c-c++-common/gomp/dispatch-7.c  | 28 
 10 files changed, 262 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-1.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-2.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-3.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-4.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-5.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-6.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-7.c

diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c 
b/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
new file mode 100644
index 000..728abe62092
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b) adjust_args (need_device_ptr: c)
+int f1 (int a, void *b, float c[2]);
+
+int test () {
+  int a;
+  void *b;
+  float c[2];
+  struct {int a;} s;
+
+  s.a = f0 (a, b, c);
+  #pragma omp dispatch
+  s.a = f0 (a, b, c);
+
+  f1 (a, b, c);
+  #pragma omp dispatch
+  s.a = f1 (a, b, c);
+
+  return s.a;
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device 
\\(\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c 
b/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
new file mode 100644
index 000..e36d93a01d9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) adjust_args (need_device_ptr: b, c) match 
(construct={dispatch}) adjust_args (nothing: a) 
+int f1 (int a, void *b, float c[2]);
+
+void test () {
+  int a;
+  void *b;
+  float c[2];
+
+  #pragma omp dispatch
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (-4852)
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (a + a)
+  f0 (a, b, c);
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device 
\\(\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, -4852\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, -4852\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch device\\(-4852\\)" 
1 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c 
b/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c
index 05e485ef6a8..50d9b2dcf4b 100644
--- a/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c
+++ b/gcc/testsuite/c-c++-common/gomp/declare-variant

[PATCH v2 0/8] OpenMP: dispatch + adjust_args support

2024-07-12 Thread Paul-Antoine Arras
This is a respin of my patchset implementing both the `dispatch` construct and 
the `adjust_args` clause to the `declare variant` directive. The original
submission can be found there: 
https://gcc.gnu.org/pipermail/gcc-patches/2024-May/652819.html.

Beside being rebased, this new iteration has the following changes:
 * Add a commit to fix an incorrect warning with `gfc_error`;
 * Add a testcase (xfailed due to PR/115271) to ensure that `adjust_args` works
 across TUs in Fortran;
 * Rule out `c_funptr` for `need_device_ptr`;
 * Fix some warnings turned into errors during bootstrapping.
 

Paul-Antoine Arras (8):
  Fix warnings for tree formats in gfc_error
  OpenMP: dispatch + adjust_args tree data structures and front-end
interfaces
  OpenMP: middle-end support for dispatch + adjust_args
  OpenMP: C front-end support for dispatch + adjust_args
  OpenMP: C++ front-end support for dispatch + adjust_args
  OpenMP: common C/C++ testcases for dispatch + adjust_args
  OpenMP: Fortran front-end support for dispatch + adjust_args
  OpenMP: update documentation for dispatch and adjust_args

 gcc/builtin-types.def |   1 +
 gcc/c-family/c-attribs.cc |   2 +
 gcc/c-family/c-format.cc  |   4 +
 gcc/c-family/c-omp.cc |   4 +-
 gcc/c-family/c-pragma.cc  |   1 +
 gcc/c-family/c-pragma.h   |   3 +
 gcc/c/c-parser.cc | 496 --
 gcc/c/c-typeck.cc |   2 +
 gcc/cp/decl.cc|  33 +
 gcc/cp/parser.cc  | 612 --
 gcc/cp/pt.cc  |   3 +
 gcc/cp/semantics.cc   |  20 +
 gcc/fortran/dump-parse-tree.cc|  17 +
 gcc/fortran/frontend-passes.cc|   2 +
 gcc/fortran/gfortran.h|  11 +-
 gcc/fortran/match.h   |   1 +
 gcc/fortran/openmp.cc | 201 +-
 gcc/fortran/parse.cc  |  39 +-
 gcc/fortran/resolve.cc|   2 +
 gcc/fortran/st.cc |   1 +
 gcc/fortran/trans-decl.cc |   9 +-
 gcc/fortran/trans-openmp.cc   | 161 +
 gcc/fortran/trans.cc  |   1 +
 gcc/fortran/types.def |   1 +
 gcc/gimple-low.cc |   1 +
 gcc/gimple-pretty-print.cc|  33 +
 gcc/gimple-walk.cc|   1 +
 gcc/gimple.cc |  20 +
 gcc/gimple.def|   5 +
 gcc/gimple.h  |  33 +-
 gcc/gimplify.cc   | 412 +++-
 gcc/gimplify.h|   2 +
 gcc/omp-builtins.def  |   6 +
 gcc/omp-expand.cc |  18 +
 gcc/omp-general.cc|  16 +-
 gcc/omp-low.cc|  35 +
 gcc/omp-selectors.h   |   3 +
 .../c-c++-common/gomp/adjust-args-1.c |  30 +
 .../c-c++-common/gomp/adjust-args-2.c |  31 +
 .../c-c++-common/gomp/declare-variant-2.c |   4 +-
 gcc/testsuite/c-c++-common/gomp/dispatch-1.c  |  65 ++
 gcc/testsuite/c-c++-common/gomp/dispatch-2.c  |  28 +
 gcc/testsuite/c-c++-common/gomp/dispatch-3.c  |  15 +
 gcc/testsuite/c-c++-common/gomp/dispatch-4.c  |  18 +
 gcc/testsuite/c-c++-common/gomp/dispatch-5.c  |  26 +
 gcc/testsuite/c-c++-common/gomp/dispatch-6.c  |  19 +
 gcc/testsuite/c-c++-common/gomp/dispatch-7.c  |  28 +
 gcc/testsuite/g++.dg/gomp/adjust-args-1.C |  39 ++
 gcc/testsuite/g++.dg/gomp/adjust-args-2.C |  51 ++
 gcc/testsuite/g++.dg/gomp/dispatch-1.C|  53 ++
 gcc/testsuite/g++.dg/gomp/dispatch-2.C|  62 ++
 gcc/testsuite/gcc.dg/gomp/adjust-args-1.c |  32 +
 gcc/testsuite/gcc.dg/gomp/dispatch-1.c|  53 ++
 .../gfortran.dg/gomp/adjust-args-1.f90|  63 ++
 .../gfortran.dg/gomp/adjust-args-2.f90|  18 +
 .../gfortran.dg/gomp/adjust-args-3.f90|  26 +
 .../gfortran.dg/gomp/adjust-args-4.f90|  58 ++
 .../gfortran.dg/gomp/adjust-args-5.f90|  58 ++
 .../gfortran.dg/gomp/declare-variant-2.f90|   6 +-
 .../gomp/declare-variant-21-aux.f90   |  18 +
 .../gfortran.dg/gomp/declare-variant-21.f90   |  28 +
 gcc/testsuite/gfortran.dg/gomp/dispatch-1.f90 |  77 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-2.f90 |  79 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-3.f90 |  39 ++
 gcc/testsuite/gfortran.dg/gomp/dispatch-4.f90 |  19 +
 gcc/testsuite/gfortran.dg/gomp/dispatch-5.f90 |  24 +
 gcc/testsuite/gfortran.dg/gomp/dispatch-6.f90 |  38 ++
 gcc/testsuite/gfortran.dg/gomp/dispatch-7.f90 |  27 +
 gcc/testsuite/gfortran.dg/gomp/dispatch-8.f90 |  39 ++
 gcc/tree-core.h

[PATCH v2 3/8] OpenMP: middle-end support for dispatch + adjust_args

2024-07-12 Thread Paul-Antoine Arras
This patch adds middle-end support for the `dispatch` construct and the
`adjust_args` clause. The heavy lifting is done in `gimplify_omp_dispatch` and
`gimplify_call_expr` respectively. For `adjust_args`, this mostly consists in
emitting a call to `gomp_get_mapped_ptr` for the adequate device.

For dispatch, the following steps are performed:

* Handle the device clause, if any. This may affect `need_device_ptr` arguments.

* Handle novariants and nocontext clauses, if any. Evaluate compile-time
constants and select a variant, if possible. Otherwise, emit code to handle all
possible cases at run time.

* Create an explicit task, as if the `task` construct was used, that wraps the
body of the `dispatch` statement. Move relevant clauses to the task.

gcc/ChangeLog:

* gimple-low.cc (lower_stmt): Handle GIMPLE_OMP_DISPATCH.
* gimple-pretty-print.cc (dump_gimple_omp_dispatch): New function.
(pp_gimple_stmt_1): Handle GIMPLE_OMP_DISPATCH.
* gimple-walk.cc (walk_gimple_stmt): Likewise.
* gimple.cc (gimple_build_omp_dispatch): New function.
(gimple_copy): Handle GIMPLE_OMP_DISPATCH.
* gimple.def (GIMPLE_OMP_DISPATCH): Define.
* gimple.h (gimple_build_omp_dispatch): Declare.
(gimple_has_substatements): Handle GIMPLE_OMP_DISPATCH.
(gimple_omp_dispatch_clauses): New function.
(gimple_omp_dispatch_clauses_ptr): Likewise.
(gimple_omp_dispatch_set_clauses): Likewise.
(gimple_return_set_retval): Handle GIMPLE_OMP_DISPATCH.
* gimplify.cc (enum omp_region_type): Add ORT_DISPATCH.
(gimplify_call_expr): Handle need_device_ptr arguments.
(is_gimple_stmt): Handle OMP_DISPATCH.
(gimplify_scan_omp_clauses): Handle OMP_CLAUSE_DEVICE in a dispatch
construct. Handle OMP_CLAUSE_NOVARIANTS and OMP_CLAUSE_NOCONTEXT.
(gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(omp_construct_selector_matches): Handle OMP_DISPATCH with nocontext
clause.
(omp_has_novariants): New function.
(omp_has_nocontext): Likewise.
(gimplify_omp_dispatch): Likewise.
(gimplify_expr): Handle OMP_DISPATCH.
* gimplify.h (omp_has_novariants): Declare.
(omp_has_nocontext): Declare.
* omp-builtins.def (BUILT_IN_OMP_GET_MAPPED_PTR): Define.
(BUILT_IN_OMP_GET_DEFAULT_DEVICE): Define.
(BUILT_IN_OMP_SET_DEFAULT_DEVICE): Define.
* omp-expand.cc (expand_omp_dispatch): New function.
(expand_omp): Handle GIMPLE_OMP_DISPATCH.
(omp_make_gimple_edges): Likewise.
* omp-general.cc (omp_construct_traits_to_codes): Add OMP_DISPATCH.
(struct omp_ts_info): Add dispatch.
(omp_context_selector_matches): Handle OMP_TRAIT_SET_NEED_DEVICE_PTR.
(omp_resolve_declare_variant): Handle novariants. Adjust
DECL_ASSEMBLER_NAME.
---
 gcc/gimple-low.cc  |   1 +
 gcc/gimple-pretty-print.cc |  33 +++
 gcc/gimple-walk.cc |   1 +
 gcc/gimple.cc  |  20 ++
 gcc/gimple.def |   5 +
 gcc/gimple.h   |  33 ++-
 gcc/gimplify.cc| 412 -
 gcc/gimplify.h |   2 +
 gcc/omp-builtins.def   |   6 +
 gcc/omp-expand.cc  |  18 ++
 gcc/omp-general.cc |  16 +-
 gcc/omp-low.cc |  35 
 gcc/tree-inline.cc |   7 +
 13 files changed, 578 insertions(+), 11 deletions(-)

diff --git a/gcc/gimple-low.cc b/gcc/gimple-low.cc
index e0371988705..712a1ebf776 100644
--- a/gcc/gimple-low.cc
+++ b/gcc/gimple-low.cc
@@ -746,6 +746,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data 
*data)
 case GIMPLE_EH_MUST_NOT_THROW:
 case GIMPLE_OMP_FOR:
 case GIMPLE_OMP_SCOPE:
+case GIMPLE_OMP_DISPATCH:
 case GIMPLE_OMP_SECTIONS:
 case GIMPLE_OMP_SECTIONS_SWITCH:
 case GIMPLE_OMP_SECTION:
diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc
index 08b823c84ef..e7b2df9a0ef 100644
--- a/gcc/gimple-pretty-print.cc
+++ b/gcc/gimple-pretty-print.cc
@@ -1726,6 +1726,35 @@ dump_gimple_omp_scope (pretty_printer *pp, const gimple 
*gs,
 }
 }
 
+/* Dump a GIMPLE_OMP_DISPATCH tuple on the pretty_printer BUFFER.  */
+
+static void
+dump_gimple_omp_dispatch (pretty_printer *buffer, const gimple *gs, int spc,
+ dump_flags_t flags)
+{
+  if (flags & TDF_RAW)
+{
+  dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
+  gimple_omp_body (gs));
+  dump_omp_clauses (buffer, gimple_omp_dispatch_clauses (gs), spc, flags);
+  dump_gimple_fmt (buffer, spc, flags, " >");
+}
+  else
+{
+  pp_string (buffer, "#pragma omp dispatch");
+  dump_omp_clauses (buffer, gimple_omp_dispatch_clauses (gs), spc, flags);
+  if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+   {
+ newline_and_indent (buffer, spc + 2);
+ pp_lef

[PATCH v2 2/8] OpenMP: dispatch + adjust_args tree data structures and front-end interfaces

2024-07-12 Thread Paul-Antoine Arras
This patch introduces the OMP_DISPATCH tree node, as well as two new clauses
`nocontext` and `novariants`. It defines/exposes interfaces that will be
used in subsequent patches that add front-end and middle-end support, but
nothing generates these nodes yet.

It also adds support for new OpenMP context selectors: `dispatch` as trait
selector and `need_device_ptr` as pseudo-trait set selector. The purpose of the
latter is for the C++ front-end to store the list of arguments (that need to be
converted to device pointers) until the declaration of the variant function
becomes available.

gcc/ChangeLog:

* builtin-types.def (BT_FN_PTR_CONST_PTR_INT): New.
* omp-selectors.h (enum omp_tss_code): Add
OMP_TRAIT_SET_NEED_DEVICE_PTR.
(enum omp_ts_code): Add OMP_TRAIT_CONSTRUCT_DISPATCH.
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
* tree-pretty-print.cc (dump_omp_clause): Handle OMP_CLAUSE_NOVARIANTS
and OMP_CLAUSE_NOCONTEXT.
(dump_generic_node): Handle OMP_DISPATCH.
* tree.cc (omp_clause_num_ops): Add OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(omp_clause_code_name): Add "novariants" and "nocontext".
* tree.def (OMP_DISPATCH): New.
* tree.h (OMP_DISPATCH_BODY): New macro.
(OMP_DISPATCH_CLAUSES): New macro.
(OMP_CLAUSE_NOVARIANTS_EXPR): New macro.
(OMP_CLAUSE_NOCONTEXT_EXPR): New macro.
---
 gcc/builtin-types.def|  1 +
 gcc/omp-selectors.h  |  3 +++
 gcc/tree-core.h  |  7 +++
 gcc/tree-pretty-print.cc | 21 +
 gcc/tree.cc  |  4 
 gcc/tree.def |  5 +
 gcc/tree.h   |  7 +++
 7 files changed, 48 insertions(+)

diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index c97d6bad1de..ef7aaf67d13 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -677,6 +677,7 @@ DEF_FUNCTION_TYPE_2 (BT_FN_INT_FEXCEPT_T_PTR_INT, BT_INT, 
BT_FEXCEPT_T_PTR,
 DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_FEXCEPT_T_PTR_INT, BT_INT,
 BT_CONST_FEXCEPT_T_PTR, BT_INT)
 DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_UINT8, BT_PTR, BT_CONST_PTR, BT_UINT8)
+DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_INT, BT_PTR, BT_CONST_PTR, BT_INT)
 
 DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
 
diff --git a/gcc/omp-selectors.h b/gcc/omp-selectors.h
index c61808ec0ad..12bc9e9afa0 100644
--- a/gcc/omp-selectors.h
+++ b/gcc/omp-selectors.h
@@ -31,6 +31,8 @@ enum omp_tss_code {
   OMP_TRAIT_SET_TARGET_DEVICE,
   OMP_TRAIT_SET_IMPLEMENTATION,
   OMP_TRAIT_SET_USER,
+  OMP_TRAIT_SET_NEED_DEVICE_PTR, // pseudo-set selector used to convey argument
+// list until variant has a decl
   OMP_TRAIT_SET_LAST,
   OMP_TRAIT_SET_INVALID = -1
 };
@@ -55,6 +57,7 @@ enum omp_ts_code {
   OMP_TRAIT_CONSTRUCT_PARALLEL,
   OMP_TRAIT_CONSTRUCT_FOR,
   OMP_TRAIT_CONSTRUCT_SIMD,
+  OMP_TRAIT_CONSTRUCT_DISPATCH,
   OMP_TRAIT_LAST,
   OMP_TRAIT_INVALID = -1
 };
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 27c569c7702..508f5c580d4 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -542,6 +542,13 @@ enum omp_clause_code {
 
   /* OpenACC clause: nohost.  */
   OMP_CLAUSE_NOHOST,
+
+  /* OpenMP clause: novariants (scalar-expression).  */
+  OMP_CLAUSE_NOVARIANTS,
+
+  /* OpenMP clause: nocontext (scalar-expression).  */
+  OMP_CLAUSE_NOCONTEXT,
+
 };
 
 #undef DEFTREESTRUCT
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index 4bb946bb0e8..752a402e0d0 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -506,6 +506,22 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, 
dump_flags_t flags)
 case OMP_CLAUSE_EXCLUSIVE:
   name = "exclusive";
   goto print_remap;
+case OMP_CLAUSE_NOVARIANTS:
+  pp_string (pp, "novariants");
+  pp_left_paren (pp);
+  gcc_assert (OMP_CLAUSE_NOVARIANTS_EXPR (clause));
+  dump_generic_node (pp, OMP_CLAUSE_NOVARIANTS_EXPR (clause), spc, flags,
+false);
+  pp_right_paren (pp);
+  break;
+case OMP_CLAUSE_NOCONTEXT:
+  pp_string (pp, "nocontext");
+  pp_left_paren (pp);
+  gcc_assert (OMP_CLAUSE_NOCONTEXT_EXPR (clause));
+  dump_generic_node (pp, OMP_CLAUSE_NOCONTEXT_EXPR (clause), spc, flags,
+false);
+  pp_right_paren (pp);
+  break;
 case OMP_CLAUSE__LOOPTEMP_:
   name = "_looptemp_";
   goto print_remap;
@@ -3947,6 +3963,11 @@ dump_generic_node (pretty_printer *pp, tree node, int 
spc, dump_flags_t flags,
   dump_omp_clauses (pp, OMP_SECTIONS_CLAUSES (node), spc, flags);
   goto dump_omp_body;
 
+case OMP_DISPATCH:
+  pp_string (pp, "#pragma omp dispatch");
+  dump_omp_clauses (pp, OMP_DISPATCH_CLAUSES (node), spc, flags);
+  goto dump_omp_body;
+
 case OMP_SECTION:
   pp_string (pp, "#pragma omp section");
   

[PATCH v2 5/8] OpenMP: C++ front-end support for dispatch + adjust_args

2024-07-12 Thread Paul-Antoine Arras
This patch adds C++ support for the `dispatch` construct and the `adjust_args`
clause. It relies on the c-family bits comprised in the corresponding C front
end patch for pragmas and attributes.

Additional C/C++ common testcases are provided in a subsequent patch in the
series.

gcc/cp/ChangeLog:

* decl.cc (omp_declare_variant_finalize_one): Set adjust_args
need_device_ptr attribute.
* parser.cc (cp_parser_direct_declarator): Update call to
cp_parser_late_return_type_opt.
(cp_parser_late_return_type_opt): Add parameter. Update call to
cp_parser_late_parsing_omp_declare_simd.
(cp_parser_omp_clause_name): Handle nocontext and novariants clauses.
(cp_parser_omp_clause_novariants): New function.
(cp_parser_omp_clause_nocontext): Likewise.
(cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_NOVARIANTS and
PRAGMA_OMP_CLAUSE_NOCONTEXT.
(cp_parser_omp_dispatch_body): New function, inspired from
cp_parser_assignment_expression and cp_parser_postfix_expression.
(OMP_DISPATCH_CLAUSE_MASK): Define.
(cp_parser_omp_dispatch): New function.
(cp_finish_omp_declare_variant): Add parameter. Handle adjust_args
clause.
(cp_parser_late_parsing_omp_declare_simd): Add parameter. Update calls
to cp_finish_omp_declare_variant and cp_finish_omp_declare_variant.
(cp_parser_omp_construct): Handle PRAGMA_OMP_DISPATCH.
(cp_parser_pragma): Likewise.
* pt.cc (tsubst_attribute): Skip pseudo-TSS need_device_ptr.
* semantics.cc (finish_omp_clauses): Handle OMP_CLAUSE_NOCONTEXT and
OMP_CLAUSE_NOVARIANTS.

gcc/testsuite/ChangeLog:

* g++.dg/gomp/adjust-args-1.C: New test.
* g++.dg/gomp/adjust-args-2.C: New test.
* g++.dg/gomp/dispatch-1.C: New test.
* g++.dg/gomp/dispatch-2.C: New test.
---
 gcc/cp/decl.cc|  33 ++
 gcc/cp/parser.cc  | 612 --
 gcc/cp/pt.cc  |   3 +
 gcc/cp/semantics.cc   |  20 +
 gcc/testsuite/g++.dg/gomp/adjust-args-1.C |  39 ++
 gcc/testsuite/g++.dg/gomp/adjust-args-2.C |  51 ++
 gcc/testsuite/g++.dg/gomp/dispatch-1.C|  53 ++
 gcc/testsuite/g++.dg/gomp/dispatch-2.C|  62 +++
 8 files changed, 828 insertions(+), 45 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/gomp/adjust-args-1.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/adjust-args-2.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/dispatch-1.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/dispatch-2.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index edf4c155bf7..fae37d508b0 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -8375,6 +8375,39 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
  if (!omp_context_selector_matches (ctx))
return true;
  TREE_PURPOSE (TREE_VALUE (attr)) = variant;
+
+ for (tree a = ctx; a != NULL_TREE; a = TREE_CHAIN (a))
+   {
+ if (OMP_TSS_CODE (a) == OMP_TRAIT_SET_NEED_DEVICE_PTR)
+   {
+ for (tree need_device_ptr_list = TREE_VALUE (a);
+  need_device_ptr_list != NULL_TREE;
+  need_device_ptr_list = TREE_CHAIN (need_device_ptr_list))
+   {
+ tree parm_decl = TREE_VALUE (need_device_ptr_list);
+ bool found_arg = false;
+ for (tree arg = DECL_ARGUMENTS (variant); arg != NULL;
+  arg = TREE_CHAIN (arg))
+   if (DECL_NAME (arg) == DECL_NAME (parm_decl))
+ {
+   DECL_ATTRIBUTES (arg)
+ = tree_cons (get_identifier (
+"omp declare variant adjust_args "
+"need_device_ptr"),
+  NULL_TREE, DECL_ATTRIBUTES (arg));
+   found_arg = true;
+   break;
+ }
+ if (!found_arg)
+   {
+ error_at (varid_loc,
+   "variant %qD does not have a parameter %qD",
+   variant, parm_decl);
+ return true;
+   }
+   }
+   }
+   }
}
 }
   else if (!processing_template_decl)
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 6bf3f52a059..b85c9c387fb 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #include "config.h"
+#include "omp-selectors.h"
 #define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
@@ -2587,7 +2588,7 @@ static cp_ref_qualifier cp_parser_

[PATCH v2 4/8] OpenMP: C front-end support for dispatch + adjust_args

2024-07-12 Thread Paul-Antoine Arras
This patch adds support to the C front-end to parse the `dispatch` construct and
the `adjust_args` clause. It also includes some common C/C++ bits for pragmas
and attributes.

Additional common C/C++ testcases are in a later patch in the series.

gcc/c-family/ChangeLog:

* c-attribs.cc (c_common_gnu_attributes): Add attribute for adjust_args
need_device_ptr.
* c-omp.cc (c_omp_directives): Uncomment dispatch.
* c-pragma.cc (omp_pragmas): Add dispatch.
* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_DISPATCH.
(enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_NOCONTEXT and
PRAGMA_OMP_CLAUSE_NOVARIANTS.

gcc/c/ChangeLog:

* c-parser.cc (c_parser_omp_dispatch): New function.
(c_parser_omp_clause_name): Handle nocontext and novariants clauses.
(c_parser_omp_clause_novariants): New function.
(c_parser_omp_clause_nocontext): Likewise.
(c_parser_omp_all_clauses): Handle nocontext and novariants clauses.
(c_parser_omp_dispatch_body): New function adapted from
c_parser_expr_no_commas.
(OMP_DISPATCH_CLAUSE_MASK): Define.
(c_parser_omp_dispatch): New function.
(c_finish_omp_declare_variant): Parse adjust_args.
(c_parser_omp_construct): Handle PRAGMA_OMP_DISPATCH.
* c-typeck.cc (c_finish_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.

gcc/testsuite/ChangeLog:

* gcc.dg/gomp/adjust-args-1.c: New test.
* gcc.dg/gomp/dispatch-1.c: New test.
---
 gcc/c-family/c-attribs.cc |   2 +
 gcc/c-family/c-omp.cc |   4 +-
 gcc/c-family/c-pragma.cc  |   1 +
 gcc/c-family/c-pragma.h   |   3 +
 gcc/c/c-parser.cc | 496 +++---
 gcc/c/c-typeck.cc |   2 +
 gcc/testsuite/gcc.dg/gomp/adjust-args-1.c |  32 ++
 gcc/testsuite/gcc.dg/gomp/dispatch-1.c|  53 +++
 libgomp/testsuite/libgomp.c/dispatch-1.c  |  76 
 9 files changed, 609 insertions(+), 60 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/gomp/adjust-args-1.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/dispatch-1.c
 create mode 100644 libgomp/testsuite/libgomp.c/dispatch-1.c

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index f9b229aba7f..1cb49d7b911 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -560,6 +560,8 @@ const struct attribute_spec c_common_gnu_attributes[] =
  handle_omp_declare_variant_attribute, NULL },
   { "omp declare variant variant", 0, -1, true,  false, false, false,
  handle_omp_declare_variant_attribute, NULL },
+  { "omp declare variant adjust_args need_device_ptr", 0, -1, true,  false, 
false, false,
+ handle_omp_declare_variant_attribute, NULL },
   { "simd",  0, 1, true,  false, false, false,
  handle_simd_attribute, NULL },
   { "omp declare target", 0, -1, true, false, false, false,
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index b5ce1466e5d..c74a9fb2691 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -4299,8 +4299,8 @@ const struct c_omp_directive c_omp_directives[] = {
 C_OMP_DIR_DECLARATIVE, false },
   { "depobj", nullptr, nullptr, PRAGMA_OMP_DEPOBJ,
 C_OMP_DIR_STANDALONE, false },
-  /* { "dispatch", nullptr, nullptr, PRAGMA_OMP_DISPATCH,
-C_OMP_DIR_CONSTRUCT, false },  */
+  { "dispatch", nullptr, nullptr, PRAGMA_OMP_DISPATCH,
+C_OMP_DIR_DECLARATIVE, false },
   { "distribute", nullptr, nullptr, PRAGMA_OMP_DISTRIBUTE,
 C_OMP_DIR_CONSTRUCT, true },
   { "end", "assumes", nullptr, PRAGMA_OMP_END,
diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc
index 25251c2b69f..b956819c0a5 100644
--- a/gcc/c-family/c-pragma.cc
+++ b/gcc/c-family/c-pragma.cc
@@ -1526,6 +1526,7 @@ static const struct omp_pragma_def omp_pragmas[] = {
   { "cancellation", PRAGMA_OMP_CANCELLATION_POINT },
   { "critical", PRAGMA_OMP_CRITICAL },
   { "depobj", PRAGMA_OMP_DEPOBJ },
+  { "dispatch", PRAGMA_OMP_DISPATCH },
   { "error", PRAGMA_OMP_ERROR },
   { "end", PRAGMA_OMP_END },
   { "flush", PRAGMA_OMP_FLUSH },
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index 2ebde06c471..6b6826b2426 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -55,6 +55,7 @@ enum pragma_kind {
   PRAGMA_OMP_CRITICAL,
   PRAGMA_OMP_DECLARE,
   PRAGMA_OMP_DEPOBJ,
+  PRAGMA_OMP_DISPATCH,
   PRAGMA_OMP_DISTRIBUTE,
   PRAGMA_OMP_ERROR,
   PRAGMA_OMP_END,
@@ -135,9 +136,11 @@ enum pragma_omp_clause {
   PRAGMA_OMP_CLAUSE_LINK,
   PRAGMA_OMP_CLAUSE_MAP,
   PRAGMA_OMP_CLAUSE_MERGEABLE,
+  PRAGMA_OMP_CLAUSE_NOCONTEXT,
   PRAGMA_OMP_CLAUSE_NOGROUP,
   PRAGMA_OMP_CLAUSE_NONTEMPORAL,
   PRAGMA_OMP_CLAUSE_NOTINBRANCH,
+  PRAGMA_OMP_CLAUSE_NOVARIANTS,
   PRAGMA_OMP_CLAUSE_NOWAIT,
   PRAGMA_OMP_CLAUSE_NUM_TASKS,

[PATCH v2 7/8] OpenMP: Fortran front-end support for dispatch + adjust_args

2024-07-12 Thread Paul-Antoine Arras
This patch adds support for the `dispatch` construct and the `adjust_args`
clause to the Fortran front-end.

Handling of `adjust_args` across translation units is missing due to PR115271.

gcc/fortran/ChangeLog:

* dump-parse-tree.cc (show_omp_clauses): Handle novariants and nocontext
clauses.
(show_omp_node): Handle EXEC_OMP_DISPATCH.
(show_code_node): Likewise.
* frontend-passes.cc (gfc_code_walker): Handle novariants and nocontext.
* gfortran.h (enum gfc_statement): Add ST_OMP_DISPATCH.
(symbol_attribute): Add omp_declare_variant_need_device_ptr.
(gfc_omp_clauses): Add novariants and nocontext.
(gfc_omp_declare_variant): Add need_device_ptr_arg_list.
(enum gfc_exec_op): Add EXEC_OMP_DISPATCH.
* match.h (gfc_match_omp_dispatch): Declare.
* openmp.cc (gfc_free_omp_clauses): Free novariants and nocontext
clauses.
(gfc_free_omp_declare_variant_list): Free need_device_ptr_arg_list
namelist.
(enum omp_mask2): Add OMP_CLAUSE_NOVARIANTS and OMP_CLAUSE_NOCONTEXT.
(gfc_match_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(OMP_DISPATCH_CLAUSES): Define.
(gfc_match_omp_dispatch): New function.
(gfc_match_omp_declare_variant): Parse adjust_args.
(resolve_omp_clauses): Handle adjust_args, novariants and nocontext.
Adjust handling of OMP_LIST_IS_DEVICE_PTR.
(icode_code_error_callback): Handle EXEC_OMP_DISPATCH.
(omp_code_to_statement): Likewise.
(resolve_omp_dispatch): New function.
(gfc_resolve_omp_directive): Handle EXEC_OMP_DISPATCH.
* parse.cc (decode_omp_directive): Match dispatch.
(next_statement): Handle ST_OMP_DISPATCH.
(gfc_ascii_statement): Likewise.
(parse_omp_dispatch): New function.
(parse_executable): Handle ST_OMP_DISPATCH.
* resolve.cc (gfc_resolve_blocks): Handle EXEC_OMP_DISPATCH.
* st.cc (gfc_free_statement): Likewise.
* trans-decl.cc (create_function_arglist): Declare.
(gfc_get_extern_function_decl): Call it.
* trans-openmp.cc (gfc_trans_omp_clauses): Handle novariants and
nocontext.
(gfc_trans_omp_dispatch): New function.
(gfc_trans_omp_directive): Handle EXEC_OMP_DISPATCH.
(gfc_trans_omp_declare_variant): Handle adjust_args.
* trans.cc (trans_code): Handle EXEC_OMP_DISPATCH:.
* types.def (BT_FN_PTR_CONST_PTR_INT): Declare.

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/declare-variant-2.f90: Update dg-error.
* gfortran.dg/gomp/declare-variant-21.f90: New test (xfail).
* gfortran.dg/gomp/declare-variant-21-aux.f90: New test.
* gfortran.dg/gomp/adjust-args-1.f90: New test.
* gfortran.dg/gomp/adjust-args-2.f90: New test.
* gfortran.dg/gomp/adjust-args-3.f90: New test.
* gfortran.dg/gomp/adjust-args-4.f90: New test.
* gfortran.dg/gomp/adjust-args-5.f90: New test.
* gfortran.dg/gomp/dispatch-1.f90: New test.
* gfortran.dg/gomp/dispatch-2.f90: New test.
* gfortran.dg/gomp/dispatch-3.f90: New test.
* gfortran.dg/gomp/dispatch-4.f90: New test.
* gfortran.dg/gomp/dispatch-5.f90: New test.
* gfortran.dg/gomp/dispatch-6.f90: New test.
* gfortran.dg/gomp/dispatch-7.f90: New test.
* gfortran.dg/gomp/dispatch-8.f90: New test.
---
 gcc/fortran/dump-parse-tree.cc|  17 ++
 gcc/fortran/frontend-passes.cc|   2 +
 gcc/fortran/gfortran.h|  11 +-
 gcc/fortran/match.h   |   1 +
 gcc/fortran/openmp.cc | 201 --
 gcc/fortran/parse.cc  |  39 +++-
 gcc/fortran/resolve.cc|   2 +
 gcc/fortran/st.cc |   1 +
 gcc/fortran/trans-decl.cc |   9 +-
 gcc/fortran/trans-openmp.cc   | 161 ++
 gcc/fortran/trans.cc  |   1 +
 gcc/fortran/types.def |   1 +
 .../gfortran.dg/gomp/adjust-args-1.f90|  63 ++
 .../gfortran.dg/gomp/adjust-args-2.f90|  18 ++
 .../gfortran.dg/gomp/adjust-args-3.f90|  26 +++
 .../gfortran.dg/gomp/adjust-args-4.f90|  58 +
 .../gfortran.dg/gomp/adjust-args-5.f90|  58 +
 .../gfortran.dg/gomp/declare-variant-2.f90|   6 +-
 .../gomp/declare-variant-21-aux.f90   |  18 ++
 .../gfortran.dg/gomp/declare-variant-21.f90   |  28 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-1.f90 |  77 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-2.f90 |  79 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-3.f90 |  39 
 gcc/testsuite/gfortran.dg/gomp/dispatch-4.f90 |  19 ++
 gcc/testsuite/gfortran.dg/gomp/dispatch-5.f90 |  24 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-6.f90 |  38 
 gcc/testsuite/gfor

[PATCH v2 8/8] OpenMP: update documentation for dispatch and adjust_args

2024-07-12 Thread Paul-Antoine Arras
libgomp/ChangeLog:

* libgomp.texi:
---
 libgomp/libgomp.texi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index 50da248b74d..a2f5897463a 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -294,8 +294,8 @@ The OpenMP 4.5 specification is fully supported.
 @item C/C++'s @code{declare variant} directive: elision support of
   preprocessed code @tab N @tab
 @item @code{declare variant}: new clauses @code{adjust_args} and
-  @code{append_args} @tab N @tab
-@item @code{dispatch} construct @tab N @tab
+  @code{append_args} @tab P @tab Only @code{adjust_args}
+@item @code{dispatch} construct @tab Y @tab
 @item device-specific ICV settings with environment variables @tab Y @tab
 @item @code{assume} and @code{assumes} directives @tab Y @tab
 @item @code{nothing} directive @tab Y @tab
-- 
2.45.2



[PATCH] i386, testsuite: Fix non-Unicode character

2024-07-15 Thread Paul-Antoine Arras
This trivially fixes an incorrectly encoded character in the DejaGnu 
scan pattern.


OK for trunk?
--
PA>From 87686fe5589711b90d0b421368747373978f2a39 Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Mon, 15 Jul 2024 13:18:01 +0200
Subject: [PATCH] Fix non-Unicode character

---
 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
index 3be7676d887..5810cb534a1 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
@@ -18,4 +18,4 @@ male_indirect_jump (long offset)
 /* { dg-final { scan-assembler "jmp\[ \t\]*_?__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
 /* { dg-final { scan-assembler-not {jmp[ \t]*\.?LIND} } } */
-/* { dg-final { scan-assembler-not {call[ \t]*\.âLIND} } } */
+/* { dg-final { scan-assembler-not {call[ \t]*\.?LIND} } } */
-- 
2.45.2



[PATCH 0/7] OpenMP: dispatch + adjust_args support

2024-05-27 Thread Paul-Antoine Arras
This series of patches implement two tightly-knit OpenMP features: the
`dispatch` construct and the `adjust_args` clause to the `declare variant`
directive. `adjust_args` can only be used if the `dispatch` selector appears in
the `match` clause. The "interoperability requirement set" and the `append_args`
clause are out of scope.

In practice, this is mostly useful to transparently convert host pointer
arguments into device pointers when the function is offloaded.

All three front-ends have been tested on an x86_64 Linux machine, as well as
offloading on an AMD Instinct MI210 (gfx90a) GPU.

Paul-Antoine Arras (7):
  OpenMP: dispatch + adjust_args tree data structures and front-end
interfaces
  OpenMP: middle-end support for dispatch + adjust_args
  OpenMP: C front-end support for dispatch + adjust_args
  OpenMP: C++ front-end support for dispatch + adjust_args
  OpenMP: common C/C++ testcases for dispatch + adjust_args
  OpenMP: Fortran front-end support for dispatch + adjust_args
  OpenMP: update documentation for dispatch and adjust_args

 gcc/builtin-types.def |   1 +
 gcc/c-family/c-attribs.cc |   2 +
 gcc/c-family/c-omp.cc |   4 +-
 gcc/c-family/c-pragma.cc  |   1 +
 gcc/c-family/c-pragma.h   |   3 +
 gcc/c/c-parser.cc | 483 --
 gcc/c/c-typeck.cc |   2 +
 gcc/cp/decl.cc|  27 +
 gcc/cp/parser.cc  | 613 --
 gcc/cp/pt.cc  |   3 +
 gcc/cp/semantics.cc   |  20 +
 gcc/fortran/dump-parse-tree.cc|  17 +
 gcc/fortran/frontend-passes.cc|   2 +
 gcc/fortran/gfortran.h|  11 +-
 gcc/fortran/match.h   |   1 +
 gcc/fortran/openmp.cc | 193 +-
 gcc/fortran/parse.cc  |  38 ++
 gcc/fortran/resolve.cc|   2 +
 gcc/fortran/st.cc |   1 +
 gcc/fortran/trans-decl.cc |   9 +-
 gcc/fortran/trans-openmp.cc   | 161 +
 gcc/fortran/trans.cc  |   1 +
 gcc/fortran/types.def |   1 +
 gcc/gimple-low.cc |   1 +
 gcc/gimple-pretty-print.cc|  33 +
 gcc/gimple-walk.cc|   1 +
 gcc/gimple.cc |  20 +
 gcc/gimple.def|   5 +
 gcc/gimple.h  |  33 +-
 gcc/gimplify.cc   | 417 +++-
 gcc/gimplify.h|   2 +
 gcc/omp-builtins.def  |   6 +
 gcc/omp-expand.cc |  18 +
 gcc/omp-general.cc|  16 +-
 gcc/omp-low.cc|  35 +
 gcc/omp-selectors.h   |   3 +
 .../c-c++-common/gomp/adjust-args-1.c |  30 +
 .../c-c++-common/gomp/adjust-args-2.c |  31 +
 .../c-c++-common/gomp/declare-variant-2.c |   4 +-
 gcc/testsuite/c-c++-common/gomp/dispatch-1.c  |  65 ++
 gcc/testsuite/c-c++-common/gomp/dispatch-2.c  |  28 +
 gcc/testsuite/c-c++-common/gomp/dispatch-3.c  |  15 +
 gcc/testsuite/c-c++-common/gomp/dispatch-4.c  |  18 +
 gcc/testsuite/c-c++-common/gomp/dispatch-5.c  |  26 +
 gcc/testsuite/c-c++-common/gomp/dispatch-6.c  |  19 +
 gcc/testsuite/c-c++-common/gomp/dispatch-7.c  |  28 +
 gcc/testsuite/g++.dg/gomp/adjust-args-1.C |  39 ++
 gcc/testsuite/g++.dg/gomp/adjust-args-2.C |  51 ++
 gcc/testsuite/g++.dg/gomp/dispatch-1.C|  53 ++
 gcc/testsuite/g++.dg/gomp/dispatch-2.C|  62 ++
 gcc/testsuite/gcc.dg/gomp/adjust-args-1.c |  32 +
 gcc/testsuite/gcc.dg/gomp/dispatch-1.c|  53 ++
 .../gfortran.dg/gomp/adjust-args-1.f90|  54 ++
 .../gfortran.dg/gomp/adjust-args-2.f90|  18 +
 .../gfortran.dg/gomp/adjust-args-3.f90|  26 +
 .../gfortran.dg/gomp/adjust-args-4.f90|  58 ++
 .../gfortran.dg/gomp/adjust-args-5.f90|  58 ++
 .../gfortran.dg/gomp/declare-variant-2.f90|   6 +-
 gcc/testsuite/gfortran.dg/gomp/dispatch-1.f90 |  77 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-2.f90 |  75 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-3.f90 |  39 ++
 gcc/testsuite/gfortran.dg/gomp/dispatch-4.f90 |  19 +
 gcc/testsuite/gfortran.dg/gomp/dispatch-5.f90 |  24 +
 gcc/testsuite/gfortran.dg/gomp/dispatch-6.f90 |  38 ++
 gcc/testsuite/gfortran.dg/gomp/dispatch-7.f90 |  27 +
 gcc/testsuite/gfortran.dg/gomp/dispatch-8.f90 |  39 ++
 gcc/tree-core.h   |   7 +
 gcc/tree-inline.cc|   7 +
 gcc/tree-pretty-print.cc  |  21 +
 gcc/tree.cc   |   4 +
 gc

[PATCH 2/7] OpenMP: middle-end support for dispatch + adjust_args

2024-05-27 Thread Paul-Antoine Arras
This patch adds middle-end support for the `dispatch` construct and the
`adjust_args` clause. The heavy lifting is done in `gimplify_omp_dispatch` and
`gimplify_call_expr` respectively. For `adjust_args`, this mostly consists in
emitting a call to `gomp_get_mapped_ptr` for the adequate device.

For dispatch, the following steps are performed:

* Handle the device clause, if any. This may affect `need_device_ptr` arguments.

* Handle novariants and nocontext clauses, if any. Evaluate compile-time
constants and select a variant, if possible. Otherwise, emit code to handle all
possible cases at run time.

* Create an explicit task, as if the `task` construct was used, that wraps the
body of the `dispatch` statement. Move relevant clauses to the task.

gcc/ChangeLog:

* gimple-low.cc (lower_stmt): Handle GIMPLE_OMP_DISPATCH.
* gimple-pretty-print.cc (dump_gimple_omp_dispatch): New function.
(pp_gimple_stmt_1): Handle GIMPLE_OMP_DISPATCH.
* gimple-walk.cc (walk_gimple_stmt): Likewise.
* gimple.cc (gimple_build_omp_dispatch): New function.
(gimple_copy): Handle GIMPLE_OMP_DISPATCH.
* gimple.def (GIMPLE_OMP_DISPATCH): Define.
* gimple.h (gimple_build_omp_dispatch): Declare.
(gimple_has_substatements): Handle GIMPLE_OMP_DISPATCH.
(gimple_omp_dispatch_clauses): New function.
(gimple_omp_dispatch_clauses_ptr): Likewise.
(gimple_omp_dispatch_set_clauses): Likewise.
(gimple_return_set_retval): Handle GIMPLE_OMP_DISPATCH.
* gimplify.cc (enum omp_region_type): Add ORT_DISPATCH.
(gimplify_call_expr): Handle need_device_ptr arguments.
(is_gimple_stmt): Handle OMP_DISPATCH.
(gimplify_scan_omp_clauses): Handle OMP_CLAUSE_DEVICE in a dispatch
construct. Handle OMP_CLAUSE_NOVARIANTS and OMP_CLAUSE_NOCONTEXT.
(gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(omp_construct_selector_matches): Handle OMP_DISPATCH with nocontext
clause.
(omp_has_novariants): New function.
(omp_has_nocontext): Likewise.
(gimplify_omp_dispatch): Likewise.
(gimplify_expr): Handle OMP_DISPATCH.
* gimplify.h (omp_has_novariants): Declare.
(omp_has_nocontext): Declare.
* omp-builtins.def (BUILT_IN_OMP_GET_MAPPED_PTR): Define.
(BUILT_IN_OMP_GET_DEFAULT_DEVICE): Define.
(BUILT_IN_OMP_SET_DEFAULT_DEVICE): Define.
* omp-expand.cc (expand_omp_dispatch): New function.
(expand_omp): Handle GIMPLE_OMP_DISPATCH.
(omp_make_gimple_edges): Likewise.
* omp-general.cc (omp_construct_traits_to_codes): Add OMP_DISPATCH.
(struct omp_ts_info): Add dispatch.
(omp_context_selector_matches): Handle OMP_TRAIT_SET_NEED_DEVICE_PTR.
(omp_resolve_declare_variant): Handle novariants. Adjust
DECL_ASSEMBLER_NAME.
---
 gcc/gimple-low.cc  |   1 +
 gcc/gimple-pretty-print.cc |  33 +++
 gcc/gimple-walk.cc |   1 +
 gcc/gimple.cc  |  20 ++
 gcc/gimple.def |   5 +
 gcc/gimple.h   |  33 ++-
 gcc/gimplify.cc| 417 -
 gcc/gimplify.h |   2 +
 gcc/omp-builtins.def   |   6 +
 gcc/omp-expand.cc  |  18 ++
 gcc/omp-general.cc |  16 +-
 gcc/omp-low.cc |  35 
 gcc/tree-inline.cc |   7 +
 13 files changed, 583 insertions(+), 11 deletions(-)

diff --git a/gcc/gimple-low.cc b/gcc/gimple-low.cc
index e0371988705..712a1ebf776 100644
--- a/gcc/gimple-low.cc
+++ b/gcc/gimple-low.cc
@@ -746,6 +746,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data 
*data)
 case GIMPLE_EH_MUST_NOT_THROW:
 case GIMPLE_OMP_FOR:
 case GIMPLE_OMP_SCOPE:
+case GIMPLE_OMP_DISPATCH:
 case GIMPLE_OMP_SECTIONS:
 case GIMPLE_OMP_SECTIONS_SWITCH:
 case GIMPLE_OMP_SECTION:
diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc
index a71e1e0efc7..d9a24ad2169 100644
--- a/gcc/gimple-pretty-print.cc
+++ b/gcc/gimple-pretty-print.cc
@@ -1726,6 +1726,35 @@ dump_gimple_omp_scope (pretty_printer *buffer, const 
gimple *gs,
 }
 }
 
+/* Dump a GIMPLE_OMP_DISPATCH tuple on the pretty_printer BUFFER.  */
+
+static void
+dump_gimple_omp_dispatch (pretty_printer *buffer, const gimple *gs, int spc,
+ dump_flags_t flags)
+{
+  if (flags & TDF_RAW)
+{
+  dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
+  gimple_omp_body (gs));
+  dump_omp_clauses (buffer, gimple_omp_dispatch_clauses (gs), spc, flags);
+  dump_gimple_fmt (buffer, spc, flags, " >");
+}
+  else
+{
+  pp_string (buffer, "#pragma omp dispatch");
+  dump_omp_clauses (buffer, gimple_omp_dispatch_clauses (gs), spc, flags);
+  if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+   {
+ newline_and_indent (buffer, spc + 2);
+ pp

[PATCH 5/7] OpenMP: common C/C++ testcases for dispatch + adjust_args

2024-05-27 Thread Paul-Antoine Arras
gcc/testsuite/ChangeLog:

* c-c++-common/gomp/declare-variant-2.c: Adjust dg-error directives.
* c-c++-common/gomp/adjust-args-1.c: New test.
* c-c++-common/gomp/adjust-args-2.c: New test.
* c-c++-common/gomp/dispatch-1.c: New test.
* c-c++-common/gomp/dispatch-2.c: New test.
* c-c++-common/gomp/dispatch-3.c: New test.
* c-c++-common/gomp/dispatch-4.c: New test.
* c-c++-common/gomp/dispatch-5.c: New test.
* c-c++-common/gomp/dispatch-6.c: New test.
* c-c++-common/gomp/dispatch-7.c: New test.
---
 .../c-c++-common/gomp/adjust-args-1.c | 30 +
 .../c-c++-common/gomp/adjust-args-2.c | 31 +
 .../c-c++-common/gomp/declare-variant-2.c |  4 +-
 gcc/testsuite/c-c++-common/gomp/dispatch-1.c  | 65 +++
 gcc/testsuite/c-c++-common/gomp/dispatch-2.c  | 28 
 gcc/testsuite/c-c++-common/gomp/dispatch-3.c  | 15 +
 gcc/testsuite/c-c++-common/gomp/dispatch-4.c  | 18 +
 gcc/testsuite/c-c++-common/gomp/dispatch-5.c  | 26 
 gcc/testsuite/c-c++-common/gomp/dispatch-6.c  | 19 ++
 gcc/testsuite/c-c++-common/gomp/dispatch-7.c  | 28 
 10 files changed, 262 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-1.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-2.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-3.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-4.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-5.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-6.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-7.c

diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c 
b/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
new file mode 100644
index 000..728abe62092
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b) adjust_args (need_device_ptr: c)
+int f1 (int a, void *b, float c[2]);
+
+int test () {
+  int a;
+  void *b;
+  float c[2];
+  struct {int a;} s;
+
+  s.a = f0 (a, b, c);
+  #pragma omp dispatch
+  s.a = f0 (a, b, c);
+
+  f1 (a, b, c);
+  #pragma omp dispatch
+  s.a = f1 (a, b, c);
+
+  return s.a;
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device 
\\(\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c 
b/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
new file mode 100644
index 000..e36d93a01d9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) adjust_args (need_device_ptr: b, c) match 
(construct={dispatch}) adjust_args (nothing: a) 
+int f1 (int a, void *b, float c[2]);
+
+void test () {
+  int a;
+  void *b;
+  float c[2];
+
+  #pragma omp dispatch
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (-4852)
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (a + a)
+  f0 (a, b, c);
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device 
\\(\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, -4852\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, -4852\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch device\\(-4852\\)" 
1 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c 
b/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c
index 05e485ef6a8..50d9b2dcf4b 100644
--- a/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c
+++ b/gcc/testsuite/c-c++-common/gomp/declare-variant

[PATCH 4/7] OpenMP: C++ front-end support for dispatch + adjust_args

2024-05-27 Thread Paul-Antoine Arras
This patch adds C++ support for the `dispatch` construct and the `adjust_args`
clause. It relies on the c-family bits comprised in the corresponding C front
end patch for pragmas and attributes.

Additional C/C++ common testcases are provided in a subsequent patch in the
series.

gcc/cp/ChangeLog:

* decl.cc (omp_declare_variant_finalize_one): Set adjust_args
need_device_ptr attribute.
* parser.cc (cp_parser_direct_declarator): Update call to
cp_parser_late_return_type_opt.
(cp_parser_late_return_type_opt): Add parameter. Update call to
cp_parser_late_parsing_omp_declare_simd.
(cp_parser_omp_clause_name): Handle nocontext and novariants clauses.
(cp_parser_omp_clause_novariants): New function.
(cp_parser_omp_clause_nocontext): Likewise.
(cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_NOVARIANTS and
PRAGMA_OMP_CLAUSE_NOCONTEXT.
(cp_parser_omp_dispatch_body): New function, inspired from
cp_parser_assignment_expression and cp_parser_postfix_expression.
(OMP_DISPATCH_CLAUSE_MASK): Define.
(cp_parser_omp_dispatch): New function.
(cp_finish_omp_declare_variant): Add parameter. Handle adjust_args
clause.
(cp_parser_late_parsing_omp_declare_simd): Add parameter. Update calls
to cp_finish_omp_declare_variant and cp_finish_omp_declare_variant.
(cp_parser_omp_construct): Handle PRAGMA_OMP_DISPATCH.
(cp_parser_pragma): Likewise.
* pt.cc (tsubst_attribute): Skip pseudo-TSS need_device_ptr.
* semantics.cc (finish_omp_clauses): Handle OMP_CLAUSE_NOCONTEXT and
OMP_CLAUSE_NOVARIANTS.

gcc/testsuite/ChangeLog:

* g++.dg/gomp/adjust-args-1.C: New test.
* g++.dg/gomp/adjust-args-2.C: New test.
* g++.dg/gomp/dispatch-1.C: New test.
* g++.dg/gomp/dispatch-2.C: New test.
---
 gcc/cp/decl.cc|  27 +
 gcc/cp/parser.cc  | 613 --
 gcc/cp/pt.cc  |   3 +
 gcc/cp/semantics.cc   |  20 +
 gcc/testsuite/g++.dg/gomp/adjust-args-1.C |  39 ++
 gcc/testsuite/g++.dg/gomp/adjust-args-2.C |  51 ++
 gcc/testsuite/g++.dg/gomp/dispatch-1.C|  53 ++
 gcc/testsuite/g++.dg/gomp/dispatch-2.C|  62 +++
 8 files changed, 822 insertions(+), 46 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/gomp/adjust-args-1.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/adjust-args-2.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/dispatch-1.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/dispatch-2.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index a992d54dc8f..fe53e59add1 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -8360,6 +8360,33 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
  if (!omp_context_selector_matches (ctx))
return true;
  TREE_PURPOSE (TREE_VALUE (attr)) = variant;
+
+ for (tree a = ctx; a != NULL_TREE; a = TREE_CHAIN (a))
+   {
+ if (OMP_TSS_CODE (a) == OMP_TRAIT_SET_NEED_DEVICE_PTR)
+   {
+ tree parm_decl = TREE_VALUE (TREE_VALUE (a));
+ bool found_arg = false;
+ for (tree arg = DECL_ARGUMENTS (variant); arg != NULL;
+  arg = TREE_CHAIN (arg))
+   if (DECL_NAME (arg) == DECL_NAME (parm_decl))
+ {
+   DECL_ATTRIBUTES (arg)
+ = tree_cons (get_identifier (
+"omp declare variant adjust_args "
+"need_device_ptr"),
+  NULL_TREE, DECL_ATTRIBUTES (arg));
+   found_arg = true;
+ }
+ if (!found_arg)
+   {
+ error_at (varid_loc,
+   "variant %qD does not have a parameter %qD",
+   variant, parm_decl);
+ return true;
+   }
+   }
+   }
}
 }
   else if (!processing_template_decl)
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 779625144db..d61c37729a7 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #include "config.h"
+#include "omp-selectors.h"
 #define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
@@ -2587,7 +2588,7 @@ static cp_ref_qualifier cp_parser_ref_qualifier_opt
 static tree cp_parser_tx_qualifier_opt
   (cp_parser *);
 static tree cp_parser_late_return_type_opt
-  (cp_parser *, cp_declarator *, tree &);
+  (cp_parser *, cp_declarator *, tree &, tree);
 static tree cp_parser_declarator_id
   (cp_parser *, bool);
 static tree cp_parser_type_id
@@ -2622,7 +2623,7 @@ static void 
cp_parser_ctor_initializer_opt_an

[PATCH 1/7] OpenMP: dispatch + adjust_args tree data structures and front-end interfaces

2024-05-27 Thread Paul-Antoine Arras
This patch introduces the OMP_DISPATCH tree node, as well as two new clauses
`nocontext` and `novariants`. It defines/exposes interfaces that will be
used in subsequent patches that add front-end and middle-end support, but
nothing generates these nodes yet.

It also adds support for new OpenMP context selectors: `dispatch` as trait
selector and `need_device_ptr` as pseudo-trait set selector. The purpose of the
latter is for the C++ front-end to store the list of arguments (that need to be
converted to device pointers) until the declaration of the variant function
becomes available.

gcc/ChangeLog:

* builtin-types.def (BT_FN_PTR_CONST_PTR_INT): New.
* omp-selectors.h (enum omp_tss_code): Add
OMP_TRAIT_SET_NEED_DEVICE_PTR.
(enum omp_ts_code): Add OMP_TRAIT_CONSTRUCT_DISPATCH.
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
* tree-pretty-print.cc (dump_omp_clause): Handle OMP_CLAUSE_NOVARIANTS
and OMP_CLAUSE_NOCONTEXT.
(dump_generic_node): Handle OMP_DISPATCH.
* tree.cc (omp_clause_num_ops): Add OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(omp_clause_code_name): Add "novariants" and "nocontext".
* tree.def (OMP_DISPATCH): New.
* tree.h (OMP_DISPATCH_BODY): New macro.
(OMP_DISPATCH_CLAUSES): New macro.
(OMP_CLAUSE_NOVARIANTS_EXPR): New macro.
(OMP_CLAUSE_NOCONTEXT_EXPR): New macro.
---
 gcc/builtin-types.def|  1 +
 gcc/omp-selectors.h  |  3 +++
 gcc/tree-core.h  |  7 +++
 gcc/tree-pretty-print.cc | 21 +
 gcc/tree.cc  |  4 
 gcc/tree.def |  5 +
 gcc/tree.h   |  7 +++
 7 files changed, 48 insertions(+)

diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index c97d6bad1de..ef7aaf67d13 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -677,6 +677,7 @@ DEF_FUNCTION_TYPE_2 (BT_FN_INT_FEXCEPT_T_PTR_INT, BT_INT, 
BT_FEXCEPT_T_PTR,
 DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_FEXCEPT_T_PTR_INT, BT_INT,
 BT_CONST_FEXCEPT_T_PTR, BT_INT)
 DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_UINT8, BT_PTR, BT_CONST_PTR, BT_UINT8)
+DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_INT, BT_PTR, BT_CONST_PTR, BT_INT)
 
 DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
 
diff --git a/gcc/omp-selectors.h b/gcc/omp-selectors.h
index c61808ec0ad..12bc9e9afa0 100644
--- a/gcc/omp-selectors.h
+++ b/gcc/omp-selectors.h
@@ -31,6 +31,8 @@ enum omp_tss_code {
   OMP_TRAIT_SET_TARGET_DEVICE,
   OMP_TRAIT_SET_IMPLEMENTATION,
   OMP_TRAIT_SET_USER,
+  OMP_TRAIT_SET_NEED_DEVICE_PTR, // pseudo-set selector used to convey argument
+// list until variant has a decl
   OMP_TRAIT_SET_LAST,
   OMP_TRAIT_SET_INVALID = -1
 };
@@ -55,6 +57,7 @@ enum omp_ts_code {
   OMP_TRAIT_CONSTRUCT_PARALLEL,
   OMP_TRAIT_CONSTRUCT_FOR,
   OMP_TRAIT_CONSTRUCT_SIMD,
+  OMP_TRAIT_CONSTRUCT_DISPATCH,
   OMP_TRAIT_LAST,
   OMP_TRAIT_INVALID = -1
 };
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 9fa74342919..ed6ffdab87f 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -533,6 +533,13 @@ enum omp_clause_code {
 
   /* OpenACC clause: nohost.  */
   OMP_CLAUSE_NOHOST,
+
+  /* OpenMP clause: novariants (scalar-expression).  */
+  OMP_CLAUSE_NOVARIANTS,
+
+  /* OpenMP clause: nocontext (scalar-expression).  */
+  OMP_CLAUSE_NOCONTEXT,
+
 };
 
 #undef DEFTREESTRUCT
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index f9ad8562078..bbae3a98e9a 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -506,6 +506,22 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, 
dump_flags_t flags)
 case OMP_CLAUSE_EXCLUSIVE:
   name = "exclusive";
   goto print_remap;
+case OMP_CLAUSE_NOVARIANTS:
+  pp_string (pp, "novariants");
+  pp_left_paren (pp);
+  gcc_assert (OMP_CLAUSE_NOVARIANTS_EXPR (clause));
+  dump_generic_node (pp, OMP_CLAUSE_NOVARIANTS_EXPR (clause), spc, flags,
+false);
+  pp_right_paren (pp);
+  break;
+case OMP_CLAUSE_NOCONTEXT:
+  pp_string (pp, "nocontext");
+  pp_left_paren (pp);
+  gcc_assert (OMP_CLAUSE_NOCONTEXT_EXPR (clause));
+  dump_generic_node (pp, OMP_CLAUSE_NOCONTEXT_EXPR (clause), spc, flags,
+false);
+  pp_right_paren (pp);
+  break;
 case OMP_CLAUSE__LOOPTEMP_:
   name = "_looptemp_";
   goto print_remap;
@@ -3918,6 +3934,11 @@ dump_generic_node (pretty_printer *pp, tree node, int 
spc, dump_flags_t flags,
   dump_omp_clauses (pp, OMP_SECTIONS_CLAUSES (node), spc, flags);
   goto dump_omp_body;
 
+case OMP_DISPATCH:
+  pp_string (pp, "#pragma omp dispatch");
+  dump_omp_clauses (pp, OMP_DISPATCH_CLAUSES (node), spc, flags);
+  goto dump_omp_body;
+
 case OMP_SECTION:
   pp_string (pp, "#pragma omp section");
   

[PATCH 7/7] OpenMP: update documentation for dispatch and adjust_args

2024-05-27 Thread Paul-Antoine Arras
libgomp/ChangeLog:

* libgomp.texi:
---
 libgomp/libgomp.texi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index 71d62105a20..b72accd0d26 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -294,8 +294,8 @@ The OpenMP 4.5 specification is fully supported.
 @item C/C++'s @code{declare variant} directive: elision support of
   preprocessed code @tab N @tab
 @item @code{declare variant}: new clauses @code{adjust_args} and
-  @code{append_args} @tab N @tab
-@item @code{dispatch} construct @tab N @tab
+  @code{append_args} @tab P @tab Only @code{adjust_args}
+@item @code{dispatch} construct @tab Y @tab
 @item device-specific ICV settings with environment variables @tab Y @tab
 @item @code{assume} and @code{assumes} directives @tab Y @tab
 @item @code{nothing} directive @tab Y @tab
-- 
2.45.1



[PATCH 3/7] OpenMP: C front-end support for dispatch + adjust_args

2024-05-27 Thread Paul-Antoine Arras
This patch adds support to the C front-end to parse the `dispatch` construct and
the `adjust_args` clause. It also includes some common C/C++ bits for pragmas
and attributes.

Additional common C/C++ testcases are in a later patch in the series.

gcc/c-family/ChangeLog:

* c-attribs.cc (c_common_gnu_attributes): Add attribute for adjust_args
need_device_ptr.
* c-omp.cc (c_omp_directives): Uncomment dispatch.
* c-pragma.cc (omp_pragmas): Add dispatch.
* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_DISPATCH.
(enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_NOCONTEXT and
PRAGMA_OMP_CLAUSE_NOVARIANTS.

gcc/c/ChangeLog:

* c-parser.cc (c_parser_omp_dispatch): New function.
(c_parser_omp_clause_name): Handle nocontext and novariants clauses.
(c_parser_omp_clause_novariants): New function.
(c_parser_omp_clause_nocontext): Likewise.
(c_parser_omp_all_clauses): Handle nocontext and novariants clauses.
(c_parser_omp_dispatch_body): New function adapted from
c_parser_expr_no_commas.
(OMP_DISPATCH_CLAUSE_MASK): Define.
(c_parser_omp_dispatch): New function.
(c_finish_omp_declare_variant): Parse adjust_args.
(c_parser_omp_construct): Handle PRAGMA_OMP_DISPATCH.
* c-typeck.cc (c_finish_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.

gcc/testsuite/ChangeLog:

* gcc.dg/gomp/adjust-args-1.c: New test.
* gcc.dg/gomp/dispatch-1.c: New test.
---
 gcc/c-family/c-attribs.cc |   2 +
 gcc/c-family/c-omp.cc |   4 +-
 gcc/c-family/c-pragma.cc  |   1 +
 gcc/c-family/c-pragma.h   |   3 +
 gcc/c/c-parser.cc | 483 +++---
 gcc/c/c-typeck.cc |   2 +
 gcc/testsuite/gcc.dg/gomp/adjust-args-1.c |  32 ++
 gcc/testsuite/gcc.dg/gomp/dispatch-1.c|  53 +++
 libgomp/testsuite/libgomp.c/dispatch-1.c  |  76 
 9 files changed, 601 insertions(+), 55 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/gomp/adjust-args-1.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/dispatch-1.c
 create mode 100644 libgomp/testsuite/libgomp.c/dispatch-1.c

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 04e39b41bdf..860a068d527 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -556,6 +556,8 @@ const struct attribute_spec c_common_gnu_attributes[] =
  handle_omp_declare_variant_attribute, NULL },
   { "omp declare variant variant", 0, -1, true,  false, false, false,
  handle_omp_declare_variant_attribute, NULL },
+  { "omp declare variant adjust_args need_device_ptr", 0, -1, true,  false, 
false, false,
+ handle_omp_declare_variant_attribute, NULL },
   { "simd",  0, 1, true,  false, false, false,
  handle_simd_attribute, NULL },
   { "omp declare target", 0, -1, true, false, false, false,
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index c0e02aa422f..e6b42dbd01c 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -4196,8 +4196,8 @@ const struct c_omp_directive c_omp_directives[] = {
 C_OMP_DIR_DECLARATIVE, false },
   { "depobj", nullptr, nullptr, PRAGMA_OMP_DEPOBJ,
 C_OMP_DIR_STANDALONE, false },
-  /* { "dispatch", nullptr, nullptr, PRAGMA_OMP_DISPATCH,
-C_OMP_DIR_CONSTRUCT, false },  */
+  { "dispatch", nullptr, nullptr, PRAGMA_OMP_DISPATCH,
+C_OMP_DIR_DECLARATIVE, false },
   { "distribute", nullptr, nullptr, PRAGMA_OMP_DISTRIBUTE,
 C_OMP_DIR_CONSTRUCT, true },
   { "end", "assumes", nullptr, PRAGMA_OMP_END,
diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc
index 1237ee6e62b..60fadeee286 100644
--- a/gcc/c-family/c-pragma.cc
+++ b/gcc/c-family/c-pragma.cc
@@ -1526,6 +1526,7 @@ static const struct omp_pragma_def omp_pragmas[] = {
   { "cancellation", PRAGMA_OMP_CANCELLATION_POINT },
   { "critical", PRAGMA_OMP_CRITICAL },
   { "depobj", PRAGMA_OMP_DEPOBJ },
+  { "dispatch", PRAGMA_OMP_DISPATCH },
   { "error", PRAGMA_OMP_ERROR },
   { "end", PRAGMA_OMP_END },
   { "flush", PRAGMA_OMP_FLUSH },
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index ce93a52fa57..061a83d1716 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -55,6 +55,7 @@ enum pragma_kind {
   PRAGMA_OMP_CRITICAL,
   PRAGMA_OMP_DECLARE,
   PRAGMA_OMP_DEPOBJ,
+  PRAGMA_OMP_DISPATCH,
   PRAGMA_OMP_DISTRIBUTE,
   PRAGMA_OMP_ERROR,
   PRAGMA_OMP_END,
@@ -132,9 +133,11 @@ enum pragma_omp_clause {
   PRAGMA_OMP_CLAUSE_LINK,
   PRAGMA_OMP_CLAUSE_MAP,
   PRAGMA_OMP_CLAUSE_MERGEABLE,
+  PRAGMA_OMP_CLAUSE_NOCONTEXT,
   PRAGMA_OMP_CLAUSE_NOGROUP,
   PRAGMA_OMP_CLAUSE_NONTEMPORAL,
   PRAGMA_OMP_CLAUSE_NOTINBRANCH,
+  PRAGMA_OMP_CLAUSE_NOVARIANTS,
   PRAGMA_OMP_CLAUSE_NOWAIT,
   PRAGMA_OMP_CLAUSE_NUM_TASKS,

[PATCH 6/7] OpenMP: Fortran front-end support for dispatch + adjust_args

2024-05-27 Thread Paul-Antoine Arras
This patch adds support for the `dispatch` construct and the `adjust_args`
clause to the Fortran front-end.

gcc/fortran/ChangeLog:

* dump-parse-tree.cc (show_omp_clauses): Handle novariants and nocontext
clauses.
(show_omp_node): Handle EXEC_OMP_DISPATCH.
(show_code_node): Likewise.
* frontend-passes.cc (gfc_code_walker): Handle novariants and nocontext.
* gfortran.h (enum gfc_statement): Add ST_OMP_DISPATCH.
(symbol_attribute): Add omp_declare_variant_need_device_ptr.
(gfc_omp_clauses): Add novariants and nocontext.
(gfc_omp_declare_variant): Add need_device_ptr_arg_list.
(enum gfc_exec_op): Add EXEC_OMP_DISPATCH.
* match.h (gfc_match_omp_dispatch): Declare.
* openmp.cc (gfc_free_omp_clauses): Free novariants and nocontext
clauses.
(gfc_free_omp_declare_variant_list): Free need_device_ptr_arg_list
namelist.
(enum omp_mask2): Add OMP_CLAUSE_NOVARIANTS and OMP_CLAUSE_NOCONTEXT.
(gfc_match_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(OMP_DISPATCH_CLAUSES): Define.
(gfc_match_omp_dispatch): New function.
(gfc_match_omp_declare_variant): Parse adjust_args.
(resolve_omp_clauses): Handle adjust_args, novariants and nocontext.
Adjust handling of OMP_LIST_IS_DEVICE_PTR.
(icode_code_error_callback): Handle EXEC_OMP_DISPATCH.
(omp_code_to_statement): Likewise.
(resolve_omp_dispatch): New function.
(gfc_resolve_omp_directive): Handle EXEC_OMP_DISPATCH.
* parse.cc (decode_omp_directive): Match dispatch.
(next_statement): Handle ST_OMP_DISPATCH.
(gfc_ascii_statement): Likewise.
(parse_omp_dispatch): New function.
(parse_executable): Handle ST_OMP_DISPATCH.
* resolve.cc (gfc_resolve_blocks): Handle EXEC_OMP_DISPATCH.
* st.cc (gfc_free_statement): Likewise.
* trans-decl.cc (create_function_arglist): Declare.
(gfc_get_extern_function_decl): Call it.
* trans-openmp.cc (gfc_trans_omp_clauses): Handle novariants and
nocontext.
(gfc_trans_omp_dispatch): New function.
(gfc_trans_omp_directive): Handle EXEC_OMP_DISPATCH.
(gfc_trans_omp_declare_variant): Handle adjust_args.
* trans.cc (trans_code): Handle EXEC_OMP_DISPATCH:.
* types.def (BT_FN_PTR_CONST_PTR_INT): Declare.

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/declare-variant-2.f90: Update dg-error.
* gfortran.dg/gomp/adjust-args-1.f90: New test.
* gfortran.dg/gomp/adjust-args-2.f90: New test.
* gfortran.dg/gomp/adjust-args-3.f90: New test.
* gfortran.dg/gomp/adjust-args-4.f90: New test.
* gfortran.dg/gomp/adjust-args-5.f90: New test.
* gfortran.dg/gomp/dispatch-1.f90: New test.
* gfortran.dg/gomp/dispatch-2.f90: New test.
* gfortran.dg/gomp/dispatch-3.f90: New test.
* gfortran.dg/gomp/dispatch-4.f90: New test.
* gfortran.dg/gomp/dispatch-5.f90: New test.
* gfortran.dg/gomp/dispatch-6.f90: New test.
* gfortran.dg/gomp/dispatch-7.f90: New test.
* gfortran.dg/gomp/dispatch-8.f90: New test.
---
 gcc/fortran/dump-parse-tree.cc|  17 ++
 gcc/fortran/frontend-passes.cc|   2 +
 gcc/fortran/gfortran.h|  11 +-
 gcc/fortran/match.h   |   1 +
 gcc/fortran/openmp.cc | 193 --
 gcc/fortran/parse.cc  |  38 
 gcc/fortran/resolve.cc|   2 +
 gcc/fortran/st.cc |   1 +
 gcc/fortran/trans-decl.cc |   9 +-
 gcc/fortran/trans-openmp.cc   | 161 +++
 gcc/fortran/trans.cc  |   1 +
 gcc/fortran/types.def |   1 +
 .../gfortran.dg/gomp/adjust-args-1.f90|  54 +
 .../gfortran.dg/gomp/adjust-args-2.f90|  18 ++
 .../gfortran.dg/gomp/adjust-args-3.f90|  26 +++
 .../gfortran.dg/gomp/adjust-args-4.f90|  58 ++
 .../gfortran.dg/gomp/adjust-args-5.f90|  58 ++
 .../gfortran.dg/gomp/declare-variant-2.f90|   6 +-
 gcc/testsuite/gfortran.dg/gomp/dispatch-1.f90 |  77 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-2.f90 |  75 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-3.f90 |  39 
 gcc/testsuite/gfortran.dg/gomp/dispatch-4.f90 |  19 ++
 gcc/testsuite/gfortran.dg/gomp/dispatch-5.f90 |  24 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-6.f90 |  38 
 gcc/testsuite/gfortran.dg/gomp/dispatch-7.f90 |  27 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-8.f90 |  39 
 26 files changed, 976 insertions(+), 19 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/adjust-args-1.f90
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/adjust-args-2.f90
 create mode 100644 gcc/testsuite/gfo

Re: [PATCH 6/7] OpenMP: Fortran front-end support for dispatch + adjust_args

2024-05-31 Thread Paul-Antoine Arras

Hi Tobias,

Thanks for your comments. Here is an updated patch.

On 28/05/2024 09:14, Tobias Burnus wrote:

Paul-Antoine Arras:

+  if (n->sym->ts.type != BT_DERIVED
+  || !n->sym->ts.u.derived->ts.is_iso_c)
+    {
+  gfc_error ("argument list item %qs in "
+ "% at %L must be of "
+ "TYPE(C_PTR)",
+ n->sym->name, &n->where);


I think you need to rule out 'c_funptr' as well, e.g. via:

     || (n->sym->ts.u.derived->intmod_sym_id
     != ISOCBINDING_PTR)))

I do note that in openmp.cc, we have one check which checks explicitly 
for c_ptr and one existing one which only checks for (c_ptr or 
c_funptr); can you fix that one as well?


This is now handled in the new patch.

But I mainly miss an update to 'module.cc' for the 'declare variant' 
change; the 'adjust_args' (for 'need_device_ptr', only) list items have

to be saved in the .mod file - otherwise the following will not work:

-aux.f90
! { dg-do compile { target skip-all-targets } }
module my_mod
   ...
   !$omp declare variant ... adjust_args(need_device_ptr: ...)
   ...
end module

.f90
{ dg-do ...
! { dg-additional-sources -aux.f90 }
   ...
   call 
   ...
   !$omp displatch
    call 
end


I added a new testcase along those lines. However, I had to xfail it due 
to completely missing support for declare variant (even without 
adjust_args) in module.cc. For reference, Tobias created this PR: 
https://gcc.gnu.org/PR115271.

--
PA
commit ab1b93e3e6e7cb9b5a7419b7106ea0324699
Author: Paul-Antoine Arras 
Date:   Fri May 24 19:13:50 2024 +0200

OpenMP: Fortran front-end support for dispatch + adjust_args

This patch adds support for the `dispatch` construct and the `adjust_args`
clause to the Fortran front-end.

Handling of `adjust_args` across translation units is missing due to PR115271.

gcc/fortran/ChangeLog:

* dump-parse-tree.cc (show_omp_clauses): Handle novariants and nocontext
clauses.
(show_omp_node): Handle EXEC_OMP_DISPATCH.
(show_code_node): Likewise.
* frontend-passes.cc (gfc_code_walker): Handle novariants and nocontext.
* gfortran.h (enum gfc_statement): Add ST_OMP_DISPATCH.
(symbol_attribute): Add omp_declare_variant_need_device_ptr.
(gfc_omp_clauses): Add novariants and nocontext.
(gfc_omp_declare_variant): Add need_device_ptr_arg_list.
(enum gfc_exec_op): Add EXEC_OMP_DISPATCH.
* match.h (gfc_match_omp_dispatch): Declare.
* openmp.cc (gfc_free_omp_clauses): Free novariants and nocontext
clauses.
(gfc_free_omp_declare_variant_list): Free need_device_ptr_arg_list
namelist.
(enum omp_mask2): Add OMP_CLAUSE_NOVARIANTS and OMP_CLAUSE_NOCONTEXT.
(gfc_match_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(OMP_DISPATCH_CLAUSES): Define.
(gfc_match_omp_dispatch): New function.
(gfc_match_omp_declare_variant): Parse adjust_args.
(resolve_omp_clauses): Handle adjust_args, novariants and nocontext.
Adjust handling of OMP_LIST_IS_DEVICE_PTR.
(icode_code_error_callback): Handle EXEC_OMP_DISPATCH.
(omp_code_to_statement): Likewise.
(resolve_omp_dispatch): New function.
(gfc_resolve_omp_directive): Handle EXEC_OMP_DISPATCH.
* parse.cc (decode_omp_directive): Match dispatch.
(next_statement): Handle ST_OMP_DISPATCH.
(gfc_ascii_statement): Likewise.
(parse_omp_dispatch): New function.
(parse_executable): Handle ST_OMP_DISPATCH.
* resolve.cc (gfc_resolve_blocks): Handle EXEC_OMP_DISPATCH.
* st.cc (gfc_free_statement): Likewise.
* trans-decl.cc (create_function_arglist): Declare.
(gfc_get_extern_function_decl): Call it.
* trans-openmp.cc (gfc_trans_omp_clauses): Handle novariants and
nocontext.
(gfc_trans_omp_dispatch): New function.
(gfc_trans_omp_directive): Handle EXEC_OMP_DISPATCH.
(gfc_trans_omp_declare_variant): Handle adjust_args.
* trans.cc (trans_code): Handle EXEC_OMP_DISPATCH:.
* types.def (BT_FN_PTR_CONST_PTR_INT): Declare.

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/declare-variant-2.f90: Update dg-error.
* gfortran.dg/gomp/declare-variant-21.f90: New test (xfail).
* gfortran.dg/gomp/declare-variant-21-aux.f90: New test.
* gfortran.dg/gomp/adjust-args-1.f90: New test.
* gfortran.dg/gomp/adjust-args-2.f90: New test.
* gfortran.dg/gomp/adjust-ar

Re: [PATCH v3 2/7] OpenMP: middle-end support for dispatch + adjust_args

2024-08-20 Thread Paul-Antoine Arras

Hi Tobias,

Thanks for the review. Please find attached an updated patch following 
your comments.
Since further adjustments to other patches of the series were required, 
I'll post them shortly.

See also my replies below.

On 09/08/2024 13:51, Tobias Burnus wrote:

Paul-Antoine Arras wrote:

This patch adds middle-end support for the `dispatch` construct and the
`adjust_args` clause. The heavy lifting is done in 
`gimplify_omp_dispatch` and
`gimplify_call_expr` respectively. For `adjust_args`, this mostly 
consists in

emitting a call to `gomp_get_mapped_ptr` for the adequate device.


...


    * gimplify.h (omp_has_novariants): Declare.
    (omp_has_nocontext): Declare.


As those two functions are only used in gimplify.cc,
please make them 'static' and remove them from gimplify.h.


Done for omp_has_nocontext. However, omp_has_novariants is called by 
omp_resolve_declare_variant in omp-general.cc.



I have a testcase which is rejected with the bogus:

    17 |   !$omp end dispatch
   | 1
Error: Unclassifiable OpenMP directive at (1)

That's at least valid in OpenMP 6.0 previews as those have:
   "For a dispatch directive, the paired 'end' directive is optional."

In 5.2, it is implied via "3.1 Directive Format" and that 'dispatch'
has "Association: block (function dispatch structured block)"

Note: That 'nowait' is an 'end-clause' and may also appear as
'!$omp end dispatch nowait'.
(but either at 'dispatch' or at 'end dispatch'; the current code should 
be able to handle this.)


Added support for optional end directive.

But the main reason that I created the testcase was a comment which 
looked wrong in gimplify_omp_dispatch – and indeed, the attached

testcase gives an ICE:

internal compiler error: in gimplify_omp_dispatch, at gimplify.cc:18064

See attached Fortran testcase + comment below at gimplify_omp_dispatch.


Added testcase and fixed ICE.


--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc


...

@@ -4052,6 +4053,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq 
*pre_p, bool want_value)

    /* Gimplify the function arguments.  */
    if (nargs > 0)
  {
+    tree device_num = NULL_TREE;


Indentation issue: Indented by 4 instead of 6 spaces.


Fixed.

@@ -4062,8 +4064,111 @@ gimplify_call_expr (tree *expr_p, gimple_seq 
*pre_p, bool want_value)


...


+  if (flag_openmp && EXPR_P (CALL_EXPR_FN (*expr_p))
+  && DECL_P (TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0))
+  && (adjust_args_list = lookup_attribute (
+    "omp declare variant variant adjust_args",
+    DECL_ATTRIBUTES (
+  TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0
+   != NULL_TREE)
+    {

...

+  if (gimplify_omp_ctxp != NULL
+  && gimplify_omp_ctxp->code == OMP_DISPATCH)
+    {


The OpenMP spec only supports append_args/adjust_args "when a specified
function variant is selected for replacement in the context of a
function *dispatch* structured block.

Thus, IMHO, you can merge the two if conditions.


Done.


+  for (tree c = gimplify_omp_ctxp->clauses; c;
+   c = TREE_CHAIN (c))
+    {
+  if (OMP_CLAUSE_CODE (c)
+  == OMP_CLAUSE_IS_DEVICE_PTR)
+    {
+  tree decl1 = DECL_NAME (OMP_CLAUSE_DECL (c));
+  tree decl2
+    = tree_strip_nop_conversions (*arg_p);
+  if (TREE_CODE (decl2) == ADDR_EXPR)
+    decl2 = TREE_OPERAND (decl2, 0);
+  gcc_assert (TREE_CODE (decl2) == VAR_DECL
+  || TREE_CODE (decl2)
+   == PARM_DECL);
+  decl2 = DECL_NAME (decl2);
+  if (decl1 == decl2)
+    {
+  is_device_ptr = true;
+  break;
+    }
+    }
+  else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE)
+    device_num = OMP_CLAUSE_OPERAND (c, 0);
+    }


Assume(*) you have:

#pragma omp dispatch is_device_ptr(p) device_num(6)
   foo(p);

If I read the code correctly, this will use the default device as the 
"break" will prevent finding the device clause.


(* Or other way round, if new clauses are internally added at the 
beginning of the list.)


Fixed.


+  if (build_int_cst (integer_type_node, i)
+  == TREE_VALUE (arg))


I think

if (wi::eq_p (i, tree_strip_any_location_wrapper (
 TREE_VALUE (arg)))

is better and avoids creating new tree values that might en up being 
unused. (I am assuming that TREE_CODE(TREE_VALUE (arg)) == INTEGER_CST, 
if not, some additional checks might be needed.)


(The tree_strip_any_location_wr

Re: [PATCH v3 5/7] OpenMP: common C/C++ testcases for dispatch + adjust_args

2024-08-21 Thread Paul-Antoine Arras

Here is an updated version following Tobias's review on the ME patch.
The differences compared to the previous version are:
* updated DejaGnu patterns
* added testcase dispatch-8.c
--
PA
commit 533f2693680f109837f03cda2e123b155bbb5c60
Author: Paul-Antoine Arras 
Date:   Fri May 24 19:04:35 2024 +0200

OpenMP: common C/C++ testcases for dispatch + adjust_args

gcc/testsuite/ChangeLog:

* c-c++-common/gomp/declare-variant-2.c: Adjust dg-error directives.
* c-c++-common/gomp/adjust-args-1.c: New test.
* c-c++-common/gomp/adjust-args-2.c: New test.
* c-c++-common/gomp/dispatch-1.c: New test.
* c-c++-common/gomp/dispatch-2.c: New test.
* c-c++-common/gomp/dispatch-3.c: New test.
* c-c++-common/gomp/dispatch-4.c: New test.
* c-c++-common/gomp/dispatch-5.c: New test.
* c-c++-common/gomp/dispatch-6.c: New test.
* c-c++-common/gomp/dispatch-7.c: New test.
* c-c++-common/gomp/dispatch-8.c: New test.

diff --git gcc/testsuite/c-c++-common/gomp/adjust-args-1.c gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
new file mode 100644
index 000..728abe62092
--- /dev/null
+++ gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args (nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args (nothing: a) adjust_args (need_device_ptr: b) adjust_args (need_device_ptr: c)
+int f1 (int a, void *b, float c[2]);
+
+int test () {
+  int a;
+  void *b;
+  float c[2];
+  struct {int a;} s;
+
+  s.a = f0 (a, b, c);
+  #pragma omp dispatch
+  s.a = f0 (a, b, c);
+
+  f1 (a, b, c);
+  #pragma omp dispatch
+  s.a = f1 (a, b, c);
+
+  return s.a;
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device \\(\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = __builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = __builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
diff --git gcc/testsuite/c-c++-common/gomp/adjust-args-2.c gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
new file mode 100644
index 000..d2a4a5f4ec4
--- /dev/null
+++ gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args (nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) adjust_args (need_device_ptr: b, c) match (construct={dispatch}) adjust_args (nothing: a) 
+int f1 (int a, void *b, float c[2]);
+
+void test () {
+  int a;
+  void *b;
+  float c[2];
+
+  #pragma omp dispatch
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (-4852)
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (a + a)
+  f0 (a, b, c);
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device \\(\\);" 3 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = __builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = __builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = __builtin_omp_get_mapped_ptr \\(&c, -4852\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = __builtin_omp_get_mapped_ptr \\(b, -4852\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-not "#pragma omp dispatch device" "gimple" } } */
diff --git gcc/testsuite/c-c++-common/gomp/declare-variant-2.c gcc/testsuite/c-c++-common/gomp/declare-variant-2.c
index 05e485ef6a8..50d9b2dcf4b 100644
--- gcc/testsuite/c-c++-common/gomp/declare-variant-2.c
+++ gcc/testsuite/c-c++-common/gomp/declare-variant-2.c
@@ -8,9 +8,9 @@ void f3 (void);
 void f4 (void);
 #pragma omp declare variant match(user={condition(0)})	/* { dg-error "expected '\\(' before 'match'" } */
 void f5 (void);
-#pragma omp declare variant (f1)	/* { dg-error "expected 'match' before end of line" } */
+#pragma omp declare variant (f1)	/* { dg-error "expected 'match' or 'adjust_args' before end of line" } */
 void f6 (void);
-#pragma omp declare variant (f1) simd	/* { dg-error "expected 'match' before 'simd'" } */
+#pragma omp declar

Re: [PATCH v3 6/7] OpenMP: Fortran front-end support for dispatch + adjust_args

2024-08-21 Thread Paul-Antoine Arras

Here is an updated version following Tobias's review on the ME patch.
The main differences compared to the previous version are:
* Added support for !$OMP END DISPATCH
* Added testcase dispatch-9.f90
* Updated DejaGnu patterns
--
PA
commit d427c071326c7bf6ccf7ccbc06d6d1cbbb29e73a
Author: Paul-Antoine Arras 
Date:   Fri May 24 19:13:50 2024 +0200

OpenMP: Fortran front-end support for dispatch + adjust_args

This patch adds support for the `dispatch` construct and the `adjust_args`
clause to the Fortran front-end.

Handling of `adjust_args` across translation units is missing due to PR115271.

gcc/fortran/ChangeLog:

* dump-parse-tree.cc (show_omp_clauses): Handle novariants and nocontext
clauses.
(show_omp_node): Handle EXEC_OMP_DISPATCH.
(show_code_node): Likewise.
* frontend-passes.cc (gfc_code_walker): Handle novariants and nocontext.
* gfortran.h (enum gfc_statement): Add ST_OMP_DISPATCH.
(symbol_attribute): Add omp_declare_variant_need_device_ptr.
(gfc_omp_clauses): Add novariants and nocontext.
(gfc_omp_declare_variant): Add need_device_ptr_arg_list.
(enum gfc_exec_op): Add EXEC_OMP_DISPATCH.
* match.h (gfc_match_omp_dispatch): Declare.
* openmp.cc (gfc_free_omp_clauses): Free novariants and nocontext
clauses.
(gfc_free_omp_declare_variant_list): Free need_device_ptr_arg_list
namelist.
(enum omp_mask2): Add OMP_CLAUSE_NOVARIANTS and OMP_CLAUSE_NOCONTEXT.
(gfc_match_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(OMP_DISPATCH_CLAUSES): Define.
(gfc_match_omp_dispatch): New function.
(gfc_match_omp_declare_variant): Parse adjust_args.
(resolve_omp_clauses): Handle adjust_args, novariants and nocontext.
Adjust handling of OMP_LIST_IS_DEVICE_PTR.
(icode_code_error_callback): Handle EXEC_OMP_DISPATCH.
(omp_code_to_statement): Likewise.
(resolve_omp_dispatch): New function.
(gfc_resolve_omp_directive): Handle EXEC_OMP_DISPATCH.
* parse.cc (decode_omp_directive): Match dispatch.
(next_statement): Handle ST_OMP_DISPATCH.
(gfc_ascii_statement): Likewise.
(parse_omp_dispatch): New function.
(parse_executable): Handle ST_OMP_DISPATCH.
* resolve.cc (gfc_resolve_blocks): Handle EXEC_OMP_DISPATCH.
* st.cc (gfc_free_statement): Likewise.
* trans-decl.cc (create_function_arglist): Declare.
(gfc_get_extern_function_decl): Call it.
* trans-openmp.cc (gfc_trans_omp_clauses): Handle novariants and
nocontext.
(gfc_trans_omp_dispatch): New function.
(gfc_trans_omp_directive): Handle EXEC_OMP_DISPATCH.
(gfc_trans_omp_declare_variant): Handle adjust_args.
* trans.cc (trans_code): Handle EXEC_OMP_DISPATCH:.

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/declare-variant-2.f90: Update dg-error.
* gfortran.dg/gomp/declare-variant-21.f90: New test (xfail).
* gfortran.dg/gomp/declare-variant-21-aux.f90: New test.
* gfortran.dg/gomp/adjust-args-1.f90: New test.
* gfortran.dg/gomp/adjust-args-2.f90: New test.
* gfortran.dg/gomp/adjust-args-3.f90: New test.
* gfortran.dg/gomp/adjust-args-4.f90: New test.
* gfortran.dg/gomp/adjust-args-5.f90: New test.
* gfortran.dg/gomp/dispatch-1.f90: New test.
* gfortran.dg/gomp/dispatch-2.f90: New test.
* gfortran.dg/gomp/dispatch-3.f90: New test.
* gfortran.dg/gomp/dispatch-4.f90: New test.
* gfortran.dg/gomp/dispatch-5.f90: New test.
* gfortran.dg/gomp/dispatch-6.f90: New test.
* gfortran.dg/gomp/dispatch-7.f90: New test.
* gfortran.dg/gomp/dispatch-8.f90: New test.
* gfortran.dg/gomp/dispatch-9.f90: New test.

diff --git gcc/fortran/dump-parse-tree.cc gcc/fortran/dump-parse-tree.cc
index 80aa8ef84e7..a15a17c086c 100644
--- gcc/fortran/dump-parse-tree.cc
+++ gcc/fortran/dump-parse-tree.cc
@@ -2139,6 +2139,18 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses)
 	}
   fputc (')', dumpfile);
 }
+  if (omp_clauses->novariants)
+{
+  fputs (" NOVARIANTS(", dumpfile);
+  show_expr (omp_clauses->novariants);
+  fputc (')', dumpfile);
+}
+  if (omp_clauses->nocontext)
+{
+  fputs (" NOCONTEXT(", dumpfile);
+  show_expr (omp_clauses->nocontext);
+  fputc (')', dumpfile);
+}
 }
 
 /* Show a single OpenMP or OpenACC directive node and everything underneath it
@@ -2176,6 +2188,9 @@ show_omp_node (int level, gfc_co

[PATCH v3 1/7] OpenMP: dispatch + adjust_args tree data structures and front-end interfaces

2024-08-07 Thread Paul-Antoine Arras
This patch introduces the OMP_DISPATCH tree node, as well as two new clauses
`nocontext` and `novariants`. It defines/exposes interfaces that will be
used in subsequent patches that add front-end and middle-end support, but
nothing generates these nodes yet.

gcc/ChangeLog:

* builtin-types.def (BT_FN_PTR_CONST_PTR_INT): New.
* omp-selectors.h (enum omp_ts_code): Add OMP_TRAIT_CONSTRUCT_DISPATCH.
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
* tree-pretty-print.cc (dump_omp_clause): Handle OMP_CLAUSE_NOVARIANTS
and OMP_CLAUSE_NOCONTEXT.
(dump_generic_node): Handle OMP_DISPATCH.
* tree.cc (omp_clause_num_ops): Add OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(omp_clause_code_name): Add "novariants" and "nocontext".
* tree.def (OMP_DISPATCH): New.
* tree.h (OMP_DISPATCH_BODY): New macro.
(OMP_DISPATCH_CLAUSES): New macro.
(OMP_CLAUSE_NOVARIANTS_EXPR): New macro.
(OMP_CLAUSE_NOCONTEXT_EXPR): New macro.

gcc/fortran/ChangeLog:

* types.def (BT_FN_PTR_CONST_PTR_INT): Declare.
---
 gcc/builtin-types.def|  1 +
 gcc/fortran/types.def|  1 +
 gcc/omp-selectors.h  |  1 +
 gcc/tree-core.h  |  7 +++
 gcc/tree-pretty-print.cc | 21 +
 gcc/tree.cc  |  4 
 gcc/tree.def |  5 +
 gcc/tree.h   |  7 +++
 8 files changed, 47 insertions(+)

diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index c97d6bad1de..ef7aaf67d13 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -677,6 +677,7 @@ DEF_FUNCTION_TYPE_2 (BT_FN_INT_FEXCEPT_T_PTR_INT, BT_INT, 
BT_FEXCEPT_T_PTR,
 DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_FEXCEPT_T_PTR_INT, BT_INT,
 BT_CONST_FEXCEPT_T_PTR, BT_INT)
 DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_UINT8, BT_PTR, BT_CONST_PTR, BT_UINT8)
+DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_INT, BT_PTR, BT_CONST_PTR, BT_INT)
 
 DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
 
diff --git a/gcc/fortran/types.def b/gcc/fortran/types.def
index 390cc9542f7..5047c8f816a 100644
--- a/gcc/fortran/types.def
+++ b/gcc/fortran/types.def
@@ -120,6 +120,7 @@ DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_INT_BOOL, BT_BOOL, BT_INT, 
BT_BOOL)
 DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_PTRMODE,
 BT_VOID, BT_PTR, BT_PTRMODE)
 DEF_FUNCTION_TYPE_2 (BT_FN_VOID_CONST_PTR_SIZE, BT_VOID, BT_CONST_PTR, BT_SIZE)
+DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_INT, BT_PTR, BT_CONST_PTR, BT_INT)
 
 DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
 
diff --git a/gcc/omp-selectors.h b/gcc/omp-selectors.h
index c61808ec0ad..ef3ce9a449a 100644
--- a/gcc/omp-selectors.h
+++ b/gcc/omp-selectors.h
@@ -55,6 +55,7 @@ enum omp_ts_code {
   OMP_TRAIT_CONSTRUCT_PARALLEL,
   OMP_TRAIT_CONSTRUCT_FOR,
   OMP_TRAIT_CONSTRUCT_SIMD,
+  OMP_TRAIT_CONSTRUCT_DISPATCH,
   OMP_TRAIT_LAST,
   OMP_TRAIT_INVALID = -1
 };
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 27c569c7702..508f5c580d4 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -542,6 +542,13 @@ enum omp_clause_code {
 
   /* OpenACC clause: nohost.  */
   OMP_CLAUSE_NOHOST,
+
+  /* OpenMP clause: novariants (scalar-expression).  */
+  OMP_CLAUSE_NOVARIANTS,
+
+  /* OpenMP clause: nocontext (scalar-expression).  */
+  OMP_CLAUSE_NOCONTEXT,
+
 };
 
 #undef DEFTREESTRUCT
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index 4bb946bb0e8..752a402e0d0 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -506,6 +506,22 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, 
dump_flags_t flags)
 case OMP_CLAUSE_EXCLUSIVE:
   name = "exclusive";
   goto print_remap;
+case OMP_CLAUSE_NOVARIANTS:
+  pp_string (pp, "novariants");
+  pp_left_paren (pp);
+  gcc_assert (OMP_CLAUSE_NOVARIANTS_EXPR (clause));
+  dump_generic_node (pp, OMP_CLAUSE_NOVARIANTS_EXPR (clause), spc, flags,
+false);
+  pp_right_paren (pp);
+  break;
+case OMP_CLAUSE_NOCONTEXT:
+  pp_string (pp, "nocontext");
+  pp_left_paren (pp);
+  gcc_assert (OMP_CLAUSE_NOCONTEXT_EXPR (clause));
+  dump_generic_node (pp, OMP_CLAUSE_NOCONTEXT_EXPR (clause), spc, flags,
+false);
+  pp_right_paren (pp);
+  break;
 case OMP_CLAUSE__LOOPTEMP_:
   name = "_looptemp_";
   goto print_remap;
@@ -3947,6 +3963,11 @@ dump_generic_node (pretty_printer *pp, tree node, int 
spc, dump_flags_t flags,
   dump_omp_clauses (pp, OMP_SECTIONS_CLAUSES (node), spc, flags);
   goto dump_omp_body;
 
+case OMP_DISPATCH:
+  pp_string (pp, "#pragma omp dispatch");
+  dump_omp_clauses (pp, OMP_DISPATCH_CLAUSES (node), spc, flags);
+  goto dump_omp_body;
+
 case OMP_SECTION:
   pp_string (pp, "#pragma omp section");
   goto dump_omp_body;
diff --git a/gcc/tree.cc b/gcc/tree.cc

[PATCH v3 0/7] OpenMP: dispatch + adjust_args support

2024-08-07 Thread Paul-Antoine Arras
This is a respin of my patchset implementing both the `dispatch` construct and 
the `adjust_args` clause to the `declare variant` directive. The previous
submission can be found there: 
https://gcc.gnu.org/pipermail/gcc-patches/2024-July/657151.html.

Beside being rebased, this new iteration has the following changes:
 * Remove `need_device_ptr` as pseudo-trait set selector and pass `adjust_args`
 list as attribute to the base function. This also ensures that the list will 
 survive multiple declarations;
 * OpenMP 5.1 mandated that each dispatch construct should generate an explicit 
 task. This requirement has been lifted in 5.2, so we removed it;
 * As a result, some clauses are now handled differently: nowait has no effect, 
 depend is moved to a taskwait construct and the default-device ICV has to be 
 restored at the end of the dispatch region;
 * Update test cases.


Paul-Antoine Arras (7):
  OpenMP: dispatch + adjust_args tree data structures and front-end
interfaces
  OpenMP: middle-end support for dispatch + adjust_args
  OpenMP: C front-end support for dispatch + adjust_args
  OpenMP: C++ front-end support for dispatch + adjust_args
  OpenMP: common C/C++ testcases for dispatch + adjust_args
  OpenMP: Fortran front-end support for dispatch + adjust_args
  OpenMP: update documentation for dispatch and adjust_args

 gcc/builtin-types.def |   1 +
 gcc/c-family/c-attribs.cc |   2 +
 gcc/c-family/c-omp.cc |   4 +-
 gcc/c-family/c-pragma.cc  |   1 +
 gcc/c-family/c-pragma.h   |   3 +
 gcc/c/c-parser.cc | 522 +--
 gcc/c/c-typeck.cc |   2 +
 gcc/cp/decl.cc|   7 +
 gcc/cp/parser.cc  | 631 --
 gcc/cp/semantics.cc   |  20 +
 gcc/fortran/dump-parse-tree.cc|  17 +
 gcc/fortran/frontend-passes.cc|   2 +
 gcc/fortran/gfortran.h|  11 +-
 gcc/fortran/match.h   |   1 +
 gcc/fortran/openmp.cc | 192 +-
 gcc/fortran/parse.cc  |  39 +-
 gcc/fortran/resolve.cc|   2 +
 gcc/fortran/st.cc |   1 +
 gcc/fortran/trans-decl.cc |   9 +-
 gcc/fortran/trans-openmp.cc   | 135 
 gcc/fortran/trans.cc  |   1 +
 gcc/fortran/types.def |   1 +
 gcc/gimple-low.cc |   1 +
 gcc/gimple-pretty-print.cc|  33 +
 gcc/gimple-walk.cc|   1 +
 gcc/gimple.cc |  20 +
 gcc/gimple.def|   5 +
 gcc/gimple.h  |  33 +-
 gcc/gimplify.cc   | 421 +++-
 gcc/gimplify.h|   2 +
 gcc/omp-builtins.def  |   6 +
 gcc/omp-expand.cc |  18 +
 gcc/omp-general.cc|  14 +-
 gcc/omp-low.cc|  35 +
 gcc/omp-selectors.h   |   1 +
 .../c-c++-common/gomp/adjust-args-1.c |  30 +
 .../c-c++-common/gomp/adjust-args-2.c |  31 +
 .../c-c++-common/gomp/declare-variant-2.c |   4 +-
 gcc/testsuite/c-c++-common/gomp/dispatch-1.c  |  65 ++
 gcc/testsuite/c-c++-common/gomp/dispatch-2.c  |  28 +
 gcc/testsuite/c-c++-common/gomp/dispatch-3.c  |  12 +
 gcc/testsuite/c-c++-common/gomp/dispatch-4.c  |  18 +
 gcc/testsuite/c-c++-common/gomp/dispatch-5.c  |  27 +
 gcc/testsuite/c-c++-common/gomp/dispatch-6.c  |  18 +
 gcc/testsuite/c-c++-common/gomp/dispatch-7.c  |  21 +
 gcc/testsuite/g++.dg/gomp/adjust-args-1.C |  39 ++
 gcc/testsuite/g++.dg/gomp/adjust-args-2.C |  51 ++
 gcc/testsuite/g++.dg/gomp/dispatch-1.C|  53 ++
 gcc/testsuite/g++.dg/gomp/dispatch-2.C|  62 ++
 gcc/testsuite/gcc.dg/gomp/adjust-args-1.c |  32 +
 gcc/testsuite/gcc.dg/gomp/dispatch-1.c|  53 ++
 .../gfortran.dg/gomp/adjust-args-1.f90|  58 ++
 .../gfortran.dg/gomp/adjust-args-2.f90|  18 +
 .../gfortran.dg/gomp/adjust-args-3.f90|  27 +
 .../gfortran.dg/gomp/adjust-args-4.f90|  58 ++
 .../gfortran.dg/gomp/adjust-args-5.f90|  58 ++
 .../gfortran.dg/gomp/declare-variant-2.f90|   6 +-
 .../gomp/declare-variant-21-aux.f90   |  25 +
 .../gfortran.dg/gomp/declare-variant-21.f90   |  22 +
 gcc/testsuite/gfortran.dg/gomp/dispatch-1.f90 |  77 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-2.f90 |  79 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-3.f90 |  39 ++
 gcc/testsuite/gfortran.dg/gomp/dispatch-4.f90 |  19 +
 gcc/testsuite/gfortran.dg/gomp/dispatch-5.f90 |  25 +
 gcc/testsuite/gfortran.dg/gomp/dispatch-6.f90 |  39

[PATCH v3 2/7] OpenMP: middle-end support for dispatch + adjust_args

2024-08-07 Thread Paul-Antoine Arras
This patch adds middle-end support for the `dispatch` construct and the
`adjust_args` clause. The heavy lifting is done in `gimplify_omp_dispatch` and
`gimplify_call_expr` respectively. For `adjust_args`, this mostly consists in
emitting a call to `gomp_get_mapped_ptr` for the adequate device.

For dispatch, the following steps are performed:

* Handle the device clause, if any: set the default-device ICV at the top of the
dispatch region and restore its previous value at the end.

* Handle novariants and nocontext clauses, if any. Evaluate compile-time
constants and select a variant, if possible. Otherwise, emit code to handle all
possible cases at run time.

* If depend clauses are present, add a taskwait construct before the dispatch
region and move them there.

gcc/ChangeLog:

* gimple-low.cc (lower_stmt): Handle GIMPLE_OMP_DISPATCH.
* gimple-pretty-print.cc (dump_gimple_omp_dispatch): New function.
(pp_gimple_stmt_1): Handle GIMPLE_OMP_DISPATCH.
* gimple-walk.cc (walk_gimple_stmt): Likewise.
* gimple.cc (gimple_build_omp_dispatch): New function.
(gimple_copy): Handle GIMPLE_OMP_DISPATCH.
* gimple.def (GIMPLE_OMP_DISPATCH): Define.
* gimple.h (gimple_build_omp_dispatch): Declare.
(gimple_has_substatements): Handle GIMPLE_OMP_DISPATCH.
(gimple_omp_dispatch_clauses): New function.
(gimple_omp_dispatch_clauses_ptr): Likewise.
(gimple_omp_dispatch_set_clauses): Likewise.
(gimple_return_set_retval): Handle GIMPLE_OMP_DISPATCH.
* gimplify.cc (enum omp_region_type): Add ORT_DISPATCH.
(gimplify_call_expr): Handle need_device_ptr arguments.
(is_gimple_stmt): Handle OMP_DISPATCH.
(gimplify_scan_omp_clauses): Handle OMP_CLAUSE_DEVICE in a dispatch
construct. Handle OMP_CLAUSE_NOVARIANTS and OMP_CLAUSE_NOCONTEXT.
(gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(omp_construct_selector_matches): Handle OMP_DISPATCH with nocontext
clause.
(omp_has_novariants): New function.
(omp_has_nocontext): Likewise.
(gimplify_omp_dispatch): Likewise.
(gimplify_expr): Handle OMP_DISPATCH.
* gimplify.h (omp_has_novariants): Declare.
(omp_has_nocontext): Declare.
* omp-builtins.def (BUILT_IN_OMP_GET_MAPPED_PTR): Define.
(BUILT_IN_OMP_GET_DEFAULT_DEVICE): Define.
(BUILT_IN_OMP_SET_DEFAULT_DEVICE): Define.
* omp-expand.cc (expand_omp_dispatch): New function.
(expand_omp): Handle GIMPLE_OMP_DISPATCH.
(omp_make_gimple_edges): Likewise.
* omp-general.cc (omp_construct_traits_to_codes): Add OMP_DISPATCH.
(struct omp_ts_info): Add dispatch.
(omp_context_selector_matches): Handle OMP_TRAIT_SET_NEED_DEVICE_PTR.
(omp_resolve_declare_variant): Handle novariants. Adjust
DECL_ASSEMBLER_NAME.
---
 gcc/gimple-low.cc  |   1 +
 gcc/gimple-pretty-print.cc |  33 +++
 gcc/gimple-walk.cc |   1 +
 gcc/gimple.cc  |  20 ++
 gcc/gimple.def |   5 +
 gcc/gimple.h   |  33 ++-
 gcc/gimplify.cc| 421 -
 gcc/gimplify.h |   2 +
 gcc/omp-builtins.def   |   6 +
 gcc/omp-expand.cc  |  18 ++
 gcc/omp-general.cc |  14 +-
 gcc/omp-low.cc |  35 +++
 gcc/tree-inline.cc |   7 +
 13 files changed, 585 insertions(+), 11 deletions(-)

diff --git a/gcc/gimple-low.cc b/gcc/gimple-low.cc
index e0371988705..712a1ebf776 100644
--- a/gcc/gimple-low.cc
+++ b/gcc/gimple-low.cc
@@ -746,6 +746,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data 
*data)
 case GIMPLE_EH_MUST_NOT_THROW:
 case GIMPLE_OMP_FOR:
 case GIMPLE_OMP_SCOPE:
+case GIMPLE_OMP_DISPATCH:
 case GIMPLE_OMP_SECTIONS:
 case GIMPLE_OMP_SECTIONS_SWITCH:
 case GIMPLE_OMP_SECTION:
diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc
index 08b823c84ef..e7b2df9a0ef 100644
--- a/gcc/gimple-pretty-print.cc
+++ b/gcc/gimple-pretty-print.cc
@@ -1726,6 +1726,35 @@ dump_gimple_omp_scope (pretty_printer *pp, const gimple 
*gs,
 }
 }
 
+/* Dump a GIMPLE_OMP_DISPATCH tuple on the pretty_printer BUFFER.  */
+
+static void
+dump_gimple_omp_dispatch (pretty_printer *buffer, const gimple *gs, int spc,
+ dump_flags_t flags)
+{
+  if (flags & TDF_RAW)
+{
+  dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
+  gimple_omp_body (gs));
+  dump_omp_clauses (buffer, gimple_omp_dispatch_clauses (gs), spc, flags);
+  dump_gimple_fmt (buffer, spc, flags, " >");
+}
+  else
+{
+  pp_string (buffer, "#pragma omp dispatch");
+  dump_omp_clauses (buffer, gimple_omp_dispatch_clauses (gs), spc, flags);
+  if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+   {
+ newline_and_indent (buffer, spc + 2);

[PATCH v3 5/7] OpenMP: common C/C++ testcases for dispatch + adjust_args

2024-08-07 Thread Paul-Antoine Arras
gcc/testsuite/ChangeLog:

* c-c++-common/gomp/declare-variant-2.c: Adjust dg-error directives.
* c-c++-common/gomp/adjust-args-1.c: New test.
* c-c++-common/gomp/adjust-args-2.c: New test.
* c-c++-common/gomp/dispatch-1.c: New test.
* c-c++-common/gomp/dispatch-2.c: New test.
* c-c++-common/gomp/dispatch-3.c: New test.
* c-c++-common/gomp/dispatch-4.c: New test.
* c-c++-common/gomp/dispatch-5.c: New test.
* c-c++-common/gomp/dispatch-6.c: New test.
* c-c++-common/gomp/dispatch-7.c: New test.
---
 .../c-c++-common/gomp/adjust-args-1.c | 30 +
 .../c-c++-common/gomp/adjust-args-2.c | 31 +
 .../c-c++-common/gomp/declare-variant-2.c |  4 +-
 gcc/testsuite/c-c++-common/gomp/dispatch-1.c  | 65 +++
 gcc/testsuite/c-c++-common/gomp/dispatch-2.c  | 28 
 gcc/testsuite/c-c++-common/gomp/dispatch-3.c  | 12 
 gcc/testsuite/c-c++-common/gomp/dispatch-4.c  | 18 +
 gcc/testsuite/c-c++-common/gomp/dispatch-5.c  | 27 
 gcc/testsuite/c-c++-common/gomp/dispatch-6.c  | 18 +
 gcc/testsuite/c-c++-common/gomp/dispatch-7.c  | 21 ++
 .../dispatch-1.c  |  0
 .../dispatch-2.c  |  0
 12 files changed, 252 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-1.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-2.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-3.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-4.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-5.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-6.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-7.c
 rename libgomp/testsuite/{libgomp.c => libgomp.c-c++-common}/dispatch-1.c 
(100%)
 rename libgomp/testsuite/{libgomp.c => libgomp.c-c++-common}/dispatch-2.c 
(100%)

diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c 
b/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
new file mode 100644
index 000..728abe62092
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b) adjust_args (need_device_ptr: c)
+int f1 (int a, void *b, float c[2]);
+
+int test () {
+  int a;
+  void *b;
+  float c[2];
+  struct {int a;} s;
+
+  s.a = f0 (a, b, c);
+  #pragma omp dispatch
+  s.a = f0 (a, b, c);
+
+  f1 (a, b, c);
+  #pragma omp dispatch
+  s.a = f1 (a, b, c);
+
+  return s.a;
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device 
\\(\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c 
b/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
new file mode 100644
index 000..d2a4a5f4ec4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) adjust_args (need_device_ptr: b, c) match 
(construct={dispatch}) adjust_args (nothing: a) 
+int f1 (int a, void *b, float c[2]);
+
+void test () {
+  int a;
+  void *b;
+  float c[2];
+
+  #pragma omp dispatch
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (-4852)
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (a + a)
+  f0 (a, b, c);
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device 
\\(\\);" 3 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, -4852\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, -4852\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-not "#pragma omp dispatch device" "gimple" } } 
*/
diff --git a/gcc/t

[PATCH v3 4/7] OpenMP: C++ front-end support for dispatch + adjust_args

2024-08-07 Thread Paul-Antoine Arras
This patch adds C++ support for the `dispatch` construct and the `adjust_args`
clause. It relies on the c-family bits comprised in the corresponding C front
end patch for pragmas and attributes.

Additional C/C++ common testcases are provided in a subsequent patch in the
series.

gcc/cp/ChangeLog:

* decl.cc (omp_declare_variant_finalize_one): Set adjust_args
need_device_ptr attribute.
* parser.cc (cp_parser_direct_declarator): Update call to
cp_parser_late_return_type_opt.
(cp_parser_late_return_type_opt): Add parameter. Update call to
cp_parser_late_parsing_omp_declare_simd.
(cp_parser_omp_clause_name): Handle nocontext and novariants clauses.
(cp_parser_omp_clause_novariants): New function.
(cp_parser_omp_clause_nocontext): Likewise.
(cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_NOVARIANTS and
PRAGMA_OMP_CLAUSE_NOCONTEXT.
(cp_parser_omp_dispatch_body): New function, inspired from
cp_parser_assignment_expression and cp_parser_postfix_expression.
(OMP_DISPATCH_CLAUSE_MASK): Define.
(cp_parser_omp_dispatch): New function.
(cp_finish_omp_declare_variant): Add parameter. Handle adjust_args
clause.
(cp_parser_late_parsing_omp_declare_simd): Add parameter. Update calls
to cp_finish_omp_declare_variant and cp_finish_omp_declare_variant.
(cp_parser_omp_construct): Handle PRAGMA_OMP_DISPATCH.
(cp_parser_pragma): Likewise.
* semantics.cc (finish_omp_clauses): Handle OMP_CLAUSE_NOCONTEXT and
OMP_CLAUSE_NOVARIANTS.

gcc/testsuite/ChangeLog:

* g++.dg/gomp/adjust-args-1.C: New test.
* g++.dg/gomp/adjust-args-2.C: New test.
* g++.dg/gomp/dispatch-1.C: New test.
* g++.dg/gomp/dispatch-2.C: New test.
---
 gcc/cp/decl.cc|   7 +
 gcc/cp/parser.cc  | 631 --
 gcc/cp/semantics.cc   |  20 +
 gcc/testsuite/g++.dg/gomp/adjust-args-1.C |  39 ++
 gcc/testsuite/g++.dg/gomp/adjust-args-2.C |  51 ++
 gcc/testsuite/g++.dg/gomp/dispatch-1.C|  53 ++
 gcc/testsuite/g++.dg/gomp/dispatch-2.C|  62 +++
 7 files changed, 818 insertions(+), 45 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/gomp/adjust-args-1.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/adjust-args-2.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/dispatch-1.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/dispatch-2.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 279af21eed0..00056d37ecf 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -8383,6 +8383,13 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
  if (!omp_context_selector_matches (ctx))
return true;
  TREE_PURPOSE (TREE_VALUE (attr)) = variant;
+
+ // Prepend adjust_args list to variant attributes
+ tree adjust_args_list = TREE_CHAIN (TREE_CHAIN (chain));
+ if (adjust_args_list != NULL_TREE)
+   DECL_ATTRIBUTES (variant) = tree_cons (
+ get_identifier ("omp declare variant variant adjust_args"),
+ TREE_VALUE (adjust_args_list), DECL_ATTRIBUTES (variant));
}
 }
   else if (!processing_template_decl)
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index eb102dea829..b43eabb0cff 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #include "config.h"
+#include "omp-selectors.h"
 #define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
@@ -2587,7 +2588,7 @@ static cp_ref_qualifier cp_parser_ref_qualifier_opt
 static tree cp_parser_tx_qualifier_opt
   (cp_parser *);
 static tree cp_parser_late_return_type_opt
-  (cp_parser *, cp_declarator *, tree &);
+  (cp_parser *, cp_declarator *, tree &, tree);
 static tree cp_parser_declarator_id
   (cp_parser *, bool);
 static tree cp_parser_type_id
@@ -2622,7 +2623,7 @@ static void 
cp_parser_ctor_initializer_opt_and_function_body
   (cp_parser *, bool);
 
 static tree cp_parser_late_parsing_omp_declare_simd
-  (cp_parser *, tree);
+  (cp_parser *, tree, tree);
 
 static tree cp_parser_late_parsing_oacc_routine
   (cp_parser *, tree);
@@ -24193,7 +24194,7 @@ cp_parser_direct_declarator (cp_parser* parser,
  tree requires_clause = NULL_TREE;
  late_return
= cp_parser_late_return_type_opt (parser, declarator,
- requires_clause);
+ requires_clause, params);
 
  cp_finalize_omp_declare_simd (parser, &odsd);
 
@@ -25058,8 +25059,8 @@ parsing_function_declarator ()
function.  */
 
 static tree
-cp_parser_late_return_type_opt (cp_parser* parser, cp_declarator *declarator,
-   tree& requires_clause)
+cp_parser_late_return_type_opt (c

[PATCH v3 7/7] OpenMP: update documentation for dispatch and adjust_args

2024-08-07 Thread Paul-Antoine Arras
libgomp/ChangeLog:

* libgomp.texi:
---
 libgomp/libgomp.texi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index 07cd75124b0..b35424c047a 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -294,8 +294,8 @@ The OpenMP 4.5 specification is fully supported.
 @item C/C++'s @code{declare variant} directive: elision support of
   preprocessed code @tab N @tab
 @item @code{declare variant}: new clauses @code{adjust_args} and
-  @code{append_args} @tab N @tab
-@item @code{dispatch} construct @tab N @tab
+  @code{append_args} @tab P @tab Only @code{adjust_args}
+@item @code{dispatch} construct @tab Y @tab
 @item device-specific ICV settings with environment variables @tab Y @tab
 @item @code{assume} and @code{assumes} directives @tab Y @tab
 @item @code{nothing} directive @tab Y @tab
-- 
2.45.2



[PATCH v3 3/7] OpenMP: C front-end support for dispatch + adjust_args

2024-08-07 Thread Paul-Antoine Arras
This patch adds support to the C front-end to parse the `dispatch` construct and
the `adjust_args` clause. It also includes some common C/C++ bits for pragmas
and attributes.

Additional common C/C++ testcases are in a later patch in the series.

gcc/c-family/ChangeLog:

* c-attribs.cc (c_common_gnu_attributes): Add attribute for adjust_args
need_device_ptr.
* c-omp.cc (c_omp_directives): Uncomment dispatch.
* c-pragma.cc (omp_pragmas): Add dispatch.
* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_DISPATCH.
(enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_NOCONTEXT and
PRAGMA_OMP_CLAUSE_NOVARIANTS.

gcc/c/ChangeLog:

* c-parser.cc (c_parser_omp_dispatch): New function.
(c_parser_omp_clause_name): Handle nocontext and novariants clauses.
(c_parser_omp_clause_novariants): New function.
(c_parser_omp_clause_nocontext): Likewise.
(c_parser_omp_all_clauses): Handle nocontext and novariants clauses.
(c_parser_omp_dispatch_body): New function adapted from
c_parser_expr_no_commas.
(OMP_DISPATCH_CLAUSE_MASK): Define.
(c_parser_omp_dispatch): New function.
(c_finish_omp_declare_variant): Parse adjust_args.
(c_parser_omp_construct): Handle PRAGMA_OMP_DISPATCH.
* c-typeck.cc (c_finish_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.

gcc/testsuite/ChangeLog:

* gcc.dg/gomp/adjust-args-1.c: New test.
* gcc.dg/gomp/dispatch-1.c: New test.
---
 gcc/c-family/c-attribs.cc |   2 +
 gcc/c-family/c-omp.cc |   4 +-
 gcc/c-family/c-pragma.cc  |   1 +
 gcc/c-family/c-pragma.h   |   3 +
 gcc/c/c-parser.cc | 522 +++---
 gcc/c/c-typeck.cc |   2 +
 gcc/testsuite/gcc.dg/gomp/adjust-args-1.c |  32 ++
 gcc/testsuite/gcc.dg/gomp/dispatch-1.c|  53 +++
 libgomp/testsuite/libgomp.c/dispatch-1.c  |  76 
 libgomp/testsuite/libgomp.c/dispatch-2.c  |  84 
 10 files changed, 719 insertions(+), 60 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/gomp/adjust-args-1.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/dispatch-1.c
 create mode 100644 libgomp/testsuite/libgomp.c/dispatch-1.c
 create mode 100644 libgomp/testsuite/libgomp.c/dispatch-2.c

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 685f212683f..91a5356796d 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -562,6 +562,8 @@ const struct attribute_spec c_common_gnu_attributes[] =
  handle_omp_declare_variant_attribute, NULL },
   { "omp declare variant variant", 0, -1, true,  false, false, false,
  handle_omp_declare_variant_attribute, NULL },
+  { "omp declare variant adjust_args need_device_ptr", 0, -1, true,  false, 
false, false,
+ handle_omp_declare_variant_attribute, NULL },
   { "simd",  0, 1, true,  false, false, false,
  handle_simd_attribute, NULL },
   { "omp declare target", 0, -1, true, false, false, false,
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index b5ce1466e5d..c74a9fb2691 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -4299,8 +4299,8 @@ const struct c_omp_directive c_omp_directives[] = {
 C_OMP_DIR_DECLARATIVE, false },
   { "depobj", nullptr, nullptr, PRAGMA_OMP_DEPOBJ,
 C_OMP_DIR_STANDALONE, false },
-  /* { "dispatch", nullptr, nullptr, PRAGMA_OMP_DISPATCH,
-C_OMP_DIR_CONSTRUCT, false },  */
+  { "dispatch", nullptr, nullptr, PRAGMA_OMP_DISPATCH,
+C_OMP_DIR_DECLARATIVE, false },
   { "distribute", nullptr, nullptr, PRAGMA_OMP_DISTRIBUTE,
 C_OMP_DIR_CONSTRUCT, true },
   { "end", "assumes", nullptr, PRAGMA_OMP_END,
diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc
index 25251c2b69f..b956819c0a5 100644
--- a/gcc/c-family/c-pragma.cc
+++ b/gcc/c-family/c-pragma.cc
@@ -1526,6 +1526,7 @@ static const struct omp_pragma_def omp_pragmas[] = {
   { "cancellation", PRAGMA_OMP_CANCELLATION_POINT },
   { "critical", PRAGMA_OMP_CRITICAL },
   { "depobj", PRAGMA_OMP_DEPOBJ },
+  { "dispatch", PRAGMA_OMP_DISPATCH },
   { "error", PRAGMA_OMP_ERROR },
   { "end", PRAGMA_OMP_END },
   { "flush", PRAGMA_OMP_FLUSH },
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index 2ebde06c471..6b6826b2426 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -55,6 +55,7 @@ enum pragma_kind {
   PRAGMA_OMP_CRITICAL,
   PRAGMA_OMP_DECLARE,
   PRAGMA_OMP_DEPOBJ,
+  PRAGMA_OMP_DISPATCH,
   PRAGMA_OMP_DISTRIBUTE,
   PRAGMA_OMP_ERROR,
   PRAGMA_OMP_END,
@@ -135,9 +136,11 @@ enum pragma_omp_clause {
   PRAGMA_OMP_CLAUSE_LINK,
   PRAGMA_OMP_CLAUSE_MAP,
   PRAGMA_OMP_CLAUSE_MERGEABLE,
+  PRAGMA_OMP_CLAUSE_NOCONTEXT,
   PRAGMA_OMP_CLAUSE_NOGROUP,
   PRAGMA_OMP_CLAUSE_NONTEMPORAL,
   PRAGMA_O

[PATCH v3 6/7] OpenMP: Fortran front-end support for dispatch + adjust_args

2024-08-07 Thread Paul-Antoine Arras
This patch adds support for the `dispatch` construct and the `adjust_args`
clause to the Fortran front-end.

Handling of `adjust_args` across translation units is missing due to PR115271.

gcc/fortran/ChangeLog:

* dump-parse-tree.cc (show_omp_clauses): Handle novariants and nocontext
clauses.
(show_omp_node): Handle EXEC_OMP_DISPATCH.
(show_code_node): Likewise.
* frontend-passes.cc (gfc_code_walker): Handle novariants and nocontext.
* gfortran.h (enum gfc_statement): Add ST_OMP_DISPATCH.
(symbol_attribute): Add omp_declare_variant_need_device_ptr.
(gfc_omp_clauses): Add novariants and nocontext.
(gfc_omp_declare_variant): Add need_device_ptr_arg_list.
(enum gfc_exec_op): Add EXEC_OMP_DISPATCH.
* match.h (gfc_match_omp_dispatch): Declare.
* openmp.cc (gfc_free_omp_clauses): Free novariants and nocontext
clauses.
(gfc_free_omp_declare_variant_list): Free need_device_ptr_arg_list
namelist.
(enum omp_mask2): Add OMP_CLAUSE_NOVARIANTS and OMP_CLAUSE_NOCONTEXT.
(gfc_match_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(OMP_DISPATCH_CLAUSES): Define.
(gfc_match_omp_dispatch): New function.
(gfc_match_omp_declare_variant): Parse adjust_args.
(resolve_omp_clauses): Handle adjust_args, novariants and nocontext.
Adjust handling of OMP_LIST_IS_DEVICE_PTR.
(icode_code_error_callback): Handle EXEC_OMP_DISPATCH.
(omp_code_to_statement): Likewise.
(resolve_omp_dispatch): New function.
(gfc_resolve_omp_directive): Handle EXEC_OMP_DISPATCH.
* parse.cc (decode_omp_directive): Match dispatch.
(next_statement): Handle ST_OMP_DISPATCH.
(gfc_ascii_statement): Likewise.
(parse_omp_dispatch): New function.
(parse_executable): Handle ST_OMP_DISPATCH.
* resolve.cc (gfc_resolve_blocks): Handle EXEC_OMP_DISPATCH.
* st.cc (gfc_free_statement): Likewise.
* trans-decl.cc (create_function_arglist): Declare.
(gfc_get_extern_function_decl): Call it.
* trans-openmp.cc (gfc_trans_omp_clauses): Handle novariants and
nocontext.
(gfc_trans_omp_dispatch): New function.
(gfc_trans_omp_directive): Handle EXEC_OMP_DISPATCH.
(gfc_trans_omp_declare_variant): Handle adjust_args.
* trans.cc (trans_code): Handle EXEC_OMP_DISPATCH:.

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/declare-variant-2.f90: Update dg-error.
* gfortran.dg/gomp/declare-variant-21.f90: New test (xfail).
* gfortran.dg/gomp/declare-variant-21-aux.f90: New test.
* gfortran.dg/gomp/adjust-args-1.f90: New test.
* gfortran.dg/gomp/adjust-args-2.f90: New test.
* gfortran.dg/gomp/adjust-args-3.f90: New test.
* gfortran.dg/gomp/adjust-args-4.f90: New test.
* gfortran.dg/gomp/adjust-args-5.f90: New test.
* gfortran.dg/gomp/dispatch-1.f90: New test.
* gfortran.dg/gomp/dispatch-2.f90: New test.
* gfortran.dg/gomp/dispatch-3.f90: New test.
* gfortran.dg/gomp/dispatch-4.f90: New test.
* gfortran.dg/gomp/dispatch-5.f90: New test.
* gfortran.dg/gomp/dispatch-6.f90: New test.
* gfortran.dg/gomp/dispatch-7.f90: New test.
* gfortran.dg/gomp/dispatch-8.f90: New test.
---
 gcc/fortran/dump-parse-tree.cc|  17 ++
 gcc/fortran/frontend-passes.cc|   2 +
 gcc/fortran/gfortran.h|  11 +-
 gcc/fortran/match.h   |   1 +
 gcc/fortran/openmp.cc | 192 --
 gcc/fortran/parse.cc  |  39 +++-
 gcc/fortran/resolve.cc|   2 +
 gcc/fortran/st.cc |   1 +
 gcc/fortran/trans-decl.cc |   9 +-
 gcc/fortran/trans-openmp.cc   | 135 
 gcc/fortran/trans.cc  |   1 +
 .../gfortran.dg/gomp/adjust-args-1.f90|  58 ++
 .../gfortran.dg/gomp/adjust-args-2.f90|  18 ++
 .../gfortran.dg/gomp/adjust-args-3.f90|  27 +++
 .../gfortran.dg/gomp/adjust-args-4.f90|  58 ++
 .../gfortran.dg/gomp/adjust-args-5.f90|  58 ++
 .../gfortran.dg/gomp/declare-variant-2.f90|   6 +-
 .../gomp/declare-variant-21-aux.f90   |  25 +++
 .../gfortran.dg/gomp/declare-variant-21.f90   |  22 ++
 gcc/testsuite/gfortran.dg/gomp/dispatch-1.f90 |  77 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-2.f90 |  79 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-3.f90 |  39 
 gcc/testsuite/gfortran.dg/gomp/dispatch-4.f90 |  19 ++
 gcc/testsuite/gfortran.dg/gomp/dispatch-5.f90 |  25 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-6.f90 |  39 
 gcc/testsuite/gfortran.dg/gomp/dispatch-7.f90 |  26 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-8.f90 |  33 +++
 27 files change

[PATCH] amdgcn: Add instruction pattern for conditional shift operations

2023-02-01 Thread Paul-Antoine Arras
This patch introduces an instruction pattern for conditional shift 
operations (cond_{ashl|ashr|lshr}) in the GCN machine description.

Tested on GCN3 Fiji gfx803.

OK to commit?
--
PA
From e9c974670e8d37f725098eea97e22be5e2e9fd21 Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Wed, 1 Feb 2023 16:13:23 +0100
Subject: [PATCH] amdgcn: Add instruction pattern for conditional shift
 operations

gcc/ChangeLog:

	* config/gcn/gcn-valu.md (cond_): Add cond_{ashl|ashr|lshr}

gcc/testsuite/ChangeLog:

	* gcc.target/gcn/cond_shift_3.c: New test.
	* gcc.target/gcn/cond_shift_3_run.c: New test.
	* gcc.target/gcn/cond_shift_4.c: New test.
	* gcc.target/gcn/cond_shift_4_run.c: New test.
	* gcc.target/gcn/cond_shift_8.c: New test.
	* gcc.target/gcn/cond_shift_8_run.c: New test.
	* gcc.target/gcn/cond_shift_9.c: New test.
	* gcc.target/gcn/cond_shift_9_run.c: New test.
---
 gcc/config/gcn/gcn-valu.md| 23 +++
 gcc/testsuite/gcc.target/gcn/cond_shift_3.c   | 37 ++
 .../gcc.target/gcn/cond_shift_3_run.c | 27 +
 gcc/testsuite/gcc.target/gcn/cond_shift_4.c   | 38 +++
 .../gcc.target/gcn/cond_shift_4_run.c | 27 +
 gcc/testsuite/gcc.target/gcn/cond_shift_8.c   | 35 +
 .../gcc.target/gcn/cond_shift_8_run.c | 28 ++
 gcc/testsuite/gcc.target/gcn/cond_shift_9.c   | 36 ++
 .../gcc.target/gcn/cond_shift_9_run.c | 28 ++
 9 files changed, 279 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_3.c
 create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_3_run.c
 create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_4.c
 create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_4_run.c
 create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_8.c
 create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_8_run.c
 create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_9.c
 create mode 100644 gcc/testsuite/gcc.target/gcn/cond_shift_9_run.c

diff --git gcc/config/gcn/gcn-valu.md gcc/config/gcn/gcn-valu.md
index 44b04c222f7..47d9d87d58a 100644
--- gcc/config/gcn/gcn-valu.md
+++ gcc/config/gcn/gcn-valu.md
@@ -3489,6 +3489,29 @@ (define_expand "cond_"
 DONE;
   })
 
+(define_code_iterator cond_shiftop [ashift lshiftrt ashiftrt])
+
+(define_expand "cond_"
+  [(match_operand:V_INT_noHI 0 "register_operand")
+   (match_operand:DI 1 "register_operand")
+   (cond_shiftop:V_INT_noHI
+ (match_operand:V_INT_noHI 2 "gcn_alu_operand")
+ (match_operand:V_INT_noHI 3 "gcn_alu_operand"))
+   (match_operand:V_INT_noHI 4 "register_operand")]
+  ""
+  {
+operands[1] = force_reg (DImode, operands[1]);
+operands[2] = force_reg (mode, operands[2]);
+
+rtx shiftby = gen_reg_rtx (mode);
+convert_move (shiftby, operands[3], 0);
+
+emit_insn (gen_v3_exec (operands[0], operands[2],
+shiftby, operands[4],
+operands[1]));
+DONE;
+  })
+
 ;; }}}
 ;; {{{ Vector reductions
 
diff --git gcc/testsuite/gcc.target/gcn/cond_shift_3.c gcc/testsuite/gcc.target/gcn/cond_shift_3.c
new file mode 100644
index 000..983386c1464
--- /dev/null
+++ gcc/testsuite/gcc.target/gcn/cond_shift_3.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -dp" } */
+
+#include 
+
+#define DEF_LOOP(TYPE, NAME, OP)   \
+  void __attribute__ ((noipa)) \
+  test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a,\
+			TYPE *__restrict b, int n) \
+  {\
+for (int i = 0; i < n; ++i)\
+  r[i] = a[i] > 20 ? b[i] OP 3 : 72;   \
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, shl, <<)\
+  T (TYPE, shr, >>)
+
+#define TEST_ALL(T)\
+  TEST_TYPE (T, int32_t)   \
+  TEST_TYPE (T, uint32_t)  \
+  TEST_TYPE (T, int64_t)   \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tv_lshlrev_b32\tv[0-9]+, 3, v[0-9]+} 10 } } */
+/* { dg-final { scan-assembler-times {\tv_ashrrev_i32\tv[0-9]+, 3, v[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {vashlv64si3_exec} 18 } } */
+/* { dg-final { scan-assembler-times {vashrv64si3_exec} 1 } } */
+/* { dg-final { scan-assembler-

[PATCH] amdgcn: Support AMD-specific 'isa' traits in OpenMP context selectors

2022-11-29 Thread Paul-Antoine Arras

Hi all,

This patch adds support for 'gfx803' as an alias for 'fiji' in OpenMP 
context selectors, so as to be consistent with LLVM. It also adds test 
cases checking all supported AMD ISAs are properly recognised when used 
in a 'declare variant' construct.


Is it OK for mainline?

Thanks,
--
PAFrom 2523122f7fff806aca7f7f03109668064969aa2d Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Tue, 29 Nov 2022 16:22:07 +0100
Subject: [PATCH] amdgcn: Support AMD-specific 'isa' traits in OpenMP context
 selectors

Add support for gfx803 as an alias for fiji.
Add test cases for all supported 'isa' values.

gcc/ChangeLog:

* config/gcn/gcn.cc (gcn_omp_device_kind_arch_isa): Add gfx803.
* config/gcn/t-omp-device: Add gfx803.

libgomp/ChangeLog:

* testsuite/libgomp.c/declare-variant-4-fiji.c: New test.
* testsuite/libgomp.c/declare-variant-4-gfx803.c: New test.
* testsuite/libgomp.c/declare-variant-4-gfx900.c: New test.
* testsuite/libgomp.c/declare-variant-4-gfx906.c: New test.
* testsuite/libgomp.c/declare-variant-4-gfx908.c: New test.
* testsuite/libgomp.c/declare-variant-4-gfx90a.c: New test.
* testsuite/libgomp.c/declare-variant-4.h: New header file.
---
 gcc/config/gcn/gcn.cc |  2 +-
 gcc/config/gcn/t-omp-device   |  2 +-
 .../libgomp.c/declare-variant-4-fiji.c|  8 +++
 .../libgomp.c/declare-variant-4-gfx803.c  |  7 +++
 .../libgomp.c/declare-variant-4-gfx900.c  |  7 +++
 .../libgomp.c/declare-variant-4-gfx906.c  |  7 +++
 .../libgomp.c/declare-variant-4-gfx908.c  |  7 +++
 .../libgomp.c/declare-variant-4-gfx90a.c  |  7 +++
 .../testsuite/libgomp.c/declare-variant-4.h   | 63 +++
 9 files changed, 108 insertions(+), 2 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.c/declare-variant-4-fiji.c
 create mode 100644 libgomp/testsuite/libgomp.c/declare-variant-4-gfx803.c
 create mode 100644 libgomp/testsuite/libgomp.c/declare-variant-4-gfx900.c
 create mode 100644 libgomp/testsuite/libgomp.c/declare-variant-4-gfx906.c
 create mode 100644 libgomp/testsuite/libgomp.c/declare-variant-4-gfx908.c
 create mode 100644 libgomp/testsuite/libgomp.c/declare-variant-4-gfx90a.c
 create mode 100644 libgomp/testsuite/libgomp.c/declare-variant-4.h

diff --git gcc/config/gcn/gcn.cc gcc/config/gcn/gcn.cc
index c74fa007a21..39e93aeaeef 100644
--- gcc/config/gcn/gcn.cc
+++ gcc/config/gcn/gcn.cc
@@ -2985,7 +2985,7 @@ gcn_omp_device_kind_arch_isa (enum 
omp_device_kind_arch_isa trait,
 case omp_device_arch:
   return strcmp (name, "amdgcn") == 0 || strcmp (name, "gcn") == 0;
 case omp_device_isa:
-  if (strcmp (name, "fiji") == 0)
+  if (strcmp (name, "fiji") == 0 || strcmp (name, "gfx803") == 0)
return gcn_arch == PROCESSOR_FIJI;
   if (strcmp (name, "gfx900") == 0)
return gcn_arch == PROCESSOR_VEGA10;
diff --git gcc/config/gcn/t-omp-device gcc/config/gcn/t-omp-device
index 27d36db894b..538624f7ec7 100644
--- gcc/config/gcn/t-omp-device
+++ gcc/config/gcn/t-omp-device
@@ -1,4 +1,4 @@
 omp-device-properties-gcn: $(srcdir)/config/gcn/gcn.cc
echo kind: gpu > $@
echo arch: amdgcn gcn >> $@
-   echo isa: fiji gfx900 gfx906 gfx908 gfx90a >> $@
+   echo isa: fiji gfx803 gfx900 gfx906 gfx908 gfx90a >> $@
diff --git libgomp/testsuite/libgomp.c/declare-variant-4-fiji.c 
libgomp/testsuite/libgomp.c/declare-variant-4-fiji.c
new file mode 100644
index 000..ae2af1cc00c
--- /dev/null
+++ libgomp/testsuite/libgomp.c/declare-variant-4-fiji.c
@@ -0,0 +1,8 @@
+/* { dg-do run { target { offload_target_amdgcn } } } */
+/* { dg-skip-if "fiji/gfx803 only" { ! amdgcn-*-* } { "*" } { 
"-foffload=-march=fiji" } } */
+/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */
+
+#define USE_FIJI_FOR_GFX803
+#include "declare-variant-4.h"
+
+/* { dg-final { scan-offload-tree-dump "= gfx803 \\(\\);" "optimized" } } */
diff --git libgomp/testsuite/libgomp.c/declare-variant-4-gfx803.c 
libgomp/testsuite/libgomp.c/declare-variant-4-gfx803.c
new file mode 100644
index 000..e0437a04d65
--- /dev/null
+++ libgomp/testsuite/libgomp.c/declare-variant-4-gfx803.c
@@ -0,0 +1,7 @@
+/* { dg-do run { target { offload_target_amdgcn } } } */
+/* { dg-skip-if "fiji/gfx803 only" { ! amdgcn-*-* } { "*" } { 
"-foffload=-march=fiji" } } */
+/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */
+
+#include "declare-variant-4.h"
+
+/* { dg-final { scan-offload-tree-dump "= gfx803 \\(\\);" "optimized" } } */
diff --git libgomp/testsuite/libgomp.c/declare-variant-4-gfx900.c 
libgomp/testsuite/libgomp.c/declare-variant-4-gfx900.c
new file mo

[PATCH][OG12] amdgcn: Support AMD-specific 'isa' and 'arch' traits in OpenMP context selectors

2022-11-30 Thread Paul-Antoine Arras

Hi all,

This patch adds or fixes support for various AMD 'isa' and 'arch' trait 
selectors, so as to be consistent with LLVM. It also adds test cases 
checking all supported AMD ISAs are properly recognised when used in a 
'metadirective' construct.


This patch is closely related to 
https://gcc.gnu.org/r13-4403-g1fd508744eccda but cannot be committed to 
mainline because metadirectives and dynamic context selectors have not 
landed there yet.


Can this be committed to OG12?

Thanks,From 88522107dd39ba3ff8465cf688fe4438fa3b77b4 Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Wed, 30 Nov 2022 14:52:55 +0100
Subject: [PATCH] amdgcn: Support AMD-specific 'isa' and 'arch' traits in
 OpenMP context selectors

Add or fix libgomp support for 'amdgcn' as arch, and 'gfx908' and 'gfx90a' as 
isa traits.
Add test case for all supported 'isa' values used as context selectors in a 
metadirective construct..

libgomp/ChangeLog:

* config/gcn/selector.c (GOMP_evaluate_current_device): Recognise 
'amdgcn' as arch, and 'gfx908' and
'gfx90a' as isa traits.
* testsuite/libgomp.c-c++-common/metadirective-6.c: New test.
---
 libgomp/config/gcn/selector.c | 15 --
 .../libgomp.c-c++-common/metadirective-6.c| 48 +++
 2 files changed, 60 insertions(+), 3 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/metadirective-6.c

diff --git libgomp/config/gcn/selector.c libgomp/config/gcn/selector.c
index 60793fc05d3..c948497c538 100644
--- libgomp/config/gcn/selector.c
+++ libgomp/config/gcn/selector.c
@@ -36,7 +36,7 @@ GOMP_evaluate_current_device (const char *kind, const char 
*arch,
   if (kind && strcmp (kind, "gpu") != 0)
 return false;
 
-  if (arch && strcmp (arch, "gcn") != 0)
+  if (arch && (strcmp (arch, "gcn") != 0 || strcmp (arch, "amdgcn") != 0))
 return false;
 
   if (!isa)
@@ -48,8 +48,17 @@ GOMP_evaluate_current_device (const char *kind, const char 
*arch,
 #endif
 
 #ifdef __GCN5__
-  if (strcmp (isa, "gfx900") == 0 || strcmp (isa, "gfx906") != 0
-  || strcmp (isa, "gfx908") == 0)
+  if (strcmp (isa, "gfx900") == 0 || strcmp (isa, "gfx906") != 0)
+return true;
+#endif
+
+#ifdef __CDNA1__
+  if (strcmp (isa, "gfx908") == 0)
+return true;
+#endif
+
+#ifdef __CDNA2__
+  if (strcmp (isa, "gfx90a") == 0)
 return true;
 #endif
 
diff --git libgomp/testsuite/libgomp.c-c++-common/metadirective-6.c 
libgomp/testsuite/libgomp.c-c++-common/metadirective-6.c
new file mode 100644
index 000..6d169001db1
--- /dev/null
+++ libgomp/testsuite/libgomp.c-c++-common/metadirective-6.c
@@ -0,0 +1,48 @@
+/* { dg-do link { target { offload_target_amdgcn } } } */
+/* { dg-additional-options "-foffload=-fdump-tree-omp_expand_metadirective" } 
*/
+
+#define N 100
+
+void f (int x[], int y[], int z[])
+{
+  int i;
+
+  #pragma omp target map(to: x, y) map(from: z)
+#pragma omp metadirective \
+  when (device={isa("gfx803")}: teams num_teams(512)) \
+  when (device={isa("gfx900")}: teams num_teams(256)) \
+  when (device={isa("gfx906")}: teams num_teams(128)) \
+  when (device={isa("gfx908")}: teams num_teams(64)) \
+  when (device={isa("gfx90a")}: teams num_teams(32)) \
+  default (teams num_teams(4))
+   for (i = 0; i < N; i++)
+ z[i] = x[i] * y[i];
+}
+
+int main (void)
+{
+  int x[N], y[N], z[N];
+  int i;
+
+  for (i = 0; i < N; i++)
+{
+  x[i] = i;
+  y[i] = -i;
+}
+
+  f (x, y, z);
+
+  for (i = 0; i < N; i++)
+if (z[i] != x[i] * y[i])
+  return 1;
+
+  return 0;
+}
+
+/* The metadirective should be resolved after Gimplification.  */
+
+/* { dg-final { scan-offload-tree-dump "__builtin_GOMP_teams4 \\(512, 512" 
"omp_expand_metadirective" { target { any-opts "-foffload=-march=fiji" } } } } 
*/
+/* { dg-final { scan-offload-tree-dump "__builtin_GOMP_teams4 \\(256, 256" 
"omp_expand_metadirective" { target { any-opts "-foffload=-march=gfx900" } } } 
} */
+/* { dg-final { scan-offload-tree-dump "__builtin_GOMP_teams4 \\(128, 128" 
"omp_expand_metadirective" { target { any-opts "-foffload=-march=gfx906" } } } 
} */
+/* { dg-final { scan-offload-tree-dump "__builtin_GOMP_teams4 \\(64, 64" 
"omp_expand_metadirective" { target { any-opts "-foffload=-march=gfx908" } } } 
} */
+/* { dg-final { scan-offload-tree-dump "__builtin_GOMP_teams4 \\(32, 32" 
"omp_expand_metadirective" { target { any-opts "-foffload=-march=gfx90a" } } } 
} */
-- 
2.31.1



Re: [PATCH][OG12] amdgcn: Support AMD-specific 'isa' and 'arch' traits in OpenMP context selectors

2022-12-01 Thread Paul-Antoine Arras

Hi Kwok,

On 30/11/2022 19:50, Kwok Cheung Yeung wrote:

Hello PA,


--- libgomp/config/gcn/selector.c
+++ libgomp/config/gcn/selector.c
@@ -36,7 +36,7 @@ GOMP_evaluate_current_device (const char *kind, 
const char *arch,

   if (kind && strcmp (kind, "gpu") != 0)
 return false;

-  if (arch && strcmp (arch, "gcn") != 0)
+  if (arch && (strcmp (arch, "gcn") != 0 || strcmp (arch, "amdgcn") 
!= 0))

 return false;


The logic here looks wrong to me - surely it should return false if arch 
is not 'gcn' AND it is not 'amdgcn'?


Sure. Fixed in revised patch.

@@ -48,8 +48,17 @@ GOMP_evaluate_current_device (const char *kind, 
const char *arch,

 #endif

 #ifdef __GCN5__
-  if (strcmp (isa, "gfx900") == 0 || strcmp (isa, "gfx906") != 0
-  || strcmp (isa, "gfx908") == 0)
+  if (strcmp (isa, "gfx900") == 0 || strcmp (isa, "gfx906") != 0)
+    return true;
+#endif
+
+#ifdef __CDNA1__
+  if (strcmp (isa, "gfx908") == 0)
+    return true;
+#endif
+
+#ifdef __CDNA2__
+  if (strcmp (isa, "gfx90a") == 0)
 return true;
 #endif


Okay for gfx908 and gfx90a, but is there any way of distinguishing 
between 'gfx900' and 'gfx906' ISAs? I don't think these are mutually 
compatible.




Since I did not find any existing builtin to check the exact ISA, I 
added all of them for consistency. Let me know if that looks good to you.


Thanks,
--
PAFrom f846292d2ce953a633fe400226277cf0cb0d6243 Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Wed, 30 Nov 2022 14:52:55 +0100
Subject: [PATCH] amdgcn: Support AMD-specific 'isa' and 'arch' traits in
 OpenMP context selectors

Add or fix libgomp support for 'amdgcn' as arch, and 'gfx908' and 'gfx90a' as 
isa traits.
Add test case for all supported 'isa' values used as context selectors in a 
metadirective construct.

libgomp/ChangeLog:

* config/gcn/selector.c (GOMP_evaluate_current_device): Recognise 
'amdgcn' as arch, and 'gfx908' and
'gfx90a' as isa traits.
* testsuite/libgomp.c-c++-common/metadirective-6.c: New test.
---
 gcc/config/gcn/gcn-opts.h |  6 +++
 gcc/config/gcn/gcn.h  | 37 --
 libgomp/config/gcn/selector.c | 24 --
 .../libgomp.c-c++-common/metadirective-6.c| 48 +++
 4 files changed, 96 insertions(+), 19 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/metadirective-6.c

diff --git gcc/config/gcn/gcn-opts.h gcc/config/gcn/gcn-opts.h
index 07ddc79cda3..fb7e5d9a5e9 100644
--- gcc/config/gcn/gcn-opts.h
+++ gcc/config/gcn/gcn-opts.h
@@ -27,6 +27,12 @@ enum processor_type
   PROCESSOR_GFX90a
 };
 
+#define TARGET_FIJI (gcn_arch == PROCESSOR_FIJI)
+#define TARGET_VEGA10 (gcn_arch == PROCESSOR_VEGA10)
+#define TARGET_VEGA20 (gcn_arch == PROCESSOR_VEGA20)
+#define TARGET_GFX908 (gcn_arch == PROCESSOR_GFX908)
+#define TARGET_GFX90a (gcn_arch == PROCESSOR_GFX90a)
+
 /* Set in gcn_option_override.  */
 extern enum gcn_isa {
   ISA_UNKNOWN,
diff --git gcc/config/gcn/gcn.h gcc/config/gcn/gcn.h
index 38f7212db59..22a95ba6609 100644
--- gcc/config/gcn/gcn.h
+++ gcc/config/gcn/gcn.h
@@ -16,20 +16,29 @@
 
 #include "config/gcn/gcn-opts.h"
 
-#define TARGET_CPU_CPP_BUILTINS()  \
-  do   \
-{  \
-  builtin_define ("__AMDGCN__");   \
-  if (TARGET_GCN3) \
-   builtin_define ("__GCN3__");\
-  else if (TARGET_GCN5)\
-   builtin_define ("__GCN5__");\
-  else if (TARGET_CDNA1)   \
-   builtin_define ("__CDNA1__");   \
-  else if (TARGET_CDNA2)   \
-   builtin_define ("__CDNA2__");   \
-}  \
-  while(0)
+#define TARGET_CPU_CPP_BUILTINS()  
\
+  do   
\
+{  
\
+  builtin_define ("__AMDGCN__");   
\
+  if (TARGET_GCN3) 
\
+   builtin_define ("__GCN3__");   \
+  else if (TARGET_GCN5)
\
+   builtin_define ("__GCN5__");   \
+  else if (TARGET_CDNA1)   
\
+   builtin_define ("__CDNA1__");  \
+  else if (TARGET_CDNA2)   

[PATCH] amdgcn: Add preprocessor builtins for every processor type

2022-12-01 Thread Paul-Antoine Arras

Hi Andrew, all,
On 01/12/2022 13:45, Andrew Stubbs wrote:

On 01/12/2022 11:10, Paul-Antoine Arras wrote:
+  if 
(TARGET_FIJI) \
+    builtin_define 
("__FIJI__");   \
+  else if 
(TARGET_VEGA10)  \
+    builtin_define 
("__VEGA10__"); \
+  else if 
(TARGET_VEGA20)  \
+    builtin_define 
("__VEGA20__"); \
+  else if 
(TARGET_GFX908)  \
+    builtin_define 
("__GFX908__"); \
+  else if 
(TARGET_GFX90a)  \
+    builtin_define 
("__GFX90a__"); \

+  } while (0)



I don't think it makes sense to say __VEGA10__ when the user asked for 
-march=gfx900.


This whole naming thing is a bit of a mess already, so I think we'd do 
better to either keep the same names throughout or match what LLVM does 
(since it got to these first).


Please use "__gfx900__" etc. (lower case).

[...]

P.S. If you want to split the patch into the GCN bits and the bits that 
depend on metadirectives then we can apply the first part to mainline 
right away.


I believe this patch addresses your comments regarding the GCN bits.

The new builtins are consistent with the LLVM naming convention (lower 
case, canonical name). For gfx803, I also kept '__fiji__' to be 
consistent with -march=fiji.


Is it OK for mainline?

Thanks,
--
PAFrom 238e8e131741fc962fe87482d1e9a6eb1252c75c Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Thu, 1 Dec 2022 15:09:54 +0100
Subject: [PATCH] amdgcn: Add preprocessor builtins for every processor type

Provide a specific builtin for each possible value of '-march'.

gcc/ChangeLog:

* config/gcn/gcn-opts.h (TARGET_FIJI): -march=fiji.
(TARGET_VEGA10): -march=gfx900.
(TARGET_VEGA20): -march=gfx906.
(TARGET_GFX908): -march=gfx908.
(TARGET_GFX90a): -march=gfx90a.
* config/gcn/gcn.h (TARGET_CPU_CPP_BUILTINS): Define a builtin that 
uniquely maps to '-march'.
---
 gcc/config/gcn/gcn-opts.h |  6 ++
 gcc/config/gcn/gcn.h  | 40 +--
 2 files changed, 32 insertions(+), 14 deletions(-)

diff --git gcc/config/gcn/gcn-opts.h gcc/config/gcn/gcn-opts.h
index b62dfb45f59..b54eae79faf 100644
--- gcc/config/gcn/gcn-opts.h
+++ gcc/config/gcn/gcn-opts.h
@@ -27,6 +27,12 @@ enum processor_type
   PROCESSOR_GFX90a
 };
 
+#define TARGET_FIJI (gcn_arch == PROCESSOR_FIJI)
+#define TARGET_VEGA10 (gcn_arch == PROCESSOR_VEGA10)
+#define TARGET_VEGA20 (gcn_arch == PROCESSOR_VEGA20)
+#define TARGET_GFX908 (gcn_arch == PROCESSOR_GFX908)
+#define TARGET_GFX90a (gcn_arch == PROCESSOR_GFX90a)
+
 /* Set in gcn_option_override.  */
 extern enum gcn_isa {
   ISA_UNKNOWN,
diff --git gcc/config/gcn/gcn.h gcc/config/gcn/gcn.h
index 38f7212db59..1cc5981d904 100644
--- gcc/config/gcn/gcn.h
+++ gcc/config/gcn/gcn.h
@@ -16,20 +16,32 @@
 
 #include "config/gcn/gcn-opts.h"
 
-#define TARGET_CPU_CPP_BUILTINS()  \
-  do   \
-{  \
-  builtin_define ("__AMDGCN__");   \
-  if (TARGET_GCN3) \
-   builtin_define ("__GCN3__");\
-  else if (TARGET_GCN5)\
-   builtin_define ("__GCN5__");\
-  else if (TARGET_CDNA1)   \
-   builtin_define ("__CDNA1__");   \
-  else if (TARGET_CDNA2)   \
-   builtin_define ("__CDNA2__");   \
-}  \
-  while(0)
+#define TARGET_CPU_CPP_BUILTINS()  
\
+  do   
\
+{  
\
+  builtin_define ("__AMDGCN__");   
\
+  if (TARGET_GCN3) 
\
+   builtin_define ("__GCN3__");   \
+  else if (TARGET_GCN5)
\
+   builtin_define ("__GCN5__");   \
+  else if (TARGET_CDNA1)   
\
+   builtin_define ("__CDNA1__");  \
+  else if (TARGET_CDNA2)   
\
+   builtin_define ("__CDNA2__"); 

Re: [PATCH][OG12] amdgcn: Support AMD-specific 'isa' and 'arch' traits in OpenMP context selectors

2022-12-01 Thread Paul-Antoine Arras

On 01/12/2022 13:45, Andrew Stubbs wrote:
P.S. If you want to split the patch into the GCN bits and the bits that 
depend on metadirectives then we can apply the first part to mainline 
right away.


So this is the OG12-specific part (including metadirective and dynamic 
context selectors) of the previous patch.


Once https://gcc.gnu.org/r13-4446-ge41b243302e996 is backported, is it 
OK for OG12?


Thanks,
--
PAFrom 494a815af459b13da6fe9bf5a84b94d4b1f94915 Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Wed, 30 Nov 2022 14:52:55 +0100
Subject: [PATCH] amdgcn: Support AMD-specific 'isa' and 'arch' traits in
 OpenMP context selectors

Add libgomp support for 'amdgcn' as arch, and for each processor type (as passed
to '-march') as isa traits.
Add test case for all supported 'isa' values used as context selectors in a
metadirective construct.

libgomp/ChangeLog:

* config/gcn/selector.c (GOMP_evaluate_current_device): Recognise 
'amdgcn'
as arch, and '-march' values (as well as 'gfx803') as isa traits.
* testsuite/libgomp.c-c++-common/metadirective-6.c: New test.
---
 libgomp/ChangeLog.omp |  6 +++
 libgomp/config/gcn/selector.c | 24 --
 .../libgomp.c-c++-common/metadirective-6.c| 48 +++
 3 files changed, 73 insertions(+), 5 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/metadirective-6.c

diff --git libgomp/ChangeLog.omp libgomp/ChangeLog.omp
index 74053a6eea0..a2f03914725 100644
--- libgomp/ChangeLog.omp
+++ libgomp/ChangeLog.omp
@@ -1,3 +1,9 @@
+2022-12-01  Paul-Antoine Arras 
+
+   * config/gcn/selector.c (GOMP_evaluate_current_device): Recognise 
'amdgcn'
+   as arch, and '-march' values (as well as 'gfx803') as isa traits.
+   * testsuite/libgomp.c-c++-common/metadirective-6.c: New test.
+
 2022-11-30  Tobias Burnus  
 
Backported from master:
diff --git libgomp/config/gcn/selector.c libgomp/config/gcn/selector.c
index 60793fc05d3..570bc1e8ae6 100644
--- libgomp/config/gcn/selector.c
+++ libgomp/config/gcn/selector.c
@@ -36,20 +36,34 @@ GOMP_evaluate_current_device (const char *kind, const char 
*arch,
   if (kind && strcmp (kind, "gpu") != 0)
 return false;
 
-  if (arch && strcmp (arch, "gcn") != 0)
+  if (arch && (strcmp (arch, "gcn") != 0 && strcmp (arch, "amdgcn") != 0))
 return false;
 
   if (!isa)
 return true;
 
-#ifdef __GCN3__
+#ifdef __gfx803__
   if (strcmp (isa, "fiji") == 0 || strcmp (isa, "gfx803") == 0)
 return true;
 #endif
 
-#ifdef __GCN5__
-  if (strcmp (isa, "gfx900") == 0 || strcmp (isa, "gfx906") != 0
-  || strcmp (isa, "gfx908") == 0)
+#ifdef __gfx900__
+  if (strcmp (isa, "gfx900") == 0)
+return true;
+#endif
+
+#ifdef __gfx906__
+  if (strcmp (isa, "gfx906") == 0)
+return true;
+#endif
+
+#ifdef __gfx908__
+  if (strcmp (isa, "gfx908") == 0)
+return true;
+#endif
+
+#ifdef __gfx90a__
+  if (strcmp (isa, "gfx90a") == 0)
 return true;
 #endif
 
diff --git libgomp/testsuite/libgomp.c-c++-common/metadirective-6.c 
libgomp/testsuite/libgomp.c-c++-common/metadirective-6.c
new file mode 100644
index 000..6d169001db1
--- /dev/null
+++ libgomp/testsuite/libgomp.c-c++-common/metadirective-6.c
@@ -0,0 +1,48 @@
+/* { dg-do link { target { offload_target_amdgcn } } } */
+/* { dg-additional-options "-foffload=-fdump-tree-omp_expand_metadirective" } 
*/
+
+#define N 100
+
+void f (int x[], int y[], int z[])
+{
+  int i;
+
+  #pragma omp target map(to: x, y) map(from: z)
+#pragma omp metadirective \
+  when (device={isa("gfx803")}: teams num_teams(512)) \
+  when (device={isa("gfx900")}: teams num_teams(256)) \
+  when (device={isa("gfx906")}: teams num_teams(128)) \
+  when (device={isa("gfx908")}: teams num_teams(64)) \
+  when (device={isa("gfx90a")}: teams num_teams(32)) \
+  default (teams num_teams(4))
+   for (i = 0; i < N; i++)
+ z[i] = x[i] * y[i];
+}
+
+int main (void)
+{
+  int x[N], y[N], z[N];
+  int i;
+
+  for (i = 0; i < N; i++)
+{
+  x[i] = i;
+  y[i] = -i;
+}
+
+  f (x, y, z);
+
+  for (i = 0; i < N; i++)
+if (z[i] != x[i] * y[i])
+  return 1;
+
+  return 0;
+}
+
+/* The metadirective should be resolved after Gimplification.  */
+
+/* { dg-final { scan-offload-tree-dump "__builtin_GOMP_teams4 \\(512, 512" 
"omp_expand_metadirective" { target { any-opts "-foffload=-march=fiji" } } } } 
*/
+/* { dg-final { scan-offload-tree-dump "__builtin_GOMP_teams4 \\(256, 256" 
"omp_expand_metadirective" { target { any-opts "-foffload=-march=gfx900&q

Re: [PATCH v4 3/7] OpenMP: C front-end support for dispatch + adjust_args

2024-10-23 Thread Paul-Antoine Arras

Here is an updated patch following these comments.

On 09/10/2024 19:15, Tobias Burnus wrote:
First comments; I need to have a deeper, but now I need fetch some 
victuals.


Paul-Antoine Arras wrote:
This patch adds support to the C front-end to parse the `dispatch` 
construct and
the `adjust_args` clause. It also includes some common C/C++ bits for 
pragmas

and attributes.

Additional common C/C++ testcases are in a later patch in the series.


. . .


--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -571,6 +571,8 @@ const struct attribute_spec 
c_common_gnu_attributes[] =

    handle_omp_declare_variant_attribute, NULL },
    { "omp declare variant variant", 0, -1, true,  false, false, false,
    handle_omp_declare_variant_attribute, NULL },
+  { "omp declare variant adjust_args need_device_ptr", 0, -1, true,  
false, false, false,

+  handle_omp_declare_variant_attribute, NULL },


the first line is 9 characters too long ...


Fixed wrapping.


--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -1747,6 +1747,8 @@ static void c_parser_omp_assumption_clauses 
(c_parser *, bool);

  static void c_parser_omp_allocate (c_parser *);
  static void c_parser_omp_assumes (c_parser *);
  static bool c_parser_omp_ordered (c_parser *, enum pragma_context, 
bool *);

+static tree
+c_parser_omp_dispatch (location_t, c_parser *);


Spurious line break after 'tree' in the declaration.


Fixed line break.


+// Adapted from c_parser_expr_no_commas


While parts of GCC have started to use // comments of C++ and C99,
this file seemingly hasn't and I am not sure that you want to be the
first one to adds it ...

I think this needs some words on the purpose of this function,
i.e. why it exists - alias what syntax it support and does not
support.


Updated comment.


+static tree
+c_parser_omp_dispatch_body (c_parser *parser)
+{


...


+  lhs = c_parser_conditional_expression (parser, NULL, NULL);
+  if (TREE_CODE (lhs.value) == CALL_EXPR)
+    return lhs.value;
+  else
+    {


You can save on indentation and curly braces by removing the 'else {'
as after the 'return' you never need to handle the CALL_EXPR case.


Right! Removed the else.


+  location_t op_location = c_parser_peek_token (parser)->location;
+  if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
+    return error_mark_node;
+
+  /* Parse function name*/


(Possibly a '.' and then) two spaces before '*/'.


Fixed this and similar comments.


+    for (int i = 0; i < 3; i++)
+  {
+    sizeof_arg[i] = NULL_TREE;
+    sizeof_arg_loc[i] = UNKNOWN_LOCATION;


Wrong size: c_parser_expr_list expects that 6 not 3 values exist.


Changed loop upper bound.


Looks as if your code predates Jakub's change of Dec 2023:
r14-6741-ge7dd72aefed851  Split -Wcalloc-transposed-args warning from - 
Walloc-size, -Walloc-size fixes


Tobias


Thanks,
--
PAcommit 45357fe512876099f1c35c5c5b3b278ceecfda58
Author: Paul-Antoine Arras 
Date:   Fri May 24 17:28:55 2024 +0200

OpenMP: C front-end support for dispatch + adjust_args

This patch adds support to the C front-end to parse the `dispatch` construct and
the `adjust_args` clause. It also includes some common C/C++ bits for pragmas
and attributes.

Additional common C/C++ testcases are in a later patch in the series.

gcc/c-family/ChangeLog:

* c-attribs.cc (c_common_gnu_attributes): Add attribute for adjust_args
need_device_ptr.
* c-omp.cc (c_omp_directives): Uncomment dispatch.
* c-pragma.cc (omp_pragmas): Add dispatch.
* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_DISPATCH.
(enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_NOCONTEXT and
PRAGMA_OMP_CLAUSE_NOVARIANTS.

gcc/c/ChangeLog:

* c-parser.cc (c_parser_omp_dispatch): New function.
(c_parser_omp_clause_name): Handle nocontext and novariants clauses.
(c_parser_omp_clause_novariants): New function.
(c_parser_omp_clause_nocontext): Likewise.
(c_parser_omp_all_clauses): Handle nocontext and novariants clauses.
(c_parser_omp_dispatch_body): New function adapted from
c_parser_expr_no_commas.
(OMP_DISPATCH_CLAUSE_MASK): Define.
(c_parser_omp_dispatch): New function.
(c_finish_omp_declare_variant): Parse adjust_args.
(c_parser_omp_construct): Handle PRAGMA_OMP_DISPATCH.
* c-typeck.cc (c_finish_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.

gcc/testsuite/ChangeLog:

* gcc.dg/gomp/adjust-args-1.c: New test.
* gcc.dg/gomp/dispatch-1.c: New test.

diff --git gcc/c-family/c-attribs.cc gcc/c-family/c-attribs.cc
index 4dd2eecbea5..c4c71ea75

Re: [PATCH v4 2/7] OpenMP: middle-end support for dispatch + adjust_args

2024-10-22 Thread Paul-Antoine Arras

Hi Tobias,

Thanks for your thorough review. Please find attached a revised patch.

On 09/10/2024 14:55, Tobias Burnus wrote:

Paul-Antoine Arras wrote:

This patch adds middle-end support for the `dispatch` construct and the
`adjust_args` clause. The heavy lifting is done in 
`gimplify_omp_dispatch` and
`gimplify_call_expr` respectively. For `adjust_args`, this mostly 
consists in

emitting a call to `gomp_get_mapped_ptr` for the adequate device.


omp_get_… not gomp_get_…


Fixed.


For dispatch, the following steps are performed:

* Handle the device clause, if any: set the default-device ICV at the 
top of the

dispatch region and restore its previous value at the end.

* Handle novariants and nocontext clauses, if any. Evaluate compile-time
constants and select a variant, if possible. Otherwise, emit code to 
handle all

possible cases at run time.

* If depend clauses are present, add a taskwait construct before the 
dispatch

region and move them there.


The latter is not done here – but already in the front ends, i.e. 
OMP_TASK are handled in part 3 (C), 4 (C++) and 6 (Fortran) of this series.


Forgot to move that during a previous iteration. Fixed now.


...


--- a/gcc/gimple.cc
+++ b/gcc/gimple.cc


...


+/* Build a GIMPLE_OMP_DISPATCH statement.
+
+   BODY is the target function call to be dispatched.
+   CLAUSES are any of the OMP dispatch construct's clauses: ...  */


Looks as if you planned to add something here. How about:
s/: ..././ ?


Right, fixed.



@@ -4067,23 +4069,125 @@ gimplify_call_expr (tree *expr_p, gimple_seq 
*pre_p, bool want_value)



+  if (flag_openmp && EXPR_P (CALL_EXPR_FN (*expr_p))
+  && DECL_P (TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0))
+  && (adjust_args_list = lookup_attribute (
+    "omp declare variant variant adjust_args",
+    DECL_ATTRIBUTES (
+  TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0
+   != NULL_TREE
+  && gimplify_omp_ctxp != NULL
+  && gimplify_omp_ctxp->code == OMP_DISPATCH
+  && !gimplify_omp_ctxp->in_call_args)
+    {


!= should be under 'a' of 'adjust (remove one space)


clang-format is consistently doing it wrong... I have to be careful and 
fix it manually.


And I wonder whether it is a bit more readable and a tiny bit faster if 
you move the gimplify_omp_ctx checks directly after flag_openmp

and only if successfull ('&&') check for the attributes.


Agreed!


+  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
+    {
+  tree decl1 = DECL_NAME (OMP_CLAUSE_DECL (c));
+  tree decl2 = tree_strip_nop_conversions (*arg_p);
+  if (TREE_CODE (decl2) == ADDR_EXPR)
+    decl2 = TREE_OPERAND (decl2, 0);
+  gcc_assert (TREE_CODE (decl2) == VAR_DECL
+  || TREE_CODE (decl2) == PARM_DECL);


The first one can be 'VAR_P (decl2)'. I keep wondering whether there


Changed.


can be cases where that's not true (e.g. VAR_DECL) or some indirect ref.


I don't remember running into such case. I think this is here just for 
extra safety.



For Fortran, I could imagine that array descriptors make problems, e.g.

subroutine f(x)
   integer, pointer :: x(:)

where 'x->data' is the device pointer and not 'x'.

(TODO: something to check + possibly to revisite when handling the 
Fortran part; for now (including C/C++), I think we can leave it as is.)


Or something with reference types (→ C++, Fortran), albeit that's more 
for need_device_addr / has_device_addr, which is not yet implemeted.



+  bool need_device_ptr = false;
+  for (tree arg
+   = TREE_PURPOSE (TREE_VALUE (adjust_args_list));
+   arg != NULL; arg = TREE_CHAIN (arg))
+    {


...


+    }
+
+  if (need_device_ptr && !is_device_ptr)


Actually, the is_device_ptr loop is only needed when need_device_ptr 
(or, later, need_device_addr) is true; I wonder whether it should be 
swapped and is_device_ptr only be checked conditionally?


Good point! Changed as suggested.


+  *arg_p = (TREE_CODE (*arg_p) == NOP_EXPR)
+ ? TREE_OPERAND (*arg_p, 0)
+ : *arg_p;


Use tree_strip_nop_conversions or STRIP_NOPS ? However, it is not clear 
why it is needed here ...


Correct, it is not needed here. Removed.


+  gimplify_arg (arg_p, pre_p, loc);
+  gimplify_arg (&device_num, pre_p, loc);
+  call = gimple_build_call (fn, 2, *arg_p, device_num);
+  tree mapped_arg
+    = create_tmp_var (gimple_call_return_type (call));
+  gimple_call_set_lhs (call, mapped_arg);
+  gimplify_seq_add_stmt (pre_p, call);
+
+  *arg_p = mapp

Re: [PATCH v4 3/7] OpenMP: C front-end support for dispatch + adjust_args

2024-10-30 Thread Paul-Antoine Arras

On 24/10/2024 13:42, Tobias Burnus wrote:

Hi,

some more comments:

Paul-Antoine Arras wrote:

Here is an updated patch following these comments.
 gcc/testsuite/ChangeLog:
 
 * gcc.dg/gomp/adjust-args-1.c: New test.

 * gcc.dg/gomp/dispatch-1.c: New test.


The ChangeLog misses to include libgomp/testsuite/libgomp.c/dispatch-1.c 
and libgomp/testsuite/libgomp.c/dispatch-2.c, which are part of this patch.


But there is reason to move them to 5/7: I think we also need a run test 
for C++ to make sure that it works, i.e. moving them to libgomp.c-c++- 
common/ makes sense, which in turn requires the 4/7 C++ FE patch.


Agreed. That's actually what I did in my local tree but forgot to move 
it to the right commit.



* * *


+/* Parse a function dispatch structured block:
+
+lvalue-expression = target-call ( [expression-list] );
+or
+target-call ( [expression-list] );
+
+   Adapted from c_parser_expr_no_commas.
+*/


Can you expand the description, e.g. like:

Adapted from c_parser_expr_no_commas and
c_parser_postfix_expression (CPP_NAME/C_ID_ID) for the
function name).


Done.


And:


+static tree
+c_parser_omp_dispatch_body (c_parser *parser)
+{

...

+  /* Parse function name.  */
+  if (!c_parser_next_token_is (parser, CPP_NAME))
+{
+  c_parser_error (parser, "expected a function name");
+  rhs.set_error ();
+  return rhs.value;
+}
+  expr_loc = c_parser_peek_token (parser)->location;
+  tree id = c_parser_peek_token (parser)->value;
+  c_parser_consume_token (parser);
+  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+return error_mark_node;
+
+  rhs.value = build_external_ref (expr_loc, id, true, &rhs.original_type);
+  set_c_expr_source_range (&rhs, tok_range);
+  /* Parse argument list.  */


Wouldn't it be way easier and future proof (less code duplication)
to just do the following:

Note:
* rhs.set_error() / return rhs.value; → error_mark_node;
* 'c_parser_require (parser, CPP_OPEN_PAREN' → c_parser_next_token_is
* And then checking that the returned code is the expected CALL.

   /* Parse function name.  */
   if (!c_parser_next_token_is (parser, CPP_NAME))
 {
   c_parser_error (parser, "expected a function name");
   return error_mark_node;
 }
   expr_loc = c_parser_peek_token (parser)->location;
   tree id = c_parser_peek_token (parser)->value;
   c_parser_consume_token (parser);
   if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN))
 {
   c_parser_error (parser, "expected a function name");
   return error_mark_node;
 }

   rhs.value = build_external_ref (expr_loc, id, true, &rhs.original_type);
   set_c_expr_source_range (&rhs, tok_range);
   
   /* Parse argument list.  */

   rhs = c_parser_postfix_expression_after_primary
 (parser, EXPR_LOC_OR_LOC (rhs.value, expr_loc), rhs);
   if (TREE_CODE (lhs.value) != CALL_EXPR)
 {
   error_at (EXPR_LOC_OR_LOC (rhs.value, expr_loc),
 "expected target-function call");
   return error_mark_node;
 }


Yes, much better indeed!


* * *

Testing it shows then the following error:

dispatch3.c:11:13: Fehler: expected target-function call
11 |x = bar()[0];
   |~^~~

which seems to be reasonable.

* * *


  #define OMP_DECLARE_SIMD_CLAUSE_MASK  \
@@ -25242,77 +25512,223 @@ c_finish_omp_declare_variant (c_parser *parser, tree 
fndecl, tree parms)


[...]

The old code did:

tree ctx = c_parser_omp_context_selector_specification (parser, parms); 
if (ctx == error_mark_node) goto fail; ctx = omp_check_context_selector 
(match_loc, ctx); if (ctx != error_mark_node && variant != 
error_mark_node) { if (TREE_CODE (variant) != FUNCTION_DECL)


i.e. it effectively finished parsing (except for the ')', then checks 
the context selector and, finally, the variant declaration. The new code 
is similar, except that the variant declaration check is inside the 
'match(…)' check – and missing this when processing 'adjust_args'. 
Either all parsing needs to happen before this - or the handling needs 
to be be but next to the relative item. NOTE: You need to ensure that 
the location is still okay if you move the checking after parsing. * * * 


Added a check for error_mark after parsing, just before the list loop.

As mentioned in the older 2/7 review, this will fail (ICE) if the 
variant has issues (e.g. variant function not declared) as the adjust- 
args code assumes that it is valid. → testcase in that email (+ some off 
list communication) * * * As mentioned off list, the following fails as well:


void variant_fn();  // Assume C < C23; in C++/C23 it becomes the same as 
'…(void)'.

#pragma omp declare variant(variant_fn) match(construct={dispatch}) 
adjust_args(need_device_ptr: x,y)
void bar(int *x,

Re: [PATCH v4 3/7] OpenMP: C front-end support for dispatch + adjust_args

2024-10-30 Thread Paul-Antoine Arras

On 30/10/2024 15:08, Tobias Burnus wrote:
I still need to look at 4/7 (C++) and 5/7 (tests for C and C++) [either 
before after you posted the new version].


I sent a revised C++ patch a few moments ago.


* * *

However, this 3/7 patch LGTM 🙂

One comment: For the < C23 testcase, can you add, e.g., -std=gnu17 ? The 
reason is that Joseph plans to switch to -std=gnu23 by default and 
already modified existing testcases, e.g. r15-4391-g9fb5348e302102 
"testsuite: Prepare for -std=gnu23 default" – and https://gcc.gnu.org/ 
pipermail/gcc-patches/2024-October/665612.html


Done.


* * *

In summary, Patches 1 to 3 are now approved 🙂

For 2, I expect a follow that for a known NULL ptr value (0L, nullptr, 
(void*)0L, absent argument in Fortran, absent argument in C++ with '= 
NULL/nullptr' parameter default), the need_device_ptr conversion will 
skip the __builtin_omp_get_mapped_ptr call (at is will just return 
NULL); but that can be done later 🙂 [Cf. also my comment to the 4/7 
patch.]


I attached an updated ME patch along with the C++ patch.
--
PA


Re: [PATCH v4 4/7] OpenMP: C++ front-end support for dispatch + adjust_args

2024-10-30 Thread Paul-Antoine Arras

On 24/10/2024 16:10, Tobias Burnus wrote:

Hi PA;

only playing around quickly and glancing at the patch; I need to have a
real look at this later.

Paul-Antoine Arras:
This patch adds C++ support for the `dispatch` construct and the 
`adjust_args`
clause. It relies on the c-family bits comprised in the corresponding 
C front

end patch for pragmas and attributes.


Regarding the parsing, I am wondering whether you could do the same as
proposed for the C parser, i.e. instead of swallowing '(' just checking
whether it is there - and then call the normaler parser, followed by 
checking that it is only the call and not expressions involving that call.


In C++, there is no equivalent to 
c_parser_postfix_expression_after_primary. So I am now calling 
cp_parser_postfix_expression, which parses not only the argument list 
but the whole function call.



* * *

Starting with playing around a bit:

int variant_fn(int *, int * = nullptr);

#pragma omp declare variant(variant_fn) match(construct={dispatch}) 
adjust_args(need_device_ptr : x, y)

int bar(int *x, int *y = nullptr);

void sub(int *a, int *b)
{
   int x;
   #pragma omp dispatch
    x = bar(a);
}

     D.2973 = __builtin_omp_get_default_device ();
     D.2974 = __builtin_omp_get_mapped_ptr (0B, D.2973);
     D.2975 = __builtin_omp_get_mapped_ptr (a, D.2973);
     x = variant_fn (D.2975, D.2974);

This code should work, but converting the NULL pointer is is a bit
pointless and OpenMP (current 6.0 draft) states:

"For each adjust_args clause that is present on the selected function
variant, the adjustment operation specified by the adjust-op modifier is
applied to each argument specified in the clause before being passed to
the selected function variant. Any argument specified in the clause that
does not exist at a given function call site is ignored."


Removed pointless conversion in the attached patch.


* * *

The following testcase produces an odd error in the C++ FE:

int& variant_fn();

#pragma omp declare variant(variant_fn) match(construct={dispatch})
int& bar();

void sub(int a)
{
   #pragma omp dispatch
     bar();
   #pragma omp dispatch
     a = bar();
}


I can reproduce but it predates my patch set. Should I try to fix it now?


* * *

Tobias



--
PAcommit 80ff2a257b07206c15d3a2d0200dba7e8234d87e
Author: Paul-Antoine Arras 
Date:   Fri May 24 18:38:07 2024 +0200

OpenMP: C++ front-end support for dispatch + adjust_args

This patch adds C++ support for the `dispatch` construct and the `adjust_args`
clause. It relies on the c-family bits comprised in the corresponding C front
end patch for pragmas and attributes.

Additional C/C++ common testcases are provided in a subsequent patch in the
series.

gcc/cp/ChangeLog:

* decl.cc (omp_declare_variant_finalize_one): Set adjust_args
need_device_ptr attribute.
* parser.cc (cp_parser_direct_declarator): Update call to
cp_parser_late_return_type_opt.
(cp_parser_late_return_type_opt): Add parameter. Update call to
cp_parser_late_parsing_omp_declare_simd.
(cp_parser_omp_clause_name): Handle nocontext and novariants clauses.
(cp_parser_omp_clause_novariants): New function.
(cp_parser_omp_clause_nocontext): Likewise.
(cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_NOVARIANTS and
PRAGMA_OMP_CLAUSE_NOCONTEXT.
(cp_parser_omp_dispatch_body): New function, inspired from
cp_parser_assignment_expression and cp_parser_postfix_expression.
(OMP_DISPATCH_CLAUSE_MASK): Define.
(cp_parser_omp_dispatch): New function.
(cp_finish_omp_declare_variant): Add parameter. Handle adjust_args
clause.
(cp_parser_late_parsing_omp_declare_simd): Add parameter. Update calls
to cp_finish_omp_declare_variant and cp_finish_omp_declare_variant.
(cp_parser_omp_construct): Handle PRAGMA_OMP_DISPATCH.
(cp_parser_pragma): Likewise.
* semantics.cc (finish_omp_clauses): Handle OMP_CLAUSE_NOCONTEXT and
OMP_CLAUSE_NOVARIANTS.

gcc/testsuite/ChangeLog:

* g++.dg/gomp/adjust-args-1.C: New test.
* g++.dg/gomp/adjust-args-2.C: New test.
* g++.dg/gomp/dispatch-1.C: New test.
* g++.dg/gomp/dispatch-2.C: New test.
* g++.dg/gomp/dispatch-3.C: New test.

diff --git gcc/cp/decl.cc gcc/cp/decl.cc
index 0c5b5c06a12..de8d088e69c 100644
--- gcc/cp/decl.cc
+++ gcc/cp/decl.cc
@@ -8403,6 +8403,13 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
 	  if (!omp_context_selector_matches (ctx))
 	return true;
 	  TREE_PURPOSE (TREE_VALUE (attr)) = variant;
+
+	  // Prepend adjust_args list to variant attributes
+	  tree adjust_args_list = TREE_CHAIN 

Re: [PATCH v4 2/7] OpenMP: middle-end support for dispatch + adjust_args

2024-10-23 Thread Paul-Antoine Arras

Here is the updated patch.

On 23/10/2024 11:41, Tobias Burnus wrote:
* The update to builtins.cc's builtin_fnspec  is lacking in the 
changelog list.


Added missing items to the ChangeLog.

* And the new testcase, new gcc/testsuite/c-c++-common/gomp/ 
dispatch-10.c, has to be put into 3/7 or later of the series as it 
requires a parser and, as written/file location, requires both C and C+ 
+, unless a skip for C is added.


Moved the testcase to 5/7. Will post the updated patch later.

Thanks,
--
PAcommit 6265c755697bba629fce4b27b8f1800ea1e313fb
Author: Paul-Antoine Arras 
Date:   Fri May 24 15:53:45 2024 +0200

OpenMP: middle-end support for dispatch + adjust_args

This patch adds middle-end support for the `dispatch` construct and the
`adjust_args` clause. The heavy lifting is done in `gimplify_omp_dispatch` and
`gimplify_call_expr` respectively. For `adjust_args`, this mostly consists in
emitting a call to `omp_get_mapped_ptr` for the adequate device.

For dispatch, the following steps are performed:

* Handle the device clause, if any: set the default-device ICV at the top of the
dispatch region and restore its previous value at the end.

* Handle novariants and nocontext clauses, if any. Evaluate compile-time
constants and select a variant, if possible. Otherwise, emit code to handle all
possible cases at run time.

gcc/ChangeLog:

* builtins.cc (builtin_fnspec): Handle BUILT_IN_OMP_GET_MAPPED_PTR.
* gimple-low.cc (lower_stmt): Handle GIMPLE_OMP_DISPATCH.
* gimple-pretty-print.cc (dump_gimple_omp_dispatch): New function.
(pp_gimple_stmt_1): Handle GIMPLE_OMP_DISPATCH.
* gimple-walk.cc (walk_gimple_stmt): Likewise.
* gimple.cc (gimple_build_omp_dispatch): New function.
(gimple_copy): Handle GIMPLE_OMP_DISPATCH.
* gimple.def (GIMPLE_OMP_DISPATCH): Define.
* gimple.h (gimple_build_omp_dispatch): Declare.
(gimple_has_substatements): Handle GIMPLE_OMP_DISPATCH.
(gimple_omp_dispatch_clauses): New function.
(gimple_omp_dispatch_clauses_ptr): Likewise.
(gimple_omp_dispatch_set_clauses): Likewise.
(gimple_return_set_retval): Handle GIMPLE_OMP_DISPATCH.
* gimplify.cc (enum omp_region_type): Add ORT_DISPATCH.
(struct gimplify_omp_ctx): Add in_call_args.
(gimplify_call_expr): Handle need_device_ptr arguments.
(is_gimple_stmt): Handle OMP_DISPATCH.
(gimplify_scan_omp_clauses): Handle OMP_CLAUSE_DEVICE in a dispatch
construct. Handle OMP_CLAUSE_NOVARIANTS and OMP_CLAUSE_NOCONTEXT.
(omp_has_novariants): New function.
(omp_has_nocontext): Likewise.
(omp_construct_selector_matches): Handle OMP_DISPATCH with nocontext
clause.
(find_ifn_gomp_dispatch): New function.
(gimplify_omp_dispatch): Likewise.
(gimplify_expr): Handle OMP_DISPATCH.
* gimplify.h (omp_has_novariants): Declare.
* internal-fn.cc (expand_GOMP_DISPATCH): New function.
* internal-fn.def (GOMP_DISPATCH): Define.
* omp-builtins.def (BUILT_IN_OMP_GET_MAPPED_PTR): Define.
(BUILT_IN_OMP_GET_DEFAULT_DEVICE): Define.
(BUILT_IN_OMP_SET_DEFAULT_DEVICE): Define.
* omp-general.cc (omp_construct_traits_to_codes): Add OMP_DISPATCH.
(struct omp_ts_info): Add dispatch.
(omp_resolve_declare_variant): Handle novariants. Adjust
DECL_ASSEMBLER_NAME.
* omp-low.cc (scan_omp_1_stmt): Handle GIMPLE_OMP_DISPATCH.
(lower_omp_dispatch): New function.
(lower_omp_1): Call it.
* tree-inline.cc (remap_gimple_stmt): Handle GIMPLE_OMP_DISPATCH.
(estimate_num_insns): Handle GIMPLE_OMP_DISPATCH.

diff --git gcc/builtins.cc gcc/builtins.cc
index 37c7c98e5c7..c7a8310bb3f 100644
--- gcc/builtins.cc
+++ gcc/builtins.cc
@@ -12580,6 +12580,8 @@ builtin_fnspec (tree callee)
 	 by its first argument.  */
   case BUILT_IN_POSIX_MEMALIGN:
 	return ".cOt";
+  case BUILT_IN_OMP_GET_MAPPED_PTR:
+	return ". R ";
 
   default:
 	return "";
diff --git gcc/gimple-low.cc gcc/gimple-low.cc
index e0371988705..712a1ebf776 100644
--- gcc/gimple-low.cc
+++ gcc/gimple-low.cc
@@ -746,6 +746,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
 case GIMPLE_EH_MUST_NOT_THROW:
 case GIMPLE_OMP_FOR:
 case GIMPLE_OMP_SCOPE:
+case GIMPLE_OMP_DISPATCH:
 case GIMPLE_OMP_SECTIONS:
 case GIMPLE_OMP_SECTIONS_SWITCH:
 case GIMPLE_OMP_SECTION:
diff --git gcc/gimple-pretty-print.cc gcc/gimple-pretty-print.cc
index 01d7c9f6eeb..7a45e8ec843 100644
--- gcc/gimple-pretty-print.cc
+++ gcc/gimple-pretty-print.cc
@@ -1726,6 +1726,35 @@ dump_gimple_omp_scope (p

Re: [PATCH v4 4/7] OpenMP: C++ front-end support for dispatch + adjust_args

2024-11-12 Thread Paul-Antoine Arras

On 04/11/2024 14:57, Tobias Burnus wrote:

Hi PA,

Regarding the update middle end patch, included in this patch, i.e.
v4.3-0002-OpenMP-middle-end-support-for-dispatch-adjust_arg.patch:


@@ -4071,23 +4073,136 @@ gimplify_call_expr (tree *expr_p, gimple_seq 
*pre_p, bool want_value)


[...]

+  if (flag_openmp && gimplify_omp_ctxp != NULL
+  && gimplify_omp_ctxp->code == OMP_DISPATCH
+  && !gimplify_omp_ctxp->in_call_args && !integer_zerop (*arg_p)
+  && EXPR_P (CALL_EXPR_FN (*expr_p))
+  && DECL_P (TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0))

Please add a line break before '&& !integer_zerop (...)'.
It is very easy to miss that part, given that the lines are very long,
such that keeps just parsing the '&&'.


Added line break.


Otherwise, this part LGTM (assuming that you have a testcase for it).


The testcase is gcc/testsuite/g++.dg/gomp/dispatch-4.C, included in 
v4.1-0004-OpenMP-C-front-end-support-for-dispatch-adjust_ar.patch... but 
I forgot to update the ChangeLog.



* * *

Regarding C++:


Paul-Antoine Arras wrote:

In C++, there is no equivalent to 
c_parser_postfix_expression_after_primary. So I am now calling 
cp_parser_postfix_expression, which parses not only the argument list 
but the whole function call.

… and …

int variant_fn(int *, int * = nullptr);

(This part is now handled via the middle end patch, cf. above.)

int& variant_fn();
#pragma omp declare variant(variant_fn) match(construct={dispatch})
int& bar();

void sub(int a)
{
   #pragma omp dispatch
 bar();
   #pragma omp dispatch
 a = bar();


The issue that 'variant_fn' is not found is now fixed →r15-4799- 
gf011f8908182fd However, the code now stumbles over the indirect ref, 
such that two (?) STRIP_REFERENCE_REF are missing. Can you look into 
this? — See also the next comment. * * *


Added STRIP_REFERENCE_REF as needed and also fixed the assert after 
cp_parser_omp_dispatch_body.



+cp_parser_omp_dispatch_body (cp_parser *parser)
+{

...

+  if (!(TREE_CODE (rhs) == CALL_EXPR
+    || (TREE_CODE (rhs) == INDIRECT_REF
+    && TREE_CODE (TREE_OPERAND (rhs, 0)) == CALL_EXPR)))
+    {


I think the last == should be !=, otherwise the code does not make sense.

Additionally, I think it is cleaner to write:

if (!TREE_CODE (STRIP_REFERENCE_REF (rhs)) == CALL_EXPR)

(Thanks to Jakub for pointing me to that macro for my patch.)


Definitely cleaner!


* * *

I still need to continue looking through the patch, but I have a second
testcase that fails - this time with an ICE:

     ../../../repos/gcc/gcc/toplev.cc:323
0xd85322 cp_build_modify_expr(unsigned int, tree_node*, tree_code, 
tree_node*, int)

     ../../../repos/gcc/gcc/cp/typeck.cc:9743
0xc5bfae cp_parser_omp_dispatch_body
     ../../../repos/gcc/gcc/cp/parser.cc:49237


My first implementation completely missed the template handling in 
pt.cc. This is now fixed; see updated ChangeLog.


Thanks,
--
PAcommit 485713d8f03600c896bbff9235874d36ac9fede2
Author: Paul-Antoine Arras 
Date:   Fri May 24 18:38:07 2024 +0200

OpenMP: C++ front-end support for dispatch + adjust_args

This patch adds C++ support for the `dispatch` construct and the `adjust_args`
clause. It relies on the c-family bits comprised in the corresponding C front
end patch for pragmas and attributes.

Additional C/C++ common testcases are provided in a subsequent patch in the
series.

gcc/cp/ChangeLog:

* decl.cc (omp_declare_variant_finalize_one): Set adjust_args
need_device_ptr attribute.
* parser.cc (cp_parser_direct_declarator): Update call to
cp_parser_late_return_type_opt.
(cp_parser_late_return_type_opt): Add parameter. Update call to
cp_parser_late_parsing_omp_declare_simd.
(cp_parser_omp_clause_name): Handle nocontext and novariants clauses.
(cp_parser_omp_clause_novariants): New function.
(cp_parser_omp_clause_nocontext): Likewise.
(cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_NOVARIANTS and
PRAGMA_OMP_CLAUSE_NOCONTEXT.
(cp_parser_omp_dispatch_body): New function, inspired from
cp_parser_assignment_expression and cp_parser_postfix_expression.
(OMP_DISPATCH_CLAUSE_MASK): Define.
(cp_parser_omp_dispatch): New function.
(cp_finish_omp_declare_variant): Add parameter. Handle adjust_args
clause.
(cp_parser_late_parsing_omp_declare_simd): Add parameter. Update calls
to cp_finish_omp_declare_variant and cp_finish_omp_declare_variant.
(cp_parser_omp_construct): Handle PRAGMA_OMP_DISPATCH.
(cp_parser_pragma): Likewise.
* semantics.cc (finish_omp_clauses): Handle OMP_CLAUSE_NOCONTEXT and
OMP_CLAUSE_NOV

Re: [PATCH v4 5/7] OpenMP: common C/C++ testcases for dispatch + adjust_args

2024-11-13 Thread Paul-Antoine Arras
Here is an updated version of the patch following earlier reviews in the 
series.

--
PAcommit 8f67de476decf151f853d68eb26223200535cc57
Author: Paul-Antoine Arras 
Date:   Fri May 24 19:04:35 2024 +0200

OpenMP: common C/C++ testcases for dispatch + adjust_args

gcc/testsuite/ChangeLog:

* c-c++-common/gomp/declare-variant-2.c: Adjust dg-error directives.
* c-c++-common/gomp/adjust-args-1.c: New test.
* c-c++-common/gomp/adjust-args-2.c: New test.
* c-c++-common/gomp/dispatch-1.c: New test.
* c-c++-common/gomp/dispatch-2.c: New test.
* c-c++-common/gomp/dispatch-3.c: New test.
* c-c++-common/gomp/dispatch-4.c: New test.
* c-c++-common/gomp/dispatch-5.c: New test.
* c-c++-common/gomp/dispatch-6.c: New test.
* c-c++-common/gomp/dispatch-7.c: New test.
* c-c++-common/gomp/dispatch-8.c: New test.
* c-c++-common/gomp/dispatch-9.c: New test.
* c-c++-common/gomp/dispatch-10.c: New test.

libgomp/ChangeLog:

* testsuite/libgomp.c-c++-common/dispatch-1.c: New test.
* testsuite/libgomp.c-c++-common/dispatch-2.c: New test.

diff --git gcc/testsuite/c-c++-common/gomp/adjust-args-1.c gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
new file mode 100644
index 000..728abe62092
--- /dev/null
+++ gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args (nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args (nothing: a) adjust_args (need_device_ptr: b) adjust_args (need_device_ptr: c)
+int f1 (int a, void *b, float c[2]);
+
+int test () {
+  int a;
+  void *b;
+  float c[2];
+  struct {int a;} s;
+
+  s.a = f0 (a, b, c);
+  #pragma omp dispatch
+  s.a = f0 (a, b, c);
+
+  f1 (a, b, c);
+  #pragma omp dispatch
+  s.a = f1 (a, b, c);
+
+  return s.a;
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device \\(\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = __builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = __builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
diff --git gcc/testsuite/c-c++-common/gomp/adjust-args-2.c gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
new file mode 100644
index 000..d2a4a5f4ec4
--- /dev/null
+++ gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args (nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) adjust_args (need_device_ptr: b, c) match (construct={dispatch}) adjust_args (nothing: a) 
+int f1 (int a, void *b, float c[2]);
+
+void test () {
+  int a;
+  void *b;
+  float c[2];
+
+  #pragma omp dispatch
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (-4852)
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (a + a)
+  f0 (a, b, c);
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device \\(\\);" 3 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = __builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = __builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = __builtin_omp_get_mapped_ptr \\(&c, -4852\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = __builtin_omp_get_mapped_ptr \\(b, -4852\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-not "#pragma omp dispatch device" "gimple" } } */
diff --git gcc/testsuite/c-c++-common/gomp/declare-variant-2.c gcc/testsuite/c-c++-common/gomp/declare-variant-2.c
index 05e485ef6a8..50d9b2dcf4b 100644
--- gcc/testsuite/c-c++-common/gomp/declare-variant-2.c
+++ gcc/testsuite/c-c++-common/gomp/declare-variant-2.c
@@ -8,9 +8,9 @@ void f3 (void);
 void f4 (void);
 #pragma omp declare variant match(user={condition(0)})	/* { dg-error "expected '\\(' before 'match'" } */
 void f5 (void);
-#pragma omp declare variant (f1)	/* { dg-error "expected 'match' before end of line" } */
+#pragma omp declare variant (f1)	/* { dg-error "expected 'match' or 'adjust_args' bef

[PATCH v4 3/7] OpenMP: C front-end support for dispatch + adjust_args

2024-10-02 Thread Paul-Antoine Arras
This patch adds support to the C front-end to parse the `dispatch` construct and
the `adjust_args` clause. It also includes some common C/C++ bits for pragmas
and attributes.

Additional common C/C++ testcases are in a later patch in the series.

gcc/c-family/ChangeLog:

* c-attribs.cc (c_common_gnu_attributes): Add attribute for adjust_args
need_device_ptr.
* c-omp.cc (c_omp_directives): Uncomment dispatch.
* c-pragma.cc (omp_pragmas): Add dispatch.
* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_DISPATCH.
(enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_NOCONTEXT and
PRAGMA_OMP_CLAUSE_NOVARIANTS.

gcc/c/ChangeLog:

* c-parser.cc (c_parser_omp_dispatch): New function.
(c_parser_omp_clause_name): Handle nocontext and novariants clauses.
(c_parser_omp_clause_novariants): New function.
(c_parser_omp_clause_nocontext): Likewise.
(c_parser_omp_all_clauses): Handle nocontext and novariants clauses.
(c_parser_omp_dispatch_body): New function adapted from
c_parser_expr_no_commas.
(OMP_DISPATCH_CLAUSE_MASK): Define.
(c_parser_omp_dispatch): New function.
(c_finish_omp_declare_variant): Parse adjust_args.
(c_parser_omp_construct): Handle PRAGMA_OMP_DISPATCH.
* c-typeck.cc (c_finish_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.

gcc/testsuite/ChangeLog:

* gcc.dg/gomp/adjust-args-1.c: New test.
* gcc.dg/gomp/dispatch-1.c: New test.
---
 gcc/c-family/c-attribs.cc |   2 +
 gcc/c-family/c-omp.cc |   4 +-
 gcc/c-family/c-pragma.cc  |   1 +
 gcc/c-family/c-pragma.h   |   3 +
 gcc/c/c-parser.cc | 536 +++---
 gcc/c/c-typeck.cc |   2 +
 gcc/testsuite/gcc.dg/gomp/adjust-args-1.c |  32 ++
 gcc/testsuite/gcc.dg/gomp/dispatch-1.c|  53 +++
 libgomp/testsuite/libgomp.c/dispatch-1.c  |  76 +++
 libgomp/testsuite/libgomp.c/dispatch-2.c  |  84 
 10 files changed, 733 insertions(+), 60 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/gomp/adjust-args-1.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/dispatch-1.c
 create mode 100644 libgomp/testsuite/libgomp.c/dispatch-1.c
 create mode 100644 libgomp/testsuite/libgomp.c/dispatch-2.c

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 4dd2eecbea5..fab9b5b8b23 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -571,6 +571,8 @@ const struct attribute_spec c_common_gnu_attributes[] =
  handle_omp_declare_variant_attribute, NULL },
   { "omp declare variant variant", 0, -1, true,  false, false, false,
  handle_omp_declare_variant_attribute, NULL },
+  { "omp declare variant adjust_args need_device_ptr", 0, -1, true,  false, 
false, false,
+ handle_omp_declare_variant_attribute, NULL },
   { "simd",  0, 1, true,  false, false, false,
  handle_simd_attribute, NULL },
   { "omp declare target", 0, -1, true, false, false, false,
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index 620a3c1353a..5a0ed636677 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -4300,8 +4300,8 @@ const struct c_omp_directive c_omp_directives[] = {
 C_OMP_DIR_DECLARATIVE, false },
   { "depobj", nullptr, nullptr, PRAGMA_OMP_DEPOBJ,
 C_OMP_DIR_STANDALONE, false },
-  /* { "dispatch", nullptr, nullptr, PRAGMA_OMP_DISPATCH,
-C_OMP_DIR_CONSTRUCT, false },  */
+  { "dispatch", nullptr, nullptr, PRAGMA_OMP_DISPATCH,
+C_OMP_DIR_DECLARATIVE, false },
   { "distribute", nullptr, nullptr, PRAGMA_OMP_DISTRIBUTE,
 C_OMP_DIR_CONSTRUCT, true },
   { "end", "assumes", nullptr, PRAGMA_OMP_END,
diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc
index ed2a7a00e9e..040370cbb6f 100644
--- a/gcc/c-family/c-pragma.cc
+++ b/gcc/c-family/c-pragma.cc
@@ -1526,6 +1526,7 @@ static const struct omp_pragma_def omp_pragmas[] = {
   { "cancellation", PRAGMA_OMP_CANCELLATION_POINT },
   { "critical", PRAGMA_OMP_CRITICAL },
   { "depobj", PRAGMA_OMP_DEPOBJ },
+  { "dispatch", PRAGMA_OMP_DISPATCH },
   { "error", PRAGMA_OMP_ERROR },
   { "end", PRAGMA_OMP_END },
   { "flush", PRAGMA_OMP_FLUSH },
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index 2ebde06c471..6b6826b2426 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -55,6 +55,7 @@ enum pragma_kind {
   PRAGMA_OMP_CRITICAL,
   PRAGMA_OMP_DECLARE,
   PRAGMA_OMP_DEPOBJ,
+  PRAGMA_OMP_DISPATCH,
   PRAGMA_OMP_DISTRIBUTE,
   PRAGMA_OMP_ERROR,
   PRAGMA_OMP_END,
@@ -135,9 +136,11 @@ enum pragma_omp_clause {
   PRAGMA_OMP_CLAUSE_LINK,
   PRAGMA_OMP_CLAUSE_MAP,
   PRAGMA_OMP_CLAUSE_MERGEABLE,
+  PRAGMA_OMP_CLAUSE_NOCONTEXT,
   PRAGMA_OMP_CLAUSE_NOGROUP,
   PRAGMA_OMP_CLAUSE_NONTEMPORAL,
   PRAGMA_OM

[PATCH v4 1/7] OpenMP: dispatch + adjust_args tree data structures and front-end interfaces

2024-10-02 Thread Paul-Antoine Arras
This patch introduces the OMP_DISPATCH tree node, as well as two new clauses
`nocontext` and `novariants`. It defines/exposes interfaces that will be
used in subsequent patches that add front-end and middle-end support, but
nothing generates these nodes yet.

gcc/ChangeLog:

* builtin-types.def (BT_FN_PTR_CONST_PTR_INT): New.
* omp-selectors.h (enum omp_ts_code): Add OMP_TRAIT_CONSTRUCT_DISPATCH.
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
* tree-pretty-print.cc (dump_omp_clause): Handle OMP_CLAUSE_NOVARIANTS
and OMP_CLAUSE_NOCONTEXT.
(dump_generic_node): Handle OMP_DISPATCH.
* tree.cc (omp_clause_num_ops): Add OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(omp_clause_code_name): Add "novariants" and "nocontext".
* tree.def (OMP_DISPATCH): New.
* tree.h (OMP_DISPATCH_BODY): New macro.
(OMP_DISPATCH_CLAUSES): New macro.
(OMP_CLAUSE_NOVARIANTS_EXPR): New macro.
(OMP_CLAUSE_NOCONTEXT_EXPR): New macro.

gcc/fortran/ChangeLog:

* types.def (BT_FN_PTR_CONST_PTR_INT): Declare.
---
 gcc/builtin-types.def|  1 +
 gcc/fortran/types.def|  1 +
 gcc/omp-selectors.h  |  1 +
 gcc/tree-core.h  |  7 +++
 gcc/tree-pretty-print.cc | 21 +
 gcc/tree.cc  |  4 
 gcc/tree.def |  5 +
 gcc/tree.h   |  7 +++
 8 files changed, 47 insertions(+)

diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index c97d6bad1de..ef7aaf67d13 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -677,6 +677,7 @@ DEF_FUNCTION_TYPE_2 (BT_FN_INT_FEXCEPT_T_PTR_INT, BT_INT, 
BT_FEXCEPT_T_PTR,
 DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_FEXCEPT_T_PTR_INT, BT_INT,
 BT_CONST_FEXCEPT_T_PTR, BT_INT)
 DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_UINT8, BT_PTR, BT_CONST_PTR, BT_UINT8)
+DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_INT, BT_PTR, BT_CONST_PTR, BT_INT)
 
 DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
 
diff --git a/gcc/fortran/types.def b/gcc/fortran/types.def
index 390cc9542f7..5047c8f816a 100644
--- a/gcc/fortran/types.def
+++ b/gcc/fortran/types.def
@@ -120,6 +120,7 @@ DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_INT_BOOL, BT_BOOL, BT_INT, 
BT_BOOL)
 DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_PTRMODE,
 BT_VOID, BT_PTR, BT_PTRMODE)
 DEF_FUNCTION_TYPE_2 (BT_FN_VOID_CONST_PTR_SIZE, BT_VOID, BT_CONST_PTR, BT_SIZE)
+DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_INT, BT_PTR, BT_CONST_PTR, BT_INT)
 
 DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
 
diff --git a/gcc/omp-selectors.h b/gcc/omp-selectors.h
index 730021ea747..447c3b8173f 100644
--- a/gcc/omp-selectors.h
+++ b/gcc/omp-selectors.h
@@ -56,6 +56,7 @@ enum omp_ts_code {
   OMP_TRAIT_CONSTRUCT_PARALLEL,
   OMP_TRAIT_CONSTRUCT_FOR,
   OMP_TRAIT_CONSTRUCT_SIMD,
+  OMP_TRAIT_CONSTRUCT_DISPATCH,
   OMP_TRAIT_LAST,
   OMP_TRAIT_INVALID = -1
 };
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 4ba63ebd4f1..b7c92daa1e6 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -542,6 +542,13 @@ enum omp_clause_code {
 
   /* OpenACC clause: nohost.  */
   OMP_CLAUSE_NOHOST,
+
+  /* OpenMP clause: novariants (scalar-expression).  */
+  OMP_CLAUSE_NOVARIANTS,
+
+  /* OpenMP clause: nocontext (scalar-expression).  */
+  OMP_CLAUSE_NOCONTEXT,
+
 };
 
 #undef DEFTREESTRUCT
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index b378ffbfb4c..61cd8708524 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -506,6 +506,22 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, 
dump_flags_t flags)
 case OMP_CLAUSE_EXCLUSIVE:
   name = "exclusive";
   goto print_remap;
+case OMP_CLAUSE_NOVARIANTS:
+  pp_string (pp, "novariants");
+  pp_left_paren (pp);
+  gcc_assert (OMP_CLAUSE_NOVARIANTS_EXPR (clause));
+  dump_generic_node (pp, OMP_CLAUSE_NOVARIANTS_EXPR (clause), spc, flags,
+false);
+  pp_right_paren (pp);
+  break;
+case OMP_CLAUSE_NOCONTEXT:
+  pp_string (pp, "nocontext");
+  pp_left_paren (pp);
+  gcc_assert (OMP_CLAUSE_NOCONTEXT_EXPR (clause));
+  dump_generic_node (pp, OMP_CLAUSE_NOCONTEXT_EXPR (clause), spc, flags,
+false);
+  pp_right_paren (pp);
+  break;
 case OMP_CLAUSE__LOOPTEMP_:
   name = "_looptemp_";
   goto print_remap;
@@ -3947,6 +3963,11 @@ dump_generic_node (pretty_printer *pp, tree node, int 
spc, dump_flags_t flags,
   dump_omp_clauses (pp, OMP_SECTIONS_CLAUSES (node), spc, flags);
   goto dump_omp_body;
 
+case OMP_DISPATCH:
+  pp_string (pp, "#pragma omp dispatch");
+  dump_omp_clauses (pp, OMP_DISPATCH_CLAUSES (node), spc, flags);
+  goto dump_omp_body;
+
 case OMP_SECTION:
   pp_string (pp, "#pragma omp section");
   goto dump_omp_body;
diff --git a/gcc/tree.cc b/gcc/tree.cc

[PATCH v4 0/7] OpenMP: dispatch + adjust_args support

2024-10-02 Thread Paul-Antoine Arras
This is a respin of my patchset implementing both the `dispatch` construct and 
the `adjust_args` clause to the `declare variant` directive. The previous
submission can be found there:
https://gcc.gnu.org/pipermail/gcc-patches/2024-August/659719.html

Compared to v3, this new iteration handles Tobias's comments on the ME patch
(https://gcc.gnu.org/pipermail/gcc-patches/2024-August/660921.html). In 
particular, it defines and uses a new internal function (namely 
IFN_GOMP_DISPATCH) to allow the middle end to more easily and accurately find 
the dispatch call. This is important when the single function call we are 
interested in is sandwiched in a sequence of pre- and post-call statements, 
or when the same function is call several times within the dispatch body.


Paul-Antoine Arras (7):
  OpenMP: dispatch + adjust_args tree data structures and front-end
interfaces
  OpenMP: middle-end support for dispatch + adjust_args
  OpenMP: C front-end support for dispatch + adjust_args
  OpenMP: C++ front-end support for dispatch + adjust_args
  OpenMP: common C/C++ testcases for dispatch + adjust_args
  OpenMP: Fortran front-end support for dispatch + adjust_args
  OpenMP: update documentation for dispatch and adjust_args

 gcc/builtin-types.def |   1 +
 gcc/c-family/c-attribs.cc |   2 +
 gcc/c-family/c-omp.cc |   4 +-
 gcc/c-family/c-pragma.cc  |   1 +
 gcc/c-family/c-pragma.h   |   3 +
 gcc/c/c-parser.cc | 536 +--
 gcc/c/c-typeck.cc |   2 +
 gcc/cp/decl.cc|   7 +
 gcc/cp/parser.cc  | 644 --
 gcc/cp/semantics.cc   |  20 +
 gcc/fortran/dump-parse-tree.cc|  17 +
 gcc/fortran/frontend-passes.cc|   2 +
 gcc/fortran/gfortran.h|  12 +-
 gcc/fortran/match.h   |   1 +
 gcc/fortran/openmp.cc | 195 +-
 gcc/fortran/parse.cc  |  51 +-
 gcc/fortran/resolve.cc|   2 +
 gcc/fortran/st.cc |   1 +
 gcc/fortran/trans-decl.cc |   9 +-
 gcc/fortran/trans-openmp.cc   | 197 ++
 gcc/fortran/trans.cc  |   1 +
 gcc/fortran/types.def |   1 +
 gcc/gimple-low.cc |   1 +
 gcc/gimple-pretty-print.cc|  33 +
 gcc/gimple-walk.cc|   1 +
 gcc/gimple.cc |  20 +
 gcc/gimple.def|   5 +
 gcc/gimple.h  |  33 +-
 gcc/gimplify.cc   | 484 -
 gcc/gimplify.h|   1 +
 gcc/internal-fn.cc|   8 +
 gcc/internal-fn.def   |   1 +
 gcc/omp-builtins.def  |   6 +
 gcc/omp-general.cc|  14 +-
 gcc/omp-low.cc|  35 +
 gcc/omp-selectors.h   |   1 +
 .../c-c++-common/gomp/adjust-args-1.c |  30 +
 .../c-c++-common/gomp/adjust-args-2.c |  31 +
 .../c-c++-common/gomp/declare-variant-2.c |   4 +-
 gcc/testsuite/c-c++-common/gomp/dispatch-1.c  |  71 ++
 gcc/testsuite/c-c++-common/gomp/dispatch-2.c  |  28 +
 gcc/testsuite/c-c++-common/gomp/dispatch-3.c  |  12 +
 gcc/testsuite/c-c++-common/gomp/dispatch-4.c  |  18 +
 gcc/testsuite/c-c++-common/gomp/dispatch-5.c  |  34 +
 gcc/testsuite/c-c++-common/gomp/dispatch-6.c  |  18 +
 gcc/testsuite/c-c++-common/gomp/dispatch-7.c  |  21 +
 gcc/testsuite/c-c++-common/gomp/dispatch-8.c  |  63 ++
 gcc/testsuite/c-c++-common/gomp/dispatch-9.c  |  17 +
 gcc/testsuite/g++.dg/gomp/adjust-args-1.C |  39 ++
 gcc/testsuite/g++.dg/gomp/adjust-args-2.C |  51 ++
 gcc/testsuite/g++.dg/gomp/dispatch-1.C|  53 ++
 gcc/testsuite/g++.dg/gomp/dispatch-2.C|  62 ++
 gcc/testsuite/g++.dg/gomp/dispatch-3.C|  17 +
 gcc/testsuite/gcc.dg/gomp/adjust-args-1.c |  32 +
 gcc/testsuite/gcc.dg/gomp/dispatch-1.c|  53 ++
 .../gfortran.dg/gomp/adjust-args-1.f90|  58 ++
 .../gfortran.dg/gomp/adjust-args-2.f90|  18 +
 .../gfortran.dg/gomp/adjust-args-3.f90|  27 +
 .../gfortran.dg/gomp/adjust-args-4.f90|  58 ++
 .../gfortran.dg/gomp/adjust-args-5.f90|  58 ++
 .../gfortran.dg/gomp/declare-variant-2.f90|   6 +-
 .../gomp/declare-variant-21-aux.f90   |  25 +
 .../gfortran.dg/gomp/declare-variant-21.f90   |  22 +
 gcc/testsuite/gfortran.dg/gomp/dispatch-1.f90 |  77 +++
 .../gfortran.dg/gomp/dispatch-10.f90  |  21 +
 gcc/testsuite/gfortran.dg/gomp/dispatch-2.f90 |  79 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-3.f90 

[PATCH v4 5/7] OpenMP: common C/C++ testcases for dispatch + adjust_args

2024-10-02 Thread Paul-Antoine Arras
gcc/testsuite/ChangeLog:

* c-c++-common/gomp/declare-variant-2.c: Adjust dg-error directives.
* c-c++-common/gomp/adjust-args-1.c: New test.
* c-c++-common/gomp/adjust-args-2.c: New test.
* c-c++-common/gomp/dispatch-1.c: New test.
* c-c++-common/gomp/dispatch-2.c: New test.
* c-c++-common/gomp/dispatch-3.c: New test.
* c-c++-common/gomp/dispatch-4.c: New test.
* c-c++-common/gomp/dispatch-5.c: New test.
* c-c++-common/gomp/dispatch-6.c: New test.
* c-c++-common/gomp/dispatch-7.c: New test.
* c-c++-common/gomp/dispatch-8.c: New test.
---
 .../c-c++-common/gomp/adjust-args-1.c | 30 
 .../c-c++-common/gomp/adjust-args-2.c | 31 
 .../c-c++-common/gomp/declare-variant-2.c |  4 +-
 gcc/testsuite/c-c++-common/gomp/dispatch-1.c  | 71 +++
 gcc/testsuite/c-c++-common/gomp/dispatch-2.c  | 28 
 gcc/testsuite/c-c++-common/gomp/dispatch-3.c  | 12 
 gcc/testsuite/c-c++-common/gomp/dispatch-4.c  | 18 +
 gcc/testsuite/c-c++-common/gomp/dispatch-5.c  | 34 +
 gcc/testsuite/c-c++-common/gomp/dispatch-6.c  | 18 +
 gcc/testsuite/c-c++-common/gomp/dispatch-7.c  | 21 ++
 gcc/testsuite/c-c++-common/gomp/dispatch-8.c  | 63 
 gcc/testsuite/c-c++-common/gomp/dispatch-9.c  | 17 +
 .../dispatch-1.c  |  0
 .../dispatch-2.c  |  0
 14 files changed, 345 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-1.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-2.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-3.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-4.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-5.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-6.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-7.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-8.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/dispatch-9.c
 rename libgomp/testsuite/{libgomp.c => libgomp.c-c++-common}/dispatch-1.c 
(100%)
 rename libgomp/testsuite/{libgomp.c => libgomp.c-c++-common}/dispatch-2.c 
(100%)

diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c 
b/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
new file mode 100644
index 000..728abe62092
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/adjust-args-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b) adjust_args (need_device_ptr: c)
+int f1 (int a, void *b, float c[2]);
+
+int test () {
+  int a;
+  void *b;
+  float c[2];
+  struct {int a;} s;
+
+  s.a = f0 (a, b, c);
+  #pragma omp dispatch
+  s.a = f0 (a, b, c);
+
+  f1 (a, b, c);
+  #pragma omp dispatch
+  s.a = f1 (a, b, c);
+
+  return s.a;
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device 
\\(\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c 
b/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
new file mode 100644
index 000..d2a4a5f4ec4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/adjust-args-2.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f) match (construct={dispatch}) adjust_args 
(nothing: a) adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+#pragma omp declare variant (f) adjust_args (need_device_ptr: b, c) match 
(construct={dispatch}) adjust_args (nothing: a) 
+int f1 (int a, void *b, float c[2]);
+
+void test () {
+  int a;
+  void *b;
+  float c[2];
+
+  #pragma omp dispatch
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (-4852)
+  f0 (a, b, c);
+
+  #pragma omp dispatch device (a + a)
+  f0 (a, b, c);
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_omp_get_default_device 
\\(\\);" 3 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(&c, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9]+ = 
__builtin_omp_get_mapped_ptr \\(b, D\.\[0-9]+\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-d

[PATCH v4 6/7] OpenMP: Fortran front-end support for dispatch + adjust_args

2024-10-02 Thread Paul-Antoine Arras
This patch adds support for the `dispatch` construct and the `adjust_args`
clause to the Fortran front-end.

Handling of `adjust_args` across translation units is missing due to PR115271.

gcc/fortran/ChangeLog:

* dump-parse-tree.cc (show_omp_clauses): Handle novariants and nocontext
clauses.
(show_omp_node): Handle EXEC_OMP_DISPATCH.
(show_code_node): Likewise.
* frontend-passes.cc (gfc_code_walker): Handle novariants and nocontext.
* gfortran.h (enum gfc_statement): Add ST_OMP_DISPATCH.
(symbol_attribute): Add omp_declare_variant_need_device_ptr.
(gfc_omp_clauses): Add novariants and nocontext.
(gfc_omp_declare_variant): Add need_device_ptr_arg_list.
(enum gfc_exec_op): Add EXEC_OMP_DISPATCH.
* match.h (gfc_match_omp_dispatch): Declare.
* openmp.cc (gfc_free_omp_clauses): Free novariants and nocontext
clauses.
(gfc_free_omp_declare_variant_list): Free need_device_ptr_arg_list
namelist.
(enum omp_mask2): Add OMP_CLAUSE_NOVARIANTS and OMP_CLAUSE_NOCONTEXT.
(gfc_match_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(OMP_DISPATCH_CLAUSES): Define.
(gfc_match_omp_dispatch): New function.
(gfc_match_omp_declare_variant): Parse adjust_args.
(resolve_omp_clauses): Handle adjust_args, novariants and nocontext.
Adjust handling of OMP_LIST_IS_DEVICE_PTR.
(icode_code_error_callback): Handle EXEC_OMP_DISPATCH.
(omp_code_to_statement): Likewise.
(resolve_omp_dispatch): New function.
(gfc_resolve_omp_directive): Handle EXEC_OMP_DISPATCH.
* parse.cc (decode_omp_directive): Match dispatch.
(next_statement): Handle ST_OMP_DISPATCH.
(gfc_ascii_statement): Likewise.
(parse_omp_dispatch): New function.
(parse_executable): Handle ST_OMP_DISPATCH.
* resolve.cc (gfc_resolve_blocks): Handle EXEC_OMP_DISPATCH.
* st.cc (gfc_free_statement): Likewise.
* trans-decl.cc (create_function_arglist): Declare.
(gfc_get_extern_function_decl): Call it.
* trans-openmp.cc (gfc_trans_omp_clauses): Handle novariants and
nocontext.
(replace_omp_dispatch_call): New function.
(gfc_trans_omp_dispatch): New function.
(gfc_trans_omp_directive): Handle EXEC_OMP_DISPATCH.
(gfc_trans_omp_declare_variant): Handle adjust_args.
* trans.cc (trans_code): Handle EXEC_OMP_DISPATCH:.

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/declare-variant-2.f90: Update dg-error.
* gfortran.dg/gomp/declare-variant-21.f90: New test (xfail).
* gfortran.dg/gomp/declare-variant-21-aux.f90: New test.
* gfortran.dg/gomp/adjust-args-1.f90: New test.
* gfortran.dg/gomp/adjust-args-2.f90: New test.
* gfortran.dg/gomp/adjust-args-3.f90: New test.
* gfortran.dg/gomp/adjust-args-4.f90: New test.
* gfortran.dg/gomp/adjust-args-5.f90: New test.
* gfortran.dg/gomp/dispatch-1.f90: New test.
* gfortran.dg/gomp/dispatch-2.f90: New test.
* gfortran.dg/gomp/dispatch-3.f90: New test.
* gfortran.dg/gomp/dispatch-4.f90: New test.
* gfortran.dg/gomp/dispatch-5.f90: New test.
* gfortran.dg/gomp/dispatch-6.f90: New test.
* gfortran.dg/gomp/dispatch-7.f90: New test.
* gfortran.dg/gomp/dispatch-8.f90: New test.
* gfortran.dg/gomp/dispatch-9.f90: New test.
* gfortran.dg/gomp/dispatch-10.f90: New test.
---
 gcc/fortran/dump-parse-tree.cc|  17 ++
 gcc/fortran/frontend-passes.cc|   2 +
 gcc/fortran/gfortran.h|  12 +-
 gcc/fortran/match.h   |   1 +
 gcc/fortran/openmp.cc | 195 +++--
 gcc/fortran/parse.cc  |  51 -
 gcc/fortran/resolve.cc|   2 +
 gcc/fortran/st.cc |   1 +
 gcc/fortran/trans-decl.cc |   9 +-
 gcc/fortran/trans-openmp.cc   | 197 ++
 gcc/fortran/trans.cc  |   1 +
 .../gfortran.dg/gomp/adjust-args-1.f90|  58 ++
 .../gfortran.dg/gomp/adjust-args-2.f90|  18 ++
 .../gfortran.dg/gomp/adjust-args-3.f90|  27 +++
 .../gfortran.dg/gomp/adjust-args-4.f90|  58 ++
 .../gfortran.dg/gomp/adjust-args-5.f90|  58 ++
 .../gfortran.dg/gomp/declare-variant-2.f90|   6 +-
 .../gomp/declare-variant-21-aux.f90   |  25 +++
 .../gfortran.dg/gomp/declare-variant-21.f90   |  22 ++
 gcc/testsuite/gfortran.dg/gomp/dispatch-1.f90 |  77 +++
 .../gfortran.dg/gomp/dispatch-10.f90  |  21 ++
 gcc/testsuite/gfortran.dg/gomp/dispatch-2.f90 |  79 +++
 gcc/testsuite/gfortran.dg/gomp/dispatch-3.f90 |  39 
 gcc/testsuite/gfortran.dg/gomp/dispatch-4.f90 |  19 ++
 gcc/testsuite/gfortran.d

[PATCH v4 2/7] OpenMP: middle-end support for dispatch + adjust_args

2024-10-02 Thread Paul-Antoine Arras
This patch adds middle-end support for the `dispatch` construct and the
`adjust_args` clause. The heavy lifting is done in `gimplify_omp_dispatch` and
`gimplify_call_expr` respectively. For `adjust_args`, this mostly consists in
emitting a call to `gomp_get_mapped_ptr` for the adequate device.

For dispatch, the following steps are performed:

* Handle the device clause, if any: set the default-device ICV at the top of the
dispatch region and restore its previous value at the end.

* Handle novariants and nocontext clauses, if any. Evaluate compile-time
constants and select a variant, if possible. Otherwise, emit code to handle all
possible cases at run time.

* If depend clauses are present, add a taskwait construct before the dispatch
region and move them there.

gcc/ChangeLog:

* gimple-low.cc (lower_stmt): Handle GIMPLE_OMP_DISPATCH.
* gimple-pretty-print.cc (dump_gimple_omp_dispatch): New function.
(pp_gimple_stmt_1): Handle GIMPLE_OMP_DISPATCH.
* gimple-walk.cc (walk_gimple_stmt): Likewise.
* gimple.cc (gimple_build_omp_dispatch): New function.
(gimple_copy): Handle GIMPLE_OMP_DISPATCH.
* gimple.def (GIMPLE_OMP_DISPATCH): Define.
* gimple.h (gimple_build_omp_dispatch): Declare.
(gimple_has_substatements): Handle GIMPLE_OMP_DISPATCH.
(gimple_omp_dispatch_clauses): New function.
(gimple_omp_dispatch_clauses_ptr): Likewise.
(gimple_omp_dispatch_set_clauses): Likewise.
(gimple_return_set_retval): Handle GIMPLE_OMP_DISPATCH.
* gimplify.cc (enum omp_region_type): Add ORT_DISPATCH.
(gimplify_call_expr): Handle need_device_ptr arguments.
(is_gimple_stmt): Handle OMP_DISPATCH.
(gimplify_scan_omp_clauses): Handle OMP_CLAUSE_DEVICE in a dispatch
construct. Handle OMP_CLAUSE_NOVARIANTS and OMP_CLAUSE_NOCONTEXT.
(omp_construct_selector_matches): Handle OMP_DISPATCH with nocontext
clause.
(omp_has_novariants): New function.
(omp_has_nocontext): Likewise.
(find_ifn_gomp_dispatch): New function.
(gimplify_omp_dispatch): Likewise.
(gimplify_expr): Handle OMP_DISPATCH.
* gimplify.h (omp_has_novariants): Declare.
* internal-fn.cc (expand_GOMP_DISPATCH): New function.
* internal-fn.def (GOMP_DISPATCH): Define.
* omp-builtins.def (BUILT_IN_OMP_GET_MAPPED_PTR): Define.
(BUILT_IN_OMP_GET_DEFAULT_DEVICE): Define.
(BUILT_IN_OMP_SET_DEFAULT_DEVICE): Define.
* omp-general.cc (omp_construct_traits_to_codes): Add OMP_DISPATCH.
(struct omp_ts_info): Add dispatch.
(omp_resolve_declare_variant): Handle novariants. Adjust
DECL_ASSEMBLER_NAME.
* omp-low.cc (scan_omp_1_stmt): Handle GIMPLE_OMP_DISPATCH.
(lower_omp_dispatch): New function.
(lower_omp_1): Call it.
* tree-inline.cc (remap_gimple_stmt): Handle GIMPLE_OMP_DISPATCH.
(estimate_num_insns): Handle GIMPLE_OMP_DISPATCH.
---
 gcc/gimple-low.cc  |   1 +
 gcc/gimple-pretty-print.cc |  33 +++
 gcc/gimple-walk.cc |   1 +
 gcc/gimple.cc  |  20 ++
 gcc/gimple.def |   5 +
 gcc/gimple.h   |  33 ++-
 gcc/gimplify.cc| 484 +++--
 gcc/gimplify.h |   1 +
 gcc/internal-fn.cc |   8 +
 gcc/internal-fn.def|   1 +
 gcc/omp-builtins.def   |   6 +
 gcc/omp-general.cc |  14 +-
 gcc/omp-low.cc |  35 +++
 gcc/tree-inline.cc |   7 +
 14 files changed, 627 insertions(+), 22 deletions(-)

diff --git a/gcc/gimple-low.cc b/gcc/gimple-low.cc
index e0371988705..712a1ebf776 100644
--- a/gcc/gimple-low.cc
+++ b/gcc/gimple-low.cc
@@ -746,6 +746,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data 
*data)
 case GIMPLE_EH_MUST_NOT_THROW:
 case GIMPLE_OMP_FOR:
 case GIMPLE_OMP_SCOPE:
+case GIMPLE_OMP_DISPATCH:
 case GIMPLE_OMP_SECTIONS:
 case GIMPLE_OMP_SECTIONS_SWITCH:
 case GIMPLE_OMP_SECTION:
diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc
index 01d7c9f6eeb..7a45e8ec843 100644
--- a/gcc/gimple-pretty-print.cc
+++ b/gcc/gimple-pretty-print.cc
@@ -1726,6 +1726,35 @@ dump_gimple_omp_scope (pretty_printer *pp, const gimple 
*gs,
 }
 }
 
+/* Dump a GIMPLE_OMP_DISPATCH tuple on the pretty_printer BUFFER.  */
+
+static void
+dump_gimple_omp_dispatch (pretty_printer *buffer, const gimple *gs, int spc,
+ dump_flags_t flags)
+{
+  if (flags & TDF_RAW)
+{
+  dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
+  gimple_omp_body (gs));
+  dump_omp_clauses (buffer, gimple_omp_dispatch_clauses (gs), spc, flags);
+  dump_gimple_fmt (buffer, spc, flags, " >");
+}
+  else
+{
+  pp_string (buffer, "#pragma omp dispatch");
+  dump_omp_clauses (buffer, gimple_omp_dispatch_clauses (gs), spc, flags);
+  if (!

[PATCH v4 7/7] OpenMP: update documentation for dispatch and adjust_args

2024-10-02 Thread Paul-Antoine Arras
libgomp/ChangeLog:

* libgomp.texi:
---
 libgomp/libgomp.texi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index c6464ece32e..7026f32f867 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -294,8 +294,8 @@ The OpenMP 4.5 specification is fully supported.
 @item C/C++'s @code{declare variant} directive: elision support of
   preprocessed code @tab N @tab
 @item @code{declare variant}: new clauses @code{adjust_args} and
-  @code{append_args} @tab N @tab
-@item @code{dispatch} construct @tab N @tab
+  @code{append_args} @tab P @tab Only @code{adjust_args}
+@item @code{dispatch} construct @tab Y @tab
 @item device-specific ICV settings with environment variables @tab Y @tab
 @item @code{assume} and @code{assumes} directives @tab Y @tab
 @item @code{nothing} directive @tab Y @tab
-- 
2.45.2



[PATCH v4 4/7] OpenMP: C++ front-end support for dispatch + adjust_args

2024-10-02 Thread Paul-Antoine Arras
This patch adds C++ support for the `dispatch` construct and the `adjust_args`
clause. It relies on the c-family bits comprised in the corresponding C front
end patch for pragmas and attributes.

Additional C/C++ common testcases are provided in a subsequent patch in the
series.

gcc/cp/ChangeLog:

* decl.cc (omp_declare_variant_finalize_one): Set adjust_args
need_device_ptr attribute.
* parser.cc (cp_parser_direct_declarator): Update call to
cp_parser_late_return_type_opt.
(cp_parser_late_return_type_opt): Add parameter. Update call to
cp_parser_late_parsing_omp_declare_simd.
(cp_parser_omp_clause_name): Handle nocontext and novariants clauses.
(cp_parser_omp_clause_novariants): New function.
(cp_parser_omp_clause_nocontext): Likewise.
(cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_NOVARIANTS and
PRAGMA_OMP_CLAUSE_NOCONTEXT.
(cp_parser_omp_dispatch_body): New function, inspired from
cp_parser_assignment_expression and cp_parser_postfix_expression.
(OMP_DISPATCH_CLAUSE_MASK): Define.
(cp_parser_omp_dispatch): New function.
(cp_finish_omp_declare_variant): Add parameter. Handle adjust_args
clause.
(cp_parser_late_parsing_omp_declare_simd): Add parameter. Update calls
to cp_finish_omp_declare_variant and cp_finish_omp_declare_variant.
(cp_parser_omp_construct): Handle PRAGMA_OMP_DISPATCH.
(cp_parser_pragma): Likewise.
* semantics.cc (finish_omp_clauses): Handle OMP_CLAUSE_NOCONTEXT and
OMP_CLAUSE_NOVARIANTS.

gcc/testsuite/ChangeLog:

* g++.dg/gomp/adjust-args-1.C: New test.
* g++.dg/gomp/adjust-args-2.C: New test.
* g++.dg/gomp/dispatch-1.C: New test.
* g++.dg/gomp/dispatch-2.C: New test.
* g++.dg/gomp/dispatch-3.C: New test.
---
 gcc/cp/decl.cc|   7 +
 gcc/cp/parser.cc  | 644 --
 gcc/cp/semantics.cc   |  20 +
 gcc/testsuite/g++.dg/gomp/adjust-args-1.C |  39 ++
 gcc/testsuite/g++.dg/gomp/adjust-args-2.C |  51 ++
 gcc/testsuite/g++.dg/gomp/dispatch-1.C|  53 ++
 gcc/testsuite/g++.dg/gomp/dispatch-2.C|  62 +++
 gcc/testsuite/g++.dg/gomp/dispatch-3.C|  17 +
 8 files changed, 848 insertions(+), 45 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/gomp/adjust-args-1.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/adjust-args-2.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/dispatch-1.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/dispatch-2.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/dispatch-3.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 07fb9855cd2..e9c489a8d76 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -8403,6 +8403,13 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
  if (!omp_context_selector_matches (ctx))
return true;
  TREE_PURPOSE (TREE_VALUE (attr)) = variant;
+
+ // Prepend adjust_args list to variant attributes
+ tree adjust_args_list = TREE_CHAIN (TREE_CHAIN (chain));
+ if (adjust_args_list != NULL_TREE)
+   DECL_ATTRIBUTES (variant) = tree_cons (
+ get_identifier ("omp declare variant variant adjust_args"),
+ TREE_VALUE (adjust_args_list), DECL_ATTRIBUTES (variant));
}
 }
   else if (!processing_template_decl)
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 0944827d777..ec8bfe1b813 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #include "config.h"
+#include "omp-selectors.h"
 #define INCLUDE_MEMORY
 #include "system.h"
 #include "coretypes.h"
@@ -2591,7 +2592,7 @@ static cp_ref_qualifier cp_parser_ref_qualifier_opt
 static tree cp_parser_tx_qualifier_opt
   (cp_parser *);
 static tree cp_parser_late_return_type_opt
-  (cp_parser *, cp_declarator *, tree &);
+  (cp_parser *, cp_declarator *, tree &, tree);
 static tree cp_parser_declarator_id
   (cp_parser *, bool);
 static tree cp_parser_type_id
@@ -2626,7 +2627,7 @@ static void 
cp_parser_ctor_initializer_opt_and_function_body
   (cp_parser *, bool);
 
 static tree cp_parser_late_parsing_omp_declare_simd
-  (cp_parser *, tree);
+  (cp_parser *, tree, tree);
 
 static tree cp_parser_late_parsing_oacc_routine
   (cp_parser *, tree);
@@ -24260,7 +24261,7 @@ cp_parser_direct_declarator (cp_parser* parser,
  tree requires_clause = NULL_TREE;
  late_return
= cp_parser_late_return_type_opt (parser, declarator,
- requires_clause);
+ requires_clause, params);
 
  cp_finalize_omp_declare_simd (parser, &odsd);
 
@@ -25125,8 +25126,8 @@ parsing_function_declarator ()
function.  */
 
 static tree
-cp_parser_l

[PATCH] Do not call cp_parser_omp_dispatch directly in cp_parser_pragma

2025-01-06 Thread Paul-Antoine Arras
This is a followup to
ed49709acda OpenMP: C++ front-end support for dispatch + adjust_args.

The call to cp_parser_omp_dispatch only belongs in cp_parser_omp_construct. In
cp_parser_pragma, handle PRAGMA_OMP_DISPATCH by calling cp_parser_omp_construct.

gcc/cp/ChangeLog:

* parser.cc (cp_parser_pragma): Replace call to cp_parser_omp_dispatch
with cp_parser_omp_construct.
---
 gcc/cp/parser.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index f548dc31c2b..7434c1d91ba 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -53060,7 +53060,7 @@ cp_parser_pragma (cp_parser *parser, enum 
pragma_context context, bool *if_p)
   break;
 
 case PRAGMA_OMP_DISPATCH:
-  cp_parser_omp_dispatch (parser, pragma_tok);
+  cp_parser_omp_construct (parser, pragma_tok, if_p);
   return true;
 
 case PRAGMA_IVDEP:
-- 
2.45.2



Re: [PATCH] Only apply adjust_args in OpenMP dispatch if variant substitution occurs

2025-01-06 Thread Paul-Antoine Arras
Apologies, I forgot to add the testcase. Please find attached an updated 
patch.


On 06/01/2025 17:12, Paul-Antoine Arras wrote:

This is a followup to
084ea8ad584 OpenMP: middle-end support for dispatch + adjust_args.

This patch fixes a bug that caused arguments in an OpenMP dispatch call to be
modified even when no variant substitution occurred.

gcc/ChangeLog:

* gimplify.cc (gimplify_call_expr): Create variable
variant_substituted_p to control whether adjust_args applies.
---
  gcc/gimplify.cc | 13 +
  1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index bd324be926a..251d581f44c 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -3857,7 +3857,8 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool 
want_value)
enum gimplify_status ret;
int i, nargs;
gcall *call;
-  bool builtin_va_start_p = false, omp_dispatch_p = false;
+  bool builtin_va_start_p = false, omp_dispatch_p = false,
+   variant_substituted_p = false;
location_t loc = EXPR_LOCATION (*expr_p);
  
gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);

@@ -4035,7 +4036,10 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, 
bool want_value)
  {
tree variant = omp_resolve_declare_variant (fndecl);
if (variant != fndecl)
-   CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
+   {
+ CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
+ variant_substituted_p = true;
+   }
  }
  
/* There is a sequence point before the call, so any side effects in

@@ -4325,8 +4329,9 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool 
want_value)
}
}
  
-			  if ((need_device_ptr && !is_device_ptr)

- || (need_device_addr && !has_device_addr))
+ if (variant_substituted_p
+ && ((need_device_ptr && !is_device_ptr)
+ || (need_device_addr && !has_device_addr)))
{
  if (dispatch_device_num == NULL_TREE)
{



--
PAFrom 4d58719cb35b379950767bec8da0446570bd735e Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Mon, 6 Jan 2025 17:00:10 +0100
Subject: [PATCH] Only apply adjust_args in OpenMP dispatch if variant
 substitution occurs

This is a followup to
084ea8ad584 OpenMP: middle-end support for dispatch + adjust_args.

This patch fixes a bug that caused arguments in an OpenMP dispatch call to be
modified even when no variant substitution occurred.

gcc/ChangeLog:

	* gimplify.cc (gimplify_call_expr): Create variable
	variant_substituted_p to control whether adjust_args applies.

gcc/testsuite/ChangeLog:

	* c-c++-common/gomp/adjust-args-4.c: New test.
---
 gcc/gimplify.cc   | 13 ++
 .../c-c++-common/gomp/adjust-args-4.c | 24 +++
 2 files changed, 33 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/gomp/adjust-args-4.c

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index bd324be926a..251d581f44c 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -3857,7 +3857,8 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
   enum gimplify_status ret;
   int i, nargs;
   gcall *call;
-  bool builtin_va_start_p = false, omp_dispatch_p = false;
+  bool builtin_va_start_p = false, omp_dispatch_p = false,
+   variant_substituted_p = false;
   location_t loc = EXPR_LOCATION (*expr_p);
 
   gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
@@ -4035,7 +4036,10 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
 {
   tree variant = omp_resolve_declare_variant (fndecl);
   if (variant != fndecl)
-	CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
+	{
+	  CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
+	  variant_substituted_p = true;
+	}
 }
 
   /* There is a sequence point before the call, so any side effects in
@@ -4325,8 +4329,9 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
 }
 			}
 
-			  if ((need_device_ptr && !is_device_ptr)
-			  || (need_device_addr && !has_device_addr))
+			  if (variant_substituted_p
+			  && ((need_device_ptr && !is_device_ptr)
+  || (need_device_addr && !has_device_addr)))
 			{
 			  if (dispatch_device_num == NULL_TREE)
 {
diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-4.c b/gcc/testsuite/c-c++-common/gomp/adjust-args-4.c
new file mode 100644
index 000..377932e1b9c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/adjust-args-4.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+/* Ensure that adjus

[PATCH] Only apply adjust_args in OpenMP dispatch if variant substitution occurs

2025-01-06 Thread Paul-Antoine Arras
This is a followup to
084ea8ad584 OpenMP: middle-end support for dispatch + adjust_args.

This patch fixes a bug that caused arguments in an OpenMP dispatch call to be
modified even when no variant substitution occurred.

gcc/ChangeLog:

* gimplify.cc (gimplify_call_expr): Create variable
variant_substituted_p to control whether adjust_args applies.
---
 gcc/gimplify.cc | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index bd324be926a..251d581f44c 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -3857,7 +3857,8 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool 
want_value)
   enum gimplify_status ret;
   int i, nargs;
   gcall *call;
-  bool builtin_va_start_p = false, omp_dispatch_p = false;
+  bool builtin_va_start_p = false, omp_dispatch_p = false,
+   variant_substituted_p = false;
   location_t loc = EXPR_LOCATION (*expr_p);
 
   gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
@@ -4035,7 +4036,10 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, 
bool want_value)
 {
   tree variant = omp_resolve_declare_variant (fndecl);
   if (variant != fndecl)
-   CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
+   {
+ CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
+ variant_substituted_p = true;
+   }
 }
 
   /* There is a sequence point before the call, so any side effects in
@@ -4325,8 +4329,9 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool 
want_value)
}
}
 
- if ((need_device_ptr && !is_device_ptr)
- || (need_device_addr && !has_device_addr))
+ if (variant_substituted_p
+ && ((need_device_ptr && !is_device_ptr)
+ || (need_device_addr && !has_device_addr)))
{
  if (dispatch_device_num == NULL_TREE)
{
-- 
2.45.2



[PATCH] Accept commas between clauses in OpenMP declare variant

2025-01-06 Thread Paul-Antoine Arras
Add support to the Fortran parser for the new OpenMP syntax that allows a
comma after the directive name and between clauses of declare variant.
The C and C++ parsers already support this syntax so only a new test is added.

gcc/fortran/ChangeLog:

* openmp.cc (gfc_match_omp_declare_variant): Match comma after directive
name and between clauses.

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/declare-variant-2.f90: Remove error test for a comma
after the directive name.
* c-c++-common/gomp/adjust-args-5.c: New test.
* gfortran.dg/gomp/adjust-args-11.f90: New test.
---
 gcc/fortran/openmp.cc |  4 ++
 .../c-c++-common/gomp/adjust-args-5.c | 21 +
 .../gfortran.dg/gomp/adjust-args-11.f90   | 45 +++
 .../gfortran.dg/gomp/declare-variant-2.f90|  3 --
 4 files changed, 70 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/gomp/adjust-args-5.c
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/adjust-args-11.f90

diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 79c0f1b2e62..9d28dc9 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -6595,6 +6595,10 @@ gfc_match_omp_declare_variant (void)
 
   for (;;)
 {
+  gfc_gobble_whitespace ();
+  gfc_match_char (',');
+  gfc_gobble_whitespace ();
+
   enum clause
   {
match,
diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-5.c 
b/gcc/testsuite/c-c++-common/gomp/adjust-args-5.c
new file mode 100644
index 000..863b77458e4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/adjust-args-5.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+/* Check that the OpenMP 6 syntax with commas after the directive name and
+   between clauses is supported. */
+
+int f (int a, void *b, float c[2]);
+
+#pragma omp declare variant (f), match (construct={dispatch}), adjust_args 
(nothing: a), adjust_args (need_device_ptr: b, c)
+int f0 (int a, void *b, float c[2]);
+
+int test () {
+  int a;
+  void *b;
+  float c[2];
+  struct {int a;} s;
+
+  #pragma omp dispatch, novariants(0), nocontext(1)
+  s.a = f0 (a, b, c);
+
+  return s.a;
+}
diff --git a/gcc/testsuite/gfortran.dg/gomp/adjust-args-11.f90 
b/gcc/testsuite/gfortran.dg/gomp/adjust-args-11.f90
new file mode 100644
index 000..3b26f1b0868
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/adjust-args-11.f90
@@ -0,0 +1,45 @@
+! { dg-do compile }
+
+! Check that the OpenMP 5.1 syntax with commas between clauses is supported.
+! A comma after the directive name is introduced in 5.2, which is not 
supported 
+! yet.
+
+module main
+  use iso_c_binding, only: c_ptr
+  implicit none
+
+  type :: struct
+integer :: a
+real :: b
+  end type
+
+  interface
+integer function f(a, b, c)
+  import c_ptr
+  integer, intent(in) :: a
+  type(c_ptr), intent(inout) :: b
+  type(c_ptr), intent(out) :: c(:)
+end function
+integer function f0(a, b, c)
+  import c_ptr
+  integer, intent(in) :: a
+  type(c_ptr), intent(inout) :: b
+  type(c_ptr), intent(out) :: c(:)
+  !$omp  declare variant (f), match (construct={dispatch}), &
+  !$omp& adjust_args (nothing: a), adjust_args (need_device_ptr: 
b, c)
+end function
+  end interface
+
+contains
+subroutine test
+  integer :: a
+  type(c_ptr) :: b
+  type(c_ptr) :: c(2)
+  type(struct) :: s
+
+  !!$omp dispatch, nocontext(.false.), novariants(.false.)   ! Not supported 
yet
+  !$omp dispatch nocontext(.false.), novariants(.false.)
+  s%a = f0 (a, b, c)
+
+end subroutine
+end module
diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-variant-2.f90 
b/gcc/testsuite/gfortran.dg/gomp/declare-variant-2.f90
index 62d2cb96fac..beea713efba 100644
--- a/gcc/testsuite/gfortran.dg/gomp/declare-variant-2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/declare-variant-2.f90
@@ -182,9 +182,6 @@ contains
   subroutine f74 ()
 !$omp declare variant (f1) match(construct={requires}) ! { dg-warning 
"unknown selector 'requires' for context selector set 'construct' at .1." }
   end subroutine
-  subroutine f75 ()
-!$omp declare variant (f1),match(construct={parallel}) ! { dg-error 
"expected 'match' or 'adjust_args' at .1." }
-  end subroutine
   subroutine f76 ()
 !$omp declare variant (f1) 
match(implementation={atomic_default_mem_order("relaxed")}) ! { dg-error 
"expected identifier at .1." }
   end subroutine
-- 
2.45.2



Re: [PATCH v4 6/7] OpenMP: Fortran front-end support for dispatch + adjust_args

2024-12-30 Thread Paul-Antoine Arras

On 27/12/2024 19:52, Paul-Antoine Arras wrote:

On 23/12/2024 21:04, Tobias Burnus wrote:
For adjust-args-10.f90, I wonder whether it is sufficient as compile- 
time only or whether it makes more sense to have a "dg-do run" to 
check that type(C_ptr) value vs. not-value works. I think either is 
fine, but if it stays in gcc/, can you manually run it once to re- 
check that it works? (I think I did check it and it worked.)


Running adjust-args-10.f90 manually exhibited a bug that no other 
testcase triggered. So I fixed the bug; then moved adjust-args-10.f90 to 
the libgomp testsuite, renamed it to dispatch-3.f90 and made it dg-run.




I forgot to mention, I had to comment out the two allocatables in 
functions f and g, otherwise I would get a segfault upon return. Is that 
correct?


Thanks,
--
PA


Re: [PATCH v4 6/7] OpenMP: Fortran front-end support for dispatch + adjust_args

2024-12-27 Thread Paul-Antoine Arras

Hi Tobias,

On 23/12/2024 21:04, Tobias Burnus wrote:

Paul-Antoine Arras wrote:

Replying to your last two messages here and attaching revised patches.


Regarding the C++ and ME patches:


==> 0003-C-fix.patch <==
Subject: [PATCH 3/4] C++ fix

==> 0004-ME-fixes.patch <==
Subject: [PATCH 4/4] ME fixes


I think it is best to fold them into the Fortran patch; otherwise, they 
would clearly need a better subject line.


Folded everything in one patch.


And for both changes and in either case, both need a ChangeLog entry.


Updated ChangeLog.

Additionally, the middle-end patch does not apply as it doesn't honor my 
Dec 18 change to gimplify.cc.


Rebased and amended accordingly. I believe I did the right thing but 
please have a quick look to be sure.



* * *


==> 0001-OpenMP-Fortran-front-end-support-for-dispatch-adjust.patch <==
Subject: [PATCH 1/4] OpenMP: Fortran front-end support for dispatch +
adjust_args


The following two patches do not work (at least with some testsuite 
testing) as in gcc/testsuite/ neither omp_lib nor libgomp.{so,a} is 
available.


For gcc/testsuite/gfortran.dg/gomp/adjust-args-10.f90, you can just 
remove the 'omp_lib'.


And as gcc/testsuite/gfortran.dg/gomp/declare-variant-21.f90 contains ! 
{ dg-do run }


... I'd suggest to move it to libgomp (including its aux-21.f90 file).


Fixed as suggested.

For adjust-args-10.f90, I wonder whether it is sufficient as compile- 
time only or whether it makes more sense to have a "dg-do run" to check 
that type(C_ptr) value vs. not-value works. I think either is fine, but 
if it stays in gcc/, can you manually run it once to re-check that it 
works? (I think I did check it and it worked.)


Running adjust-args-10.f90 manually exhibited a bug that no other 
testcase triggered. So I fixed the bug; then moved adjust-args-10.f90 to 
the libgomp testsuite, renamed it to dispatch-3.f90 and made it dg-run.



* * *

Note that gcc/testsuite/gfortran.dg/gomp/adjust-args-9.f90 
and ...-10.f90 are missing a ChangeLog entry.


Likewise for dispatch-9a.f90.


Updated ChangeLog.

BTW: If you have applied (committed) the patch locally, run ./contrib/ 
gcc-changelog/git_check_commit.py -v -p — the '-v' will output new files 
that have not been listed as warning and -p shows the patch log for 
checking it. Additionally, it has the usual "git push" checks of GCC.


Thanks for the tip!


* * *

Otherwise, LGTM. Thanks!

[As gimplify.cc couldn't be applied, I have not played with the patch 
but I believe that it should be okay, based on past playing and looking 
at the patch.]


Tobias

PS: Besides fixing the minor issues above, I think you have a follow-up/ 
cleanup patch available addressing some issues related to the C/C++ FE, 
including where the '#pragma' is handled etc. I am looking forward to 
that follow-up patch as well :-)




Yes, I'll post the follow-up patches soon.

Thanks,
--
PAcommit 59c7645e4af84e64141098085e27c39861b32522
Author: Paul-Antoine Arras 
Date:   Fri May 24 19:13:50 2024 +0200

OpenMP: Fortran front-end support for dispatch + adjust_args

This patch adds support for the `dispatch` construct and the `adjust_args`
clause to the Fortran front-end.

Handling of `adjust_args` across translation units is missing due to PR115271.

Minor modifications to the C++ FE and the ME are also folded into this patch as
a side effect of the Fortran work.

gcc/c-family/ChangeLog:

* c-attribs.cc: (c_common_gnu_attributes): Rename "omp declare variant
variant adjust_args" into "omp declare variant variant args" to also
accommodate append_args.

gcc/cp/ChangeLog:

* parser.cc (cp_parser_omp_dispatch): Handle INDIRECT_REF.

gcc/fortran/ChangeLog:

* dump-parse-tree.cc (show_omp_clauses): Handle novariants and nocontext
clauses.
(show_omp_node): Handle EXEC_OMP_DISPATCH.
(show_code_node): Likewise.
* frontend-passes.cc (gfc_code_walker): Handle novariants and nocontext.
* gfortran.h (enum gfc_statement): Add ST_OMP_DISPATCH.
(symbol_attribute): Add omp_declare_variant_need_device_ptr.
(gfc_omp_clauses): Add novariants and nocontext.
(gfc_omp_declare_variant): Add need_device_ptr_arg_list.
(enum gfc_exec_op): Add EXEC_OMP_DISPATCH.
* match.h (gfc_match_omp_dispatch): Declare.
* openmp.cc (gfc_free_omp_clauses): Free novariants and nocontext
clauses.
(gfc_free_omp_declare_variant_list): Free need_device_ptr_arg_list
namelist.
(enum omp_mask2): Add OMP_CLAUSE_NOVARIANTS and OMP_CLAUSE_NOCONTEXT.
(gfc_match_omp_clauses): Handle OMP_CLAUSE_NOVARIANTS and
OMP_CLAUSE_NOCONTEXT.
(OMP_DISPATCH_CLAUSES): De

[PATCH] OpenMP/Fortran: Add missing pop_state in parse_omp_dispatch

2025-01-31 Thread Paul-Antoine Arras
When the ST_NONE case is taken, the function returns immediately. Not calling
pop_state causes a dangling pointer.

gcc/fortran/ChangeLog:

* parse.cc (parse_omp_dispatch): Add missing pop_state.
---
 gcc/fortran/parse.cc | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index 00cd23d7729..5094d9d3ead 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -6375,7 +6375,10 @@ parse_omp_dispatch (void)
 
   st = next_statement ();
   if (st == ST_NONE)
-return st;
+{
+  pop_state ();
+  return st;
+}
   if (st == ST_CALL || st == ST_ASSIGNMENT)
 accept_statement (st);
   else
-- 
2.47.2



Re: [PATCH] OpenMP/Fortran: Add missing pop_state in parse_omp_dispatch

2025-01-31 Thread Paul-Antoine Arras

Pushed to master as obvious. This should fix PR118714.

On 31/01/2025 11:46, Paul-Antoine Arras wrote:

When the ST_NONE case is taken, the function returns immediately. Not calling
pop_state causes a dangling pointer.

gcc/fortran/ChangeLog:

* parse.cc (parse_omp_dispatch): Add missing pop_state.
---
  gcc/fortran/parse.cc | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index 00cd23d7729..5094d9d3ead 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -6375,7 +6375,10 @@ parse_omp_dispatch (void)
  
st = next_statement ();

if (st == ST_NONE)
-return st;
+{
+  pop_state ();
+  return st;
+}
if (st == ST_CALL || st == ST_ASSIGNMENT)
  accept_statement (st);
else



--
PA


Re: [PATCH v4 6/7] OpenMP: Fortran front-end support for dispatch + adjust_args

2024-12-16 Thread Paul-Antoine Arras

Hi Tobias,

See the revised patch attached and my comments below.

On 15/11/2024 14:59, Tobias Burnus wrote:

Hi,

Paul-Antoine Arras wrote:

This patch adds support for the `dispatch` construct and the
`adjust_args` clause to the Fortran front-end.

Handling of `adjust_args` across translation units is missing due
to PR115271.



First, can you add a run-time test?

[I think it helps to have at least one run-time test feature for every
major feature - as we had in the past e.g. C runtime tests and Fortran
compile time tests - but it turned out that some flags was not set,
causing the middle to ignore the feature completely ...]


Added libgomp/testsuite/libgomp.fortran/dispatch-1.f90.


* * *

The following gives an ICE after printing the error (error recovery):

module m
   use iso_c_binding
   implicit none (type, external)
contains
   subroutine foo(x,y)
     !$omp declare variant(bar) match ( construct = { dispatch } )
     type(C_ptr), value :: x, y
   end
   subroutine bar(a,b)
     type(C_ptr), value :: a, b
   end
end

use m
   ! integer, target :: y, z   ! OK
   integer :: y, z  ! ERROR shown but then gives an ICE in 
resolve_omp_dispatch

   !$omp dispatch device(5)
     call foo(c_loc(y),c_loc(z))
end


Fixed error recovery in resolve_omp_dispatch and added testcase.


* * *

The following seems to be valid but gives an error:

Error: argument list item ‘y’ in ‘need_device_ptr’ at (1) must be of 
TYPE(C_PTR)


module m
   use iso_c_binding
   implicit none (type, external)
contains
   subroutine foo(x,y)
     !$omp declare variant(bar) match ( construct = { dispatch } ) 
adjust_args(nothing : x ) adjust_args(need_device_ptr : y )

     type(C_ptr), value :: x, y
   end
   subroutine bar(a,b)
     type(C_ptr), value :: a, b
   end
end

It looks as if the type check is already done during parsing instead
of later during resolve_*.


Renamed gfc_resolve_omp_declare_simd to gfc_resolve_omp_declare and 
moved type(C_ptr) check from gfc_match_omp_declare_variant to there.

Added testcase.


* * *

A duplicate-argument error is missing for 'adjust_args(nothing : x ,x )'
and also for:

module m
   use iso_c_binding
   implicit none (type, external)
contains
   subroutine foo(x,y)
     type(C_ptr), value :: x, y
     !$omp declare variant(bar) match ( construct = { dispatch } ) 
adjust_args(nothing : x ,y ) adjust_args(need_device_ptr : y )

   end
   subroutine bar(a,b)
     type(C_ptr), value :: a, b  ! OK
     ! integer :: a, b   ! wrong type - works & diagnosed (if not ICEing)
   end
end


I think you want to add a flag to 'u' in 'typedef struct 
gfc_omp_namelist' - to set whether an OMP_ LIST_ADJUST_ARGS

is a needs-pointer one or (e.g. unset) a 'nothing' one.

And then also add 'nothing' items to the list.


Added flag as suggested, renamed need_device_ptr_arg_list into 
adjust_args_list and removed nothing_arg_list.

Added testcase.


* * *

The attached testcase shows that you mishandle Fortran calling
conventions (optional, value).

It works for the host (device == -1) but with real offloading,
it segfaults.

(There might be some lang hooks inside trans-openmp* to help
with this; best that you cross check what omp-low.cc does for
'use_device_ptr'.)


Fixed handling of passed-by-reference arguments in gimplify_call_expr.
Added testcase.


* * *

TODO: We need to handle 'type(C), dimension(:)' - but I wonder
whether that shouldn't be handled as part of 'use_device_addr'
and we need to check whether the spec has to be updated.

I filed the OpenMP lang-spec Issue #4443.

* * *

Just a side - no action needed:

We discussed that 'match' is required while 'adjust_args' is
optional.

In C, we had crashes because of a missing 'match' clause;
here it works:

     7 | !$omp declare variant(bar) adjust_args(nothing : x ,x )
   |  1
Error: an ‘adjust_args’ clause at (1) can only be specified if the 
‘dispatch’ selector of the construct selector set appears in the ‘match’ 
clause


Likewise, I think the following error is fine:
     7 | !$omp declare variant(bar)
   |   1
Error: expected ‘match’ or ‘adjust_args’ at (1)


* * *

Otherwise it seems to be okay, but I need to reread it.

Thanks,

Tobias


Thanks,
--
PAcommit e02e75cc9050e42f8887ede95cee56018bc51ad2
Author: Paul-Antoine Arras 
Date:   Fri May 24 19:13:50 2024 +0200

OpenMP: Fortran front-end support for dispatch + adjust_args

This patch adds support for the `dispatch` construct and the `adjust_args`
clause to the Fortran front-end.

Handling of `adjust_args` across translation units is missing due to PR115271.

gcc/fortran/ChangeLog:

* dump-parse-tree.cc (show_omp_clauses): Handle novariants and nocontext
clauses.
(show_omp_node): Handle EXEC_OMP_DISPATCH.

Re: [PATCH v4 2/7] OpenMP: middle-end support for dispatch + adjust_args

2024-12-06 Thread Paul-Antoine Arras

Hi Tobias,

Thanks for your thorough review.

On 09/10/2024 14:55, Tobias Burnus wrote:

Paul-Antoine Arras wrote:

This patch adds middle-end support for the `dispatch` construct and the
`adjust_args` clause. The heavy lifting is done in 
`gimplify_omp_dispatch` and
`gimplify_call_expr` respectively. For `adjust_args`, this mostly 
consists in

emitting a call to `gomp_get_mapped_ptr` for the adequate device.


omp_get_… not gomp_get_…


Fixed.


For dispatch, the following steps are performed:

* Handle the device clause, if any: set the default-device ICV at the 
top of the

dispatch region and restore its previous value at the end.

* Handle novariants and nocontext clauses, if any. Evaluate compile-time
constants and select a variant, if possible. Otherwise, emit code to 
handle all

possible cases at run time.

* If depend clauses are present, add a taskwait construct before the 
dispatch

region and move them there.


The latter is not done here – but already in the front ends, i.e. 
OMP_TASK are handled in part 3 (C), 4 (C++) and 6 (Fortran) of this series.


Forgot to move that during a previous iteration. Fixed now.


...


--- a/gcc/gimple.cc
+++ b/gcc/gimple.cc


...


+/* Build a GIMPLE_OMP_DISPATCH statement.
+
+   BODY is the target function call to be dispatched.
+   CLAUSES are any of the OMP dispatch construct's clauses: ...  */


Looks as if you planned to add something here. How about:
s/: ..././ ?


Right, fixed.



@@ -4067,23 +4069,125 @@ gimplify_call_expr (tree *expr_p, gimple_seq 
*pre_p, bool want_value)



+  if (flag_openmp && EXPR_P (CALL_EXPR_FN (*expr_p))
+  && DECL_P (TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0))
+  && (adjust_args_list = lookup_attribute (
+    "omp declare variant variant adjust_args",
+    DECL_ATTRIBUTES (
+  TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0
+   != NULL_TREE
+  && gimplify_omp_ctxp != NULL
+  && gimplify_omp_ctxp->code == OMP_DISPATCH
+  && !gimplify_omp_ctxp->in_call_args)
+    {


!= should be under 'a' of 'adjust (remove one space)


clang-format is consistently doing it wrong... I have to be careful and 
fix it manually.


And I wonder whether it is a bit more readable and a tiny bit faster if 
you move the gimplify_omp_ctx checks directly after flag_openmp

and only if successfull ('&&') check for the attributes.


Agreed!


+  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
+    {
+  tree decl1 = DECL_NAME (OMP_CLAUSE_DECL (c));
+  tree decl2 = tree_strip_nop_conversions (*arg_p);
+  if (TREE_CODE (decl2) == ADDR_EXPR)
+    decl2 = TREE_OPERAND (decl2, 0);
+  gcc_assert (TREE_CODE (decl2) == VAR_DECL
+  || TREE_CODE (decl2) == PARM_DECL);


The first one can be 'VAR_P (decl2)'. I keep wondering whether there


Changed.


can be cases where that's not true (e.g. VAR_DECL) or some indirect ref.


I don't remember running into such case. I think this is here just for 
extra safety.



For Fortran, I could imagine that array descriptors make problems, e.g.

subroutine f(x)
   integer, pointer :: x(:)

where 'x->data' is the device pointer and not 'x'.

(TODO: something to check + possibly to revisite when handling the 
Fortran part; for now (including C/C++), I think we can leave it as is.)


Or something with reference types (→ C++, Fortran), albeit that's more 
for need_device_addr / has_device_addr, which is not yet implemeted.



+  bool need_device_ptr = false;
+  for (tree arg
+   = TREE_PURPOSE (TREE_VALUE (adjust_args_list));
+   arg != NULL; arg = TREE_CHAIN (arg))
+    {


...


+    }
+
+  if (need_device_ptr && !is_device_ptr)


Actually, the is_device_ptr loop is only needed when need_device_ptr 
(or, later, need_device_addr) is true; I wonder whether it should be 
swapped and is_device_ptr only be checked conditionally?


Good point! Changed as suggested.


+  *arg_p = (TREE_CODE (*arg_p) == NOP_EXPR)
+ ? TREE_OPERAND (*arg_p, 0)
+ : *arg_p;


Use tree_strip_nop_conversions or STRIP_NOPS ? However, it is not clear 
why it is needed here ...


Correct, it is not needed here. Removed.


+  gimplify_arg (arg_p, pre_p, loc);
+  gimplify_arg (&device_num, pre_p, loc);
+  call = gimple_build_call (fn, 2, *arg_p, device_num);
+  tree mapped_arg
+    = create_tmp_var (gimple_call_return_type (call));
+  gimple_call_set_lhs (call, mapped_arg);
+  gimplify_seq_add_stmt (pre_p, call);
+
+  *arg_p = mapped_arg;


This line causes the following 

Re: [PATCH] Accept commas between clauses in OpenMP declare variant

2025-01-13 Thread Paul-Antoine Arras

Hi Tobias,

Here are an updated patch and a few questions.

On 07/01/2025 13:18, Tobias Burnus wrote:

Paul-Antoine Arras:

Add support to the Fortran parser for the new OpenMP syntax that allows a
comma after the directive name and between clauses of declare variant.
The C and C++ parsers already support this syntax so only a new test 
is added.


Note: only the optional comma between directive name and (first) clause
is new (since 5.2). The one between clauses is old (since OpenMP 2.5).

While the patch supports both, 'new OpenMP syntax' is a bit misleading.

For 'declare variant', the comma-between-clauses support is now required
as only with 5.1 and this patch set, more clauses ('adjust_args' and
'append_args') are supported.

This second type of comma (between directive and first clause) is
supported in C/C++ since OpenMP 5.1; I think mainly because of the
added [[omp::directive(...)]] C++11 attribute feature.

In Fortran, this comma is only permitted since 5.2; I think mostly
for consistency with C/C++.


I rephrased the commit message by just removing "new". Should it be more 
detailed?



* * *

BTW: Adding support for this comma for all directives is tracked as
to-be-done Fortran item for 5.2 (under other features as Appendix B
does not list it.)
→ https://gcc.gnu.org/onlinedocs/libgomp/OpenMP-5_002e2.html

* * *



--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -6595,6 +6595,10 @@ gfc_match_omp_declare_variant (void)
    for (;;)
  {
+  gfc_gobble_whitespace ();
+  gfc_match_char (',');
+  gfc_gobble_whitespace ();
+


I think that will do, but having a better error would be IMHO better.

For the first fail, we get:

    13 | !$omp declare variant(f) ,,match(construct={dispatch}) 
adjust_args(need_device_ptr : c)

   |   1
Error: expected ‘match’ or ‘adjust_args’ at (1)

which is quite helpful. But moving the ,, later gives:


    13 | !$omp declare variant(f) 
match(construct={dispatch}),,adjust_args(need_device_ptr : c)

   |   1
Error: Invalid character in name at (1)

That's kind of helpful but not really useful.

And adding a valid but not yet supported clause (it's supported for C/C++):

    13 | !$omp declare variant(f) 
match(construct={dispatch}),adjust_args(need_device_ptr : c),append_args(a)

   |   1
Error: Unclassifiable statement at (1)


I think it would be better to replace the first_p by, e.g.,
'error_p = true; break;' – and do the this diagnostic
after the for(;;) loop. This seems to yield a better diagnostic.


I am not sure I am getting that part. Is this what you are suggesting?

diff --git gcc/fortran/openmp.cc gcc/fortran/openmp.cc
index 9d28dc9..e3abbeeef98 100644
--- gcc/fortran/openmp.cc
+++ gcc/fortran/openmp.cc
@@ -6532,7 +6532,6 @@ gfc_match_omp_context_selector_specification 
(gfc_omp_declare_variant *odv)

 match
 gfc_match_omp_declare_variant (void)
 {
-  bool first_p = true;
   char buf[GFC_MAX_SYMBOL_LEN + 1];

   if (gfc_match (" (") != MATCH_YES)
@@ -6590,7 +6589,7 @@ gfc_match_omp_declare_variant (void)
   return MATCH_ERROR;
 }

-  bool has_match = false, has_adjust_args = false;
+  bool has_match = false, has_adjust_args = false, error_p = false;
   locus adjust_args_loc;

   for (;;)
@@ -6614,13 +6613,9 @@ gfc_match_omp_declare_variant (void)
}
   else
{
- if (first_p)
-   {
- gfc_error ("expected % or % at %C");
- return MATCH_ERROR;
-   }
- else
-   break;
+ if (!has_match)
+   error_p = true;
+ break;
}

   if (gfc_match (" (") != MATCH_YES)
@@ -,8 +6661,12 @@ gfc_match_omp_declare_variant (void)
for (gfc_omp_namelist *n = *head; n != NULL; n = n->next)
  n->u.need_device_ptr = true;
}
+}

-  first_p = false;
+  if (error_p)
+{
+  gfc_error ("expected % or % at %C");
+  return MATCH_ERROR;
 }

   if (has_adjust_args && !has_match)

==

If so, it does yield a better diagnostic ("expected 'match' or 
'adjust_args' at (1)") for this testcase; but it completely breaks other 
cases where the rest of the line is non empty. For instance, with an 
end-of-line comment:


   29 |  !$omp declare variant (f0) adjust_args (nothing: a) ! 
{ dg-error "an 'adjust_args' clause at .1. can only be specified if the 
'dispatch' selector of the construct selector set appears in the 'match' 
clause" }

  |  1


* * *

diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-5.c b/gcc/ 
testsuite/c-c++-common/gomp/adjust-args-5.c

new file mode 10

Re: [PATCH v4 6/7] OpenMP: Fortran front-end support for dispatch + adjust_args

2025-01-13 Thread Paul-Antoine Arras

On 13/01/2025 14:57, Tobias Burnus wrote:

Hi PA,

Paul-Antoine Arras wrote:

Here is an updated patch following your suggestion.


Thanks. It is not clear whether you are just waiting
for test result or not before committing it as obvious.

Thus, just in case: LGTM.

Thanks,

Tobias



Thanks for the final approval. It is now in mainline.

Best,
--
PA


Re: [PATCH v4 6/7] OpenMP: Fortran front-end support for dispatch + adjust_args

2025-01-13 Thread Paul-Antoine Arras

Hi Thomas,

On 08/01/2025 10:04, Thomas Schwinge wrote:

Hi Paul-Antoine!

On 2024-12-16T19:35:01+0100, Paul-Antoine Arras  wrote:

On 15/11/2024 14:59, Tobias Burnus wrote:

Paul-Antoine Arras wrote:

This patch adds support for the `dispatch` construct and the
`adjust_args` clause to the Fortran front-end.

Handling of `adjust_args` across translation units is missing due
to PR115271.



First, can you add a run-time test?

[I think it helps to have at least one run-time test feature for every
major feature - as we had in the past e.g. C runtime tests and Fortran
compile time tests - but it turned out that some flags was not set,
causing the middle to ignore the feature completely ...]


Added libgomp/testsuite/libgomp.fortran/dispatch-1.f90.


I see this new test case FAIL (execution test SIGSEGV) for most (but not
all) offloading configurations, both GCN and nvptx:

 +PASS: libgomp.fortran/dispatch-1.f90   -O  (test for excess errors)
 +FAIL: libgomp.fortran/dispatch-1.f90   -O  execution test


Thanks for pointing that out! The testcase missed an OpenMP target 
directive. The attached patch should fix it.


Best,

PA


For example:

 [...]
 Thread 1 "a.out" received signal SIGSEGV, Segmentation fault.
 0x004022fc in procedures::bar (d_bv=0x7fffc7002040, 
d_av=0x7fffc700, n=1024) at 
source-gcc/libgomp/testsuite/libgomp.fortran/dispatch-1.f90:59
 59fp_bv(i) = fp_av(i) * i
 (gdb) bt
 #0  0x004022fc in procedures::bar (d_bv=0x7fffc7002040, 
d_av=0x7fffc700, n=1024) at 
source-gcc/libgomp/testsuite/libgomp.fortran/dispatch-1.f90:59
 #1  0x00401c41 in procedures::test (n=1024) at 
source-gcc/libgomp/testsuite/libgomp.fortran/dispatch-1.f90:86
 #2  0x00402b1e in MAIN__ () at 
source-gcc/libgomp/testsuite/libgomp.fortran/dispatch-1.f90:115
 (gdb) print i
 $1 = 1
 (gdb) print fp_bv
 $2 = (0, , ...)
 (gdb) print fp_av
 $3 = (0, , ...)
 (gdb) print fp_bv(1)
 $4 = 0
 (gdb) print fp_av(1)
 $5 = 0
 (gdb) ptype fp_bv
 type = real(kind=8) (1024)
 (gdb) ptype fp_av
 type = real(kind=8) (1024)
 (gdb) up
 #1  0x00401c41 in procedures::test (n=1024) at 
source-gcc/libgomp/testsuite/libgomp.fortran/dispatch-1.f90:86
 86!$omp dispatch nocontext(n > 1024) novariants(n < 1024) 
device(last_dev)
 (gdb) print last_dev
 $6 = 0


Grüße
  Thomas



--- /dev/null
+++ libgomp/testsuite/libgomp.fortran/dispatch-1.f90
@@ -0,0 +1,120 @@
+module procedures
+  use iso_c_binding, only: c_ptr, c_f_pointer
+  use omp_lib
+  implicit none
+
+  contains
+
+  function foo(bv, av, n) result(res)
+implicit none
+integer :: res, n, i
+type(c_ptr) :: bv
+type(c_ptr) :: av
+real(8), pointer :: fp_bv(:), fp_av(:)  ! Fortran pointers for array access
+!$omp declare variant(bar) match(construct={dispatch}) 
adjust_args(need_device_ptr: bv, av)
+!$omp declare variant(baz) match(implementation={vendor(gnu)})
+
+! Associate C pointers with Fortran pointers
+call c_f_pointer(bv, fp_bv, [n])
+call c_f_pointer(av, fp_av, [n])
+
+! Perform operations using Fortran pointers
+do i = 1, n
+  fp_bv(i) = fp_av(i) * i
+end do
+res = -1
+  end function foo
+
+  function baz(d_bv, d_av, n) result(res)
+implicit none
+integer :: res, n, i
+type(c_ptr) :: d_bv
+type(c_ptr) :: d_av
+real(8), pointer :: fp_bv(:), fp_av(:)  ! Fortran pointers for array access
+
+! Associate C pointers with Fortran pointers
+call c_f_pointer(d_bv, fp_bv, [n])
+call c_f_pointer(d_av, fp_av, [n])
+
+!$omp distribute parallel do
+do i = 1, n
+  fp_bv(i) = fp_av(i) * i
+end do
+res = -3
+  end function baz
+
+  function bar(d_bv, d_av, n) result(res)
+implicit none
+integer :: res, n, i
+type(c_ptr) :: d_bv
+type(c_ptr) :: d_av
+real(8), pointer :: fp_bv(:), fp_av(:)  ! Fortran pointers for array access
+
+! Associate C pointers with Fortran pointers
+call c_f_pointer(d_bv, fp_bv, [n])
+call c_f_pointer(d_av, fp_av, [n])
+
+! Perform operations on target
+do i = 1, n
+  fp_bv(i) = fp_av(i) * i
+end do
+res = -2
+  end function bar
+
+  function test(n) result(res)
+use iso_c_binding, only: c_ptr, c_loc
+implicit none
+integer :: n, res, i, f, ff, last_dev
+real(8), allocatable, target :: av(:), bv(:), d_bv(:)
+real(8), parameter :: e = 2.71828d0
+type(c_ptr) :: c_av, c_bv, c_d_bv
+
+allocate(av(n), bv(n), d_bv(n))
+
+! Initialize arrays
+do i = 1, n
+  av(i) = e * i
+  bv(i) = 0.0d0
+  d_bv(i) = 0.0d0
+end do
+
+last_dev = omp_get_num_devices() - 1
+
+c_av = c_loc(av)
+c_d_bv = c_loc(d_bv)
+!$omp target data map(to: av(:n)) map(from: d_bv(:n)) device(last_dev) 
if(n == 1024)
+  !$omp dispatch nocontext(n > 1024) novariants(n < 1024) device(last_dev)

Re: [PATCH v4 6/7] OpenMP: Fortran front-end support for dispatch + adjust_args

2025-01-13 Thread Paul-Antoine Arras

Hi Tobias,

On 13/01/2025 13:24, Tobias Burnus wrote:

Hi PA,

Paul-Antoine Arras wrote:

Hi Thomas,

Added libgomp/testsuite/libgomp.fortran/dispatch-1.f90.

I see this new test case FAIL (execution test SIGSEGV) for most (but not
all) offloading configurations, both GCN and nvptx:

 +PASS: libgomp.fortran/dispatch-1.f90   -O  (test for excess 
errors)

 +FAIL: libgomp.fortran/dispatch-1.f90   -O  execution test


Thanks for pointing that out! The testcase missed an OpenMP target 
directive. The attached patch should fix it.


…


--- libgomp/testsuite/libgomp.fortran/dispatch-1.f90
+++ libgomp/testsuite/libgomp.fortran/dispatch-1.f90
@@ -55,6 +55,7 @@ module procedures
  call c_f_pointer(d_av, fp_av, [n])
  ! Perform operations on target
+    !$omp target is_device_ptr(fp_bv, fp_av)
  do i = 1, n
    fp_bv(i) = fp_av(i) * i
  end do


I think the patch is okay in the sense that it works;
still, I think you should consider the following.

Using 'is_device_ptr' for for an argument that
is not a type(c_ptr) is deprecated since OpenMP 5.1 and
removed from the specification since OpenMP 6.0.

Thus, it would be a bit cleaner (and might avoid future
-Wdeprecated warnings) using
    has_device_addr(fp_bv, fp_av) instead. (5.1 semantic states that 
this replacement happens automatically when the is_device_ptr argument 
is not a C_PTR.) Albeit it feels a bit cleaner to move the device 
pointer handling to the device side, i.e. implicit none integer :: res, 
n, i type(c_ptr) :: d_bv type(c_ptr) :: d_av !$omp target 
is_device_ptr(d_bv, d_av) block real(8), pointer :: fp_bv(:), fp_av(:) ! 
Fortran pointers for array access ! Associate C pointers with Fortran 
pointers call c_f_pointer(d_bv, fp_bv, [n]) call c_f_pointer(d_av, 
fp_av, [n]) ! Perform operations on target do i = 1, n fp_bv(i) = 
fp_av(i) * i end do end block However, as all variants work in practice, 
I don't feel strong about it, with a small preference of a variant that 
does not use deprecated features. (Both dispatch and the has_device_addr 
clause/the deprecation are new with OpenMP 5.1) Tobias




Here is an updated patch following your suggestion.

Thanks,
--
PAcommit c76b5ebf73201074cdf07842097a297e7ae4e9c5
Author: Paul-Antoine Arras 
Date:   Mon Jan 13 12:57:15 2025 +0100

Add missing target directive in OpenMP dispatch Fortran runtime test

Without the target directive, the test would run on the host but still try to
use device pointers, which causes a segfault.

libgomp/ChangeLog:

* testsuite/libgomp.fortran/dispatch-1.f90: Add missing target
directive.

diff --git libgomp/testsuite/libgomp.fortran/dispatch-1.f90 libgomp/testsuite/libgomp.fortran/dispatch-1.f90
index 7b2f03f9d68..f56477e4972 100644
--- libgomp/testsuite/libgomp.fortran/dispatch-1.f90
+++ libgomp/testsuite/libgomp.fortran/dispatch-1.f90
@@ -48,16 +48,21 @@ module procedures
 integer :: res, n, i
 type(c_ptr) :: d_bv
 type(c_ptr) :: d_av
-real(8), pointer :: fp_bv(:), fp_av(:)  ! Fortran pointers for array access
 
-! Associate C pointers with Fortran pointers
-call c_f_pointer(d_bv, fp_bv, [n])
-call c_f_pointer(d_av, fp_av, [n])
+!$omp target is_device_ptr(d_bv, d_av)
+block
+  real(8), pointer :: fp_bv(:), fp_av(:)  ! Fortran pointers for array access
+
+  ! Associate C pointers with Fortran pointers
+  call c_f_pointer(d_bv, fp_bv, [n])
+  call c_f_pointer(d_av, fp_av, [n])
+
+  ! Perform operations on target
+  do i = 1, n
+fp_bv(i) = fp_av(i) * i
+  end do
+end block
 
-! Perform operations on target
-do i = 1, n
-  fp_bv(i) = fp_av(i) * i
-end do
 res = -2
   end function bar
 


Re: [PATCH] Accept commas between clauses in OpenMP declare variant

2025-01-13 Thread Paul-Antoine Arras

On 13/01/2025 16:51, Tobias Burnus wrote:

Hi PA,

Paul-Antoine Arras wrote:

I am not sure I am getting that part. Is this what you are suggesting?


Yes, something like that, but not quite, as you found out.

I think we need something like the following (untested):


diff --git gcc/fortran/openmp.cc gcc/fortran/openmp.cc
index 9d28dc9..e3abbeeef98 100644
--- gcc/fortran/openmp.cc
+++ gcc/fortran/openmp.cc
@@ -6532,7 +6532,6 @@ gfc_match_omp_context_selector_specification 
(gfc_omp_declare_variant *odv)

 match
 gfc_match_omp_declare_variant (void)
 {
-  bool first_p = true;
   char buf[GFC_MAX_SYMBOL_LEN + 1];

   if (gfc_match (" (") != MATCH_YES)
@@ -6590,7 +6589,7 @@ gfc_match_omp_declare_variant (void)
   return MATCH_ERROR;
 }

-  bool has_match = false, has_adjust_args = false;
+  bool has_match = false, has_adjust_args = false, error_p = false;
   locus adjust_args_loc;

   for (;;)
@@ -6614,13 +6613,9 @@ gfc_match_omp_declare_variant (void)
 }
   else
 {
-  if (first_p)
-    {
-  gfc_error ("expected % or % at %C");
-  return MATCH_ERROR;
-    }
-  else
-    break;
+  if (!has_match)



if (gfc_match_omp_eos () != MATCH_YES)



Yes, exactly what I was missing!


+ error_p = true;
+  break;
 }

   if (gfc_match (" (") != MATCH_YES)
@@ -,8 +6661,12 @@ gfc_match_omp_declare_variant (void)
 for (gfc_omp_namelist *n = *head; n != NULL; n = n->next)
   n->u.need_device_ptr = true;
 }
+    }

-  first_p = false;
+  if (error_p)



if (error || (!has_match && !has_adjust_args))

as the missing 'match' is handled more explicitly by the next error.


Right.


+ {
+  gfc_error ("expected % or % at %C");
+  return MATCH_ERROR;
 }


* * *

The rest looks good to me.

Thanks,

Tobias




Applied, tested and committed.

Thanks,
--
PA


Re: [PATCH v4 7/7] OpenMP: update documentation for dispatch and adjust_args

2025-01-03 Thread Paul-Antoine Arras

Committing this last patch in the set as obvious (and approved off list).

On 02/10/2024 18:55, Paul-Antoine Arras wrote:

libgomp/ChangeLog:

* libgomp.texi:
---
  libgomp/libgomp.texi | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index c6464ece32e..7026f32f867 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -294,8 +294,8 @@ The OpenMP 4.5 specification is fully supported.
  @item C/C++'s @code{declare variant} directive: elision support of
preprocessed code @tab N @tab
  @item @code{declare variant}: new clauses @code{adjust_args} and
-  @code{append_args} @tab N @tab
-@item @code{dispatch} construct @tab N @tab
+  @code{append_args} @tab P @tab Only @code{adjust_args}
+@item @code{dispatch} construct @tab Y @tab
  @item device-specific ICV settings with environment variables @tab Y @tab
  @item @code{assume} and @code{assumes} directives @tab Y @tab
  @item @code{nothing} directive @tab Y @tab



--
PA


Re: [PATCH v4 6/7] OpenMP: Fortran front-end support for dispatch + adjust_args

2024-12-23 Thread Paul-Antoine Arras

Hi Tobias,

Replying to your last two messages here and attaching revised patches.

On 16/12/2024 22:34, Tobias Burnus wrote:

I have not looked in depth at the patch, but managed to
write C-ism code, which caused a segfault (due to a missing "call"),
after gfortran issued a reasonable error. Can you fix it
and, just to make sure, add it as another testcase?

foo.f90:18:7:

   18 |  g(a,b,c)
  |   1
Error: ‘g’ at (1) is not a variable
foo.f90:20:3:

   20 | end
  |   1
Error: Unexpected END statement at (1)

Segmentation fault

* * *

The problem seems to be that during parsing,
the location data is NULL, which the error diagnostic
does not like:

(gdb) p gfc_current_locus
$33 = {nextc = 0x0, u = {lb = 0x0, location = 0}}

(gdb) p gfc_at_eof()
$36 = true

and st == ST_NONE.

I think the simplest is to check for the last one,
and then return early. This will then print:

foo.f90:18:7:

   18 |  g(a,b,c)
  |   1
Error: ‘g’ at (1) is not a variable
foo.f90:20:3:

   20 | end
  |   1
Error: Unexpected END statement at (1)
f951: Error: Unexpected end of file in ‘foo.f90’

When the if st is ST_NONE then return check is added:

+static gfc_statement
+parse_omp_dispatch (void)
+{
...
+  st = next_statement ();
+  if (st == ST_NONE)
+return st;
+  if (st == ST_CALL || st == ST_ASSIGNMENT)
+accept_statement (st);
+  else


Fixed as suggested. Added testcase.


* * *


   Handling of `adjust_args` across translation units is missing due to 
PR115271.


Namely, https://gcc.gnu.org/PR115271 is about not storing 'declare variant' 
inside
module files; when repeating the decl in an interface, it obviously works as

* * *

I think the patch is now okay, but I want to re-read it tomorrow - thus, please
hold off for a couple of ours.

Possibly, others have comments as well :-)

* * *


TODO: We need to handle 'type(C), dimension(:)' - but I wonder
whether that shouldn't be handled as part of 'use_device_addr'
and we need to check whether the spec has to be updated.

I filed the OpenMP lang-spec Issue #4443.

... and we eventually have to handle 'need_device_addr'/'has_device_addr', but 
those are follow-up topics.


Keeping an eye on the open issue.

On 17/12/2024 14:11, Tobias Burnus wrote:

Additional comments: Can you hoist the condition out of the loop in:

+ for (gfc_omp_namelist *n = *head; n != NULL; n = n->next) + if 
(need_device_ptr_p) + n->u.need_device_ptr = true; 


Sure.


* * *

I was about to complain that it didn't handle VALUE + OPTIONAL
correctly, but that's a generic gfortran bug (or two):
  ->https://gcc.gnu.org/PR118080

* * *

There is a bug - 'nowait' is not propagated. Trying:

   !$omp dispatch depend(inout:x) nowait
 call g(a)
   !$omp end dispatch

gives (-fdump-tree-gimple):  #pragma omp taskwait depend(inout:&x) nowait 
but doing the equivalent !$omp dispatch depend(inout:x) call g(a) !$omp 
end dispatch nowait gives: #pragma omp taskwait depend(inout:&x) i.e. 
the 'nowait' got lost. * * *


Fixed and added testcase.


Similar the original C code, which to my knowledge is now
fixed + tested for, there is an issue related to handling nested
function calls.

I think the attached testcase is fine, but it segfaults unless
the default device is the initial device. The problem is that
the pointer conversion also happens for the inner function but
it should only do so for the outer one.

See attached testcase. – I think it can be seen by looking at the
dump (and adding an -fdump-tree-gimple + scan test probably won't
harm, as not everyone has a GPU and we might implement map as
selfmap on APUs).


This is actually not specific to the Fortran FE. So I had to modify the 
middle end and the C++ parser as well. See attached pactches.



Otherwise LGTM.

Tobias



Thanks,
--
PAFrom e470fc10269d9bb0a4b263c18f03e289973807c4 Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Fri, 24 May 2024 19:13:50 +0200
Subject: [PATCH 1/4] OpenMP: Fortran front-end support for dispatch +
 adjust_args

This patch adds support for the `dispatch` construct and the `adjust_args`
clause to the Fortran front-end.

Handling of `adjust_args` across translation units is missing due to PR115271.

gcc/fortran/ChangeLog:

	* dump-parse-tree.cc (show_omp_clauses): Handle novariants and nocontext
	clauses.
	(show_omp_node): Handle EXEC_OMP_DISPATCH.
	(show_code_node): Likewise.
	* frontend-passes.cc (gfc_code_walker): Handle novariants and nocontext.
	* gfortran.h (enum gfc_statement): Add ST_OMP_DISPATCH.
	(symbol_attribute): Add omp_declare_variant_need_device_ptr.
	(gfc_omp_clauses): Add novariants and nocontext.
	(gfc_omp_declare_variant): Add need_device_ptr_arg_list.
	(enum gfc_exec_op): Add EXEC_OMP_DISPATCH.
	* match.h (gfc_match_omp_dispatch): Declare.
	* openmp.cc (gfc_free_omp_clauses): Free novariants and nocontext
	clauses.
	(gfc_free

Re: [PATCH] Do not call cp_parser_omp_dispatch directly in cp_parser_pragma

2025-01-10 Thread Paul-Antoine Arras

Hi Tobias,

On 07/01/2025 12:13, Tobias Burnus wrote:

Paul-Antoine Arras wrote:

This is a followup to
ed49709acda OpenMP: C++ front-end support for dispatch + adjust_args.

The call to cp_parser_omp_dispatch only belongs in 
cp_parser_omp_construct. In
cp_parser_pragma, handle PRAGMA_OMP_DISPATCH by calling 
cp_parser_omp_construct.


I think this change is good - but not sufficient. For instance,
the following gives an ICE:

void k();
struct t {
  #pragma omp dispatch
   k();
};

I think that's context == pragma_member.



This amended patch checks the context and adds the suggested testcase.

Thanks,
--
PAcommit 7f91528dc54d260a489c749a8c5ccc004a96bfac
Author: Paul-Antoine Arras 
Date:   Mon Jan 6 16:06:43 2025 +0100

Do not call cp_parser_omp_dispatch directly in cp_parser_pragma

This is a followup to
ed49709acda OpenMP: C++ front-end support for dispatch + adjust_args.

The call to cp_parser_omp_dispatch only belongs in cp_parser_omp_construct. In
cp_parser_pragma, handle PRAGMA_OMP_DISPATCH by calling cp_parser_omp_construct.

gcc/cp/ChangeLog:

* parser.cc (cp_parser_pragma): Replace call to cp_parser_omp_dispatch
with cp_parser_omp_construct.

gcc/testsuite/ChangeLog:

* g++.dg/gomp/dispatch-8.C: New test.

diff --git gcc/cp/parser.cc gcc/cp/parser.cc
index f548dc31c2b..e28c23141c0 100644
--- gcc/cp/parser.cc
+++ gcc/cp/parser.cc
@@ -53060,7 +53060,9 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
   break;
 
 case PRAGMA_OMP_DISPATCH:
-  cp_parser_omp_dispatch (parser, pragma_tok);
+  if (context != pragma_stmt && context != pragma_compound)
+	goto bad_stmt;
+  cp_parser_omp_construct (parser, pragma_tok, if_p);
   return true;
 
 case PRAGMA_IVDEP:
diff --git gcc/testsuite/g++.dg/gomp/dispatch-8.C gcc/testsuite/g++.dg/gomp/dispatch-8.C
new file mode 100644
index 000..b8e8e73db1f
--- /dev/null
+++ gcc/testsuite/g++.dg/gomp/dispatch-8.C
@@ -0,0 +1,10 @@
+// { dg-do compile }
+
+// Check that an appropriate diagnostic is emitted when a dispatch directive
+// appears in a pragma_member context.
+
+void k();
+struct t {
+ #pragma omp dispatch  // { dg-error "expected declaration specifiers before end of line" }
+  k();  // { dg-error ".*" }
+};


Re: [PATCH] OpenMP: 'interop' construct - add ME support + target-independent libgomp

2025-03-23 Thread Paul-Antoine Arras

Thanks Sandra and Jakub for your comments.

Here is attached an updated version of the patch:

* Removed special case for n==1, now use an array even when only one 
interop object is passed.

* Updated scan dumps; added C/C++ disjunction where needed.
* Updated the signature of GOMP_interop to actual rather than generic types.
* Renamed 'nowait' argument into 'flags' to allow for future extension.
* Added comments.
* Fixed style and formatting.
--
PAFrom 971aff0b218e6dfc0215d3fd04bfa24aded61532 Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras 
Date: Thu, 13 Mar 2025 17:16:41 +0100
Subject: [PATCH] OpenMP: 'interop' construct - add ME support +
 target-independent libgomp

This patch partially enables use of the OpenMP interop construct by adding
middle end support, mostly in the omplower pass, and in the target-independent
part of the libgomp runtime. It follows up on previous patches for C, C++ and
Fortran front ends support. The full interop feature requires another patch to
enable foreign runtime support in libgomp plugins.

gcc/ChangeLog:

	* builtin-types.def
	(BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR): New.
	* gimple-low.cc (lower_stmt): Handle GIMPLE_OMP_INTEROP.
	* gimple-pretty-print.cc (dump_gimple_omp_interop): New function.
	(pp_gimple_stmt_1): Handle GIMPLE_OMP_INTEROP.
	* gimple.cc (gimple_build_omp_interop): New function.
	(gimple_copy): Handle GIMPLE_OMP_INTEROP.
	* gimple.def (GIMPLE_OMP_INTEROP): Define.
	* gimple.h (gimple_build_omp_interop): Declare.
	(gimple_omp_interop_clauses): New function.
	(gimple_omp_interop_clauses_ptr): Likewise.
	(gimple_omp_interop_set_clauses): Likewise.
	(gimple_return_set_retval): Handle GIMPLE_OMP_INTEROP.
	* gimplify.cc (gimplify_scan_omp_clauses): Handle OMP_CLAUSE_INIT,
	OMP_CLAUSE_USE and OMP_CLAUSE_DESTROY.
	(gimplify_omp_interop): New function.
	(gimplify_expr): Replace sorry with call to gimplify_omp_interop.
	* omp-builtins.def (BUILT_IN_GOMP_INTEROP): Define.
	* omp-low.cc (scan_sharing_clauses): Handle OMP_CLAUSE_INIT,
	OMP_CLAUSE_USE and OMP_CLAUSE_DESTROY.
	(scan_omp_1_stmt): Handle GIMPLE_OMP_INTEROP.
	(lower_omp_interop_action_clauses): New function.
	(lower_omp_interop): Likewise.
	(lower_omp_1): Handle GIMPLE_OMP_INTEROP.

gcc/c/ChangeLog:

	* c-parser.cc (c_parser_omp_clause_destroy): Make addressable.
	(c_parser_omp_clause_init): Make addressable.

gcc/cp/ChangeLog:

	* parser.cc (cp_parser_omp_clause_init): Make addressable.

gcc/fortran/ChangeLog:

	* trans-openmp.cc (gfc_trans_omp_clauses): Make OMP_CLAUSE_DESTROY and
	OMP_CLAUSE_INIT addressable.
	* types.def (BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR):
	New.

include/ChangeLog:

	* gomp-constants.h (GOMP_DEVICE_DEFAULT_OMP_61): Define.
	(GOMP_INTEROP_FLAG_TARGET): Define.
	(GOMP_INTEROP_FLAG_TARGETSYNC): Define.

libgomp/ChangeLog:

	* icv-device.c (omp_set_default_device): Check
	GOMP_DEVICE_DEFAULT_OMP_61.
	* libgomp-plugin.h (struct interop_obj_t): New.
	(enum gomp_interop_flag): New.
	(GOMP_OFFLOAD_interop): Declare.
	(GOMP_OFFLOAD_get_interop_int): Declare.
	(GOMP_OFFLOAD_get_interop_ptr): Declare.
	(GOMP_OFFLOAD_get_interop_str): Declare.
	(GOMP_OFFLOAD_get_interop_type_desc): Declare.
	* libgomp.h (_LIBGOMP_OMP_LOCK_DEFINED): Define.
	(struct gomp_device_descr): Add interop_func, get_interop_int_func,
	get_interop_ptr_func, get_interop_str_func, get_interop_type_desc_func.
	* libgomp.map: Add GOMP_interop.
	* libgomp_g.h (GOMP_interop): Declare.
	* target.c (resolve_device): Handle GOMP_DEVICE_DEFAULT_OMP_61.
	(omp_get_interop_int): Replace stub with actual implementation.
	(omp_get_interop_ptr): Likewise.
	(omp_get_interop_str): Likewise.
	(omp_get_interop_type_desc): Likewise.
	(struct interop_data_t): Define.
	(gomp_interop_internal): New function.
	(GOMP_interop): Likewise.
	(gomp_load_plugin_for_device): Load symbols for get_interop_int,
	get_interop_ptr, get_interop_str and get_interop_type_desc.
	* testsuite/libgomp.c-c++-common/interop-1.c: New test.

gcc/testsuite/ChangeLog:

	* c-c++-common/gomp/interop-1.c: Remove dg-prune-output "sorry".
	* c-c++-common/gomp/interop-2.c: Likewise.
	* c-c++-common/gomp/interop-3.c: Likewise.
	* c-c++-common/gomp/interop-4.c: Remove dg-message "not supported".
	* g++.dg/gomp/interop-5.C: Likewise.
	* gfortran.dg/gomp/interop-4.f90: Likewise.
	* c-c++-common/gomp/interop-5.c: New test.
	* gfortran.dg/gomp/interop-5.f90: New test.

Co-authored-by: Tobias Burnus 
---
 gcc/builtin-types.def |   3 +
 gcc/c/c-parser.cc |   6 +-
 gcc/cp/parser.cc  |   1 +
 gcc/fortran/trans-openmp.cc   |  20 +-
 gcc/fortran/types.def |   3 +
 gcc/gimple-low.cc |   1 +
 gcc/gimple-pretty-print.cc|  23 ++
 gcc/gimple.cc |  18 ++
 gcc/gimple.def   

Re: [PATCH] OpenMP: 'interop' construct - add ME support + target-independent libgomp

2025-03-24 Thread Paul-Antoine Arras

On 21/03/2025 20:17, Sandra Loosemore wrote:

On 3/21/25 11:35, Paul-Antoine Arras wrote:

Thanks Sandra and Jakub for your comments.

Here is attached an updated version of the patch:

* Removed special case for n==1, now use an array even when only one 
interop object is passed.

* Updated scan dumps; added C/C++ disjunction where needed.
* Updated the signature of GOMP_interop to actual rather than generic 
types.

* Renamed 'nowait' argument into 'flags' to allow for future extension.
* Added comments.
* Fixed style and formatting.


I have one more nit about this interface:

+/* Process the OpenMP interop directive. 'init' and 'destroy' take an 
array

+   of 'omp_interop_t *', 'use' an array of 'omp_interop_t', where
+   'omp_interop_t' is internally 'struct interop_obj_t *';
+   'flag' is used for the 'nowait' clause.  */
+
+void
+GOMP_interop (int device_num, int n_init, struct interop_obj_t ***init,
+  const int *target_targetsync, const char **prefer_type, int 
n_use,

+  struct interop_obj_t **use, int n_destroy,
+  struct interop_obj_t ***destroy, unsigned int flags,
+  void **depend)


Is it possible to make the init and destroy arrays const?  I think the 
right C syntax for that would be "struct interop_obj_t ** const * 
init" (I admit I always find this syntax confusing, though, so don't 
take my word for it without checking).


Basically, I'm thinking that if you have #pragma omp dispatch with a 
variant call that implicitly constructs/destructs omp_interop_t objects, 
we ought to be able to pass the same array to both GOMP_interop calls 
and know that the constructor call doesn't clobber the contents of the 
array itself (only the objects its elements point to.)  And if you have 
such a thing in a loop, the optimizers ought to be able to hoist the 
array initialization completely out of the loop so that it only happens 
once.


Likewise I think prefer_type could be declared as "const char * const 
prefer_type"?


Does the attached patch reflect what you have in mind?

If so, I guess I can commit it soon.
--
PAdiff --git libgomp/libgomp_g.h libgomp/libgomp_g.h
index 8993ec610fb..274f4937680 100644
--- libgomp/libgomp_g.h
+++ libgomp/libgomp_g.h
@@ -359,9 +359,10 @@ extern void GOMP_teams (unsigned int, unsigned int);
 extern bool GOMP_teams4 (unsigned int, unsigned int, unsigned int, bool);
 extern void *GOMP_target_map_indirect_ptr (void *);
 struct interop_obj_t;
-extern void GOMP_interop (int, int, struct interop_obj_t ***, const int *,
-			  const char **, int, struct interop_obj_t **, int,
-			  struct interop_obj_t ***, unsigned, void **);
+extern void GOMP_interop (int, int, struct interop_obj_t **const *, const int *,
+			  const char *const *, int, struct interop_obj_t **,
+			  int, struct interop_obj_t **const *, unsigned,
+			  void **);
 
 /* teams.c */
 
diff --git libgomp/target.c libgomp/target.c
index 36ed797b0a9..54c244e0f13 100644
--- libgomp/target.c
+++ libgomp/target.c
@@ -5279,11 +5279,11 @@ ialias (omp_get_interop_rc_desc)
 struct interop_data_t
 {
   int device_num, n_init, n_use, n_destroy;
-  struct interop_obj_t ***init;
+  struct interop_obj_t **const *init;
   struct interop_obj_t **use;
-  struct interop_obj_t ***destroy;
+  struct interop_obj_t **const *destroy;
   const int *target_targetsync;
-  const char **prefer_type;
+  const char *const *prefer_type;
 };
 
 static void
@@ -5348,10 +5348,10 @@ gomp_interop_internal (void *data)
'flags' is used for the 'nowait' clause.  */
 
 void
-GOMP_interop (int device_num, int n_init, struct interop_obj_t ***init,
-	  const int *target_targetsync, const char **prefer_type, int n_use,
-	  struct interop_obj_t **use, int n_destroy,
-	  struct interop_obj_t ***destroy, unsigned int flags,
+GOMP_interop (int device_num, int n_init, struct interop_obj_t **const *init,
+	  const int *target_targetsync, const char *const *prefer_type,
+	  int n_use, struct interop_obj_t **use, int n_destroy,
+	  struct interop_obj_t **const *destroy, unsigned int flags,
 	  void **depend)
 {
   struct interop_data_t args;


Re: [PATCH] OpenMP: 'interop' construct - add ME support + target-independent libgomp

2025-03-24 Thread Paul-Antoine Arras

Hi Thomas,

On 24/03/2025 13:47, Thomas Schwinge wrote:

On 2025-03-21T18:35:57+0100, Paul-Antoine Arras  wrote:

--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/interop-5.f90
@@ -0,0 +1,21 @@
+! { dg-additional-options "-fdump-tree-omplower" }
+
+subroutine sub1 (a1, a2, a3, a4)
+   use omp_lib, only: omp_interop_kind


 [...]/gfortran.dg/gomp/interop-5.f90:4:8: Fatal Error: Cannot open module 
file 'omp_lib.mod' for reading at (1): No such file or directory
 compilation terminated.
 compiler exited with status 1
 FAIL: gfortran.dg/gomp/interop-5.f90   -O  (test for excess errors)

As other files state:

 ! The following definitions are in omp_lib, which cannot be included
 ! in gcc/testsuite/


Thanks for pointing that out! The attached patch should fix it.

If no one objects, I'll commit it shortly.

Best,


+   integer(omp_interop_kind) :: a1  ! by ref
+   integer(omp_interop_kind), optional :: a2 ! as pointer
+   integer(omp_interop_kind), allocatable :: a3 ! ref to pointer
+   integer(omp_interop_kind), value :: a4
+   integer(omp_interop_kind) :: b
+
+   !$omp interop init(target : a1, a2, a3, a4, b)
+   ! { dg-final { scan-tree-dump-times "void \\* interopobjs\.\[0-9\]+\\\[5\\\];\[\r\n ]*integer\\(kind=4\\) 
tgt_tgtsync\.\[0-9\]+\\\[5\\\];\[\r\n ]*integer\\(kind=8\\) \\* & a3\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* 
D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* a2\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) & a1\.\[0-9\]+;\[\r\n 
]*interopobjs\.\[0-9\]+\\\[0\\\] = &b;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[0\\\] = 1;\[\r\n 
]*interopobjs\.\[0-9\]+\\\[1\\\] = &a4;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[1\\\] = 1;\[\r\n ]*a3\.\[0-9\]+ = a3;\[\r\n 
]*D\.\[0-9\]+ = \\*a3\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[2\\\] = D\.\[0-9\]+;\[\r\n 
]*tgt_tgtsync\.\[0-9\]+\\\[2\\\] = 1;\[\r\n ]*a2\.\[0-9\]+ = a2;\[\r\n ]*interopobjs\.\[0-9\]+\\\[3\\\] = 
a2\.\[0-9\]+;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[3\\\] = 1;\[\r\n ]*a1\.\[0-9\]+ = a1;\[\r\n ]*interopobjs\.\[0-9\]+\\\[4\\\] 
= a1\.\[0-9\]+;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[4\\\] = 1;\[\r\n ]*__builtin_GOMP_interop \\(-5, 5, 
&interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, 0B, 0, 0B, 0, 0B, 0, 0B\\);" 1 "omplower" } }
+
+   !$omp interop use(a1, a2, a3, a4, b)
+   ! { dg-final { scan-tree-dump-times "void \\* interopobjs\.\[0-9\]+\\\[5\\\];\[\r\n 
]*integer\\(kind=8\\) b\.\[0-9\]+;\[\r\n ]*void \\* b\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) 
a4\.\[0-9\]+;\[\r\n ]*void \\* a4\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* & a3\.\[0-9\]+;\[\r\n 
]*integer\\(kind=8\\) \\* D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) D\.\[0-9\]+;\[\r\n ]*void \\* 
D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* a2\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) D\.\[0-9\]+;\[\r\n 
]*void \\* D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) & a1\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) 
D\.\[0-9\]+;\[\r\n ]*void \\* D\.\[0-9\]+;\[\r\n ]*b\.\[0-9\]+ = b;\[\r\n ]*b\.\[0-9\]+ = \\(void \\*\\) 
b\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[0\\\] = b\.\[0-9\]+;\[\r\n ]*a4\.\[0-9\]+ = a4;\[\r\n 
]*a4\.\[0-9\]+ = \\(void \\*\\) a4\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[1\\\] = a4\.\[0-9\]+;\[\r\n 
]*a3\.\[0-9\]+ = a3;\[\r\n ]*D\.\[0-9\]+ = \\*a3\.\[0-9\]+;\[\r\n ]*D\.\[0-9\]+ = \\*D\.\[0-9\]+;\[\r\n 
]*D\.\[0-9\]+ = \\(void \\*\\) D\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[2\\\] = D\.\[0-9\]+;\[\r\n 
]*a2\.\[0-9\]+ = a2;\[\r\n ]*D\.\[0-9\]+ = \\*a2\.\[0-9\]+;\[\r\n ]*D\.\[0-9\]+ = \\(void \\*\\) 
D\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[3\\\] = D\.\[0-9\]+;\[\r\n ]*a1\.\[0-9\]+ = a1;\[\r\n 
]*D\.\[0-9\]+ = \\*a1\.\[0-9\]+;\[\r\n ]*D\.\[0-9\]+ = \\(void \\*\\) D\.\[0-9\]+;\[\r\n 
]*interopobjs\.\[0-9\]+\\\[4\\\] = D\.\[0-9\]+;\[\r\n ]*__builtin_GOMP_interop \\(-5, 0, 0B, 0B, 0B, 5, 
&interopobjs\.\[0-9\]+, 0, 0B, 0, 0B\\);" 1 "omplower" } }
+
+   !$omp interop destroy(a1, a2, a3, a4, b)
+   ! { dg-final { scan-tree-dump-times "void \\* interopobjs\.\[0-9\]+\\\[5\\\];\[\r\n ]*integer\\(kind=8\\) \\* 
& a3\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* a2\.\[0-9\]+;\[\r\n 
]*integer\\(kind=8\\) & a1\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[0\\\] = &b;\[\r\n 
]*interopobjs\.\[0-9\]+\\\[1\\\] = &a4;\[\r\n ]*a3\.\[0-9\]+ = a3;\[\r\n ]*D\.\[0-9\]+ = \\*a3\.\[0-9\]+;\[\r\n 
]*interopobjs\.\[0-9\]+\\\[2\\\] = D\.\[0-9\]+;\[\r\n ]*a2\.\[0-9\]+ = a2;\[\r\n ]*interopobjs\.\[0-9\]+\\\[3\\\] = 
a2\.\[0-9\]+;\[\r\n ]*a1\.\[0-9\]+ = a1;\[\r\n ]*interopobjs\.\[0-9\]+\\\[4\\\] = a1\.\[0-9\]+;\[\r\n 
]*__builtin_GOMP_interop \\(-5, 0, 0B, 0B, 0B, 0, 0B, 5, &interopobjs\.\[0-9\]+, 0, 0B\\);" 1 
"omplower" } }
+end subroutine



--
PA
diff --git gcc/testsuite/gfortran.dg/gomp/interop-5.f90 gcc/testsuite/gfortran.dg/gomp/interop-5.f90
index a6a2d719189..f669cb7c68b 100644
--- gcc/testsuite/gfortran.dg/gomp/interop-5.f90
+++ gcc/tes

Re: [PATCH] OpenMP: 'interop' construct - add ME support + target-independent libgomp

2025-03-24 Thread Paul-Antoine Arras
Here is a patch that encompasses the modifications requested by Sandra 
and Thomas, as well as a fix for 32-bit pointers.


OK for trunk?
--
PAcommit b1b634d5d3c35682b65edacecf7a4749221f5728
Author: Paul-Antoine Arras 
Date:   Mon Mar 24 15:53:36 2025 +0100

OpenMP: interop - make arrays const and fix Fortran test

This fixes up commit r15-8654-g99e2906ae255fc:
* Treat the arrays passed to GOMP_interop as const.
* Do not use omp_lib in Fortran compile test; instead, provide needed
declarations explicitly.
* Update scan-dump patterns to be compatible with 32-bit architectures.

libgomp/ChangeLog:

* libgomp_g.h (GOMP_interop): Make arrays const.
* target.c (struct interop_data_t): Likewise.
(GOMP_interop): Likewise.

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/interop-5.f90: Declare omp_interop_kind explicitly
instead of use'ing omp_lib. Update scan-dumps to allow for 4-byte
pointers.

diff --git gcc/testsuite/gfortran.dg/gomp/interop-5.f90 gcc/testsuite/gfortran.dg/gomp/interop-5.f90
index a6a2d719189..a08eeb83f71 100644
--- gcc/testsuite/gfortran.dg/gomp/interop-5.f90
+++ gcc/testsuite/gfortran.dg/gomp/interop-5.f90
@@ -1,7 +1,13 @@
 ! { dg-additional-options "-fdump-tree-omplower" }
 
 subroutine sub1 (a1, a2, a3, a4)
-   use omp_lib, only: omp_interop_kind
+   use iso_c_binding
+   implicit none
+
+   ! The following definitions are in omp_lib, which cannot be included
+   ! in gcc/testsuite/
+   integer, parameter :: omp_interop_kind = c_intptr_t
+
integer(omp_interop_kind) :: a1  ! by ref
integer(omp_interop_kind), optional :: a2 ! as pointer
integer(omp_interop_kind), allocatable :: a3 ! ref to pointer
@@ -9,13 +15,13 @@ subroutine sub1 (a1, a2, a3, a4)
integer(omp_interop_kind) :: b
 
!$omp interop init(target : a1, a2, a3, a4, b)
-   ! { dg-final { scan-tree-dump-times "void \\* interopobjs\.\[0-9\]+\\\[5\\\];\[\r\n ]*integer\\(kind=4\\) tgt_tgtsync\.\[0-9\]+\\\[5\\\];\[\r\n ]*integer\\(kind=8\\) \\* & a3\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* a2\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) & a1\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[0\\\] = &b;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[0\\\] = 1;\[\r\n ]*interopobjs\.\[0-9\]+\\\[1\\\] = &a4;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[1\\\] = 1;\[\r\n ]*a3\.\[0-9\]+ = a3;\[\r\n ]*D\.\[0-9\]+ = \\*a3\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[2\\\] = D\.\[0-9\]+;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[2\\\] = 1;\[\r\n ]*a2\.\[0-9\]+ = a2;\[\r\n ]*interopobjs\.\[0-9\]+\\\[3\\\] = a2\.\[0-9\]+;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[3\\\] = 1;\[\r\n ]*a1\.\[0-9\]+ = a1;\[\r\n ]*interopobjs\.\[0-9\]+\\\[4\\\] = a1\.\[0-9\]+;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[4\\\] = 1;\[\r\n ]*__builtin_GOMP_interop \\(-5, 5, &interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, 0B, 0, 0B, 0, 0B, 0, 0B\\);" 1 "omplower" } }
+   ! { dg-final { scan-tree-dump-times "void \\* interopobjs\.\[0-9\]+\\\[5\\\];\[\r\n ]*integer\\(kind=4\\) tgt_tgtsync\.\[0-9\]+\\\[5\\\];\[\r\n ]*integer\\(kind=\[48\]\\) \\* & a3\.\[0-9\]+;\[\r\n ]*integer\\(kind=\[48\]\\) \\* D\.\[0-9\]+;\[\r\n ]*integer\\(kind=\[48\]\\) \\* a2\.\[0-9\]+;\[\r\n ]*integer\\(kind=\[48\]\\) & a1\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[0\\\] = &b;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[0\\\] = 1;\[\r\n ]*interopobjs\.\[0-9\]+\\\[1\\\] = &a4;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[1\\\] = 1;\[\r\n ]*a3\.\[0-9\]+ = a3;\[\r\n ]*D\.\[0-9\]+ = \\*a3\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[2\\\] = D\.\[0-9\]+;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[2\\\] = 1;\[\r\n ]*a2\.\[0-9\]+ = a2;\[\r\n ]*interopobjs\.\[0-9\]+\\\[3\\\] = a2\.\[0-9\]+;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[3\\\] = 1;\[\r\n ]*a1\.\[0-9\]+ = a1;\[\r\n ]*interopobjs\.\[0-9\]+\\\[4\\\] = a1\.\[0-9\]+;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[4\\\] = 1;\[\r\n ]*__builtin_GOMP_interop \\(-5, 5, &interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, 0B, 0, 0B, 0, 0B, 0, 0B\\);" 1 "omplower" } }
 
!$omp interop use(a1, a2, a3, a4, b)
-   ! { dg-final { scan-tree-dump-times "void \\* interopobjs\.\[0-9\]+\\\[5\\\];\[\r\n ]*integer\\(kind=8\\) b\.\[0-9\]+;\[\r\n ]*void \\* b\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) a4\.\[0-9\]+;\[\r\n ]*void \\* a4\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* & a3\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) D\.\[0-9\]+;\[\r\n ]*void \\* D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* a2\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) D\.\[0-9\]+;\[\r\n ]*void \\* D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) & a1\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) D\.\[0-9\]+;\[\r\n ]*void \\* D\.\[0-9\]+;\[\r\n ]*b\.\[0-9\]+ = b;\[\r\n ]*b\.\[0-9\]+ = \\(void \\*\\) b\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[0\\\] = b\.\[0-9\]+;\[\r\n ]*a4\.\[0-9\]+ = a4;\[\r\n ]*a4\.\[0-

[PATCH] OpenMP: 'interop' construct - add ME support + target-independent libgomp

2025-04-05 Thread Paul-Antoine Arras
This patch partially enables use of the OpenMP interop construct by adding
middle end support, mostly in the omplower pass, and in the target-independent
part of the libgomp runtime. It follows up on previous patches for C, C++ and
Fortran front ends support. The full interop feature requires another patch to
enable foreign runtime support in libgomp plugins.

gcc/ChangeLog:

* builtin-types.def
(BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR): New.
* gimple-low.cc (lower_stmt): Handle GIMPLE_OMP_INTEROP.
* gimple-pretty-print.cc (dump_gimple_omp_interop): New function.
(pp_gimple_stmt_1): Handle GIMPLE_OMP_INTEROP.
* gimple.cc (gimple_build_omp_interop): New function.
(gimple_copy): Handle GIMPLE_OMP_INTEROP.
* gimple.def (GIMPLE_OMP_INTEROP): Define.
* gimple.h (gimple_build_omp_interop): Declare.
(gimple_omp_interop_clauses): New function.
(gimple_omp_interop_clauses_ptr): Likewise.
(gimple_omp_interop_set_clauses): Likewise.
(gimple_return_set_retval): Handle GIMPLE_OMP_INTEROP.
* gimplify.cc (gimplify_scan_omp_clauses): Handle OMP_CLAUSE_INIT,
OMP_CLAUSE_USE and OMP_CLAUSE_DESTROY.
(gimplify_omp_interop): New function.
(gimplify_expr): Replace sorry with call to gimplify_omp_interop.
* omp-builtins.def (BUILT_IN_GOMP_INTEROP): Define.
* omp-low.cc (scan_sharing_clauses): Handle OMP_CLAUSE_INIT,
OMP_CLAUSE_USE and OMP_CLAUSE_DESTROY.
(scan_omp_1_stmt): Handle GIMPLE_OMP_INTEROP.
(lower_omp_interop_action_clauses): New function.
(lower_omp_interop): Likewise.
(lower_omp_1): Handle GIMPLE_OMP_INTEROP.

gcc/c/ChangeLog:

* c-parser.cc (c_parser_omp_clause_destroy): Make addressable.
(c_parser_omp_clause_init): Make addressable.

gcc/cp/ChangeLog:

* parser.cc (cp_parser_omp_clause_init): Make addressable.

gcc/fortran/ChangeLog:

* trans-openmp.cc (gfc_trans_omp_clauses): Make OMP_CLAUSE_DESTROY and
OMP_CLAUSE_INIT addressable.
* types.def (BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR):
New.

include/ChangeLog:

* gomp-constants.h (GOMP_DEVICE_DEFAULT_OMP_61): Define.
(GOMP_INTEROP_FLAG_TARGET): Define.
(GOMP_INTEROP_FLAG_TARGETSYNC): Define.

libgomp/ChangeLog:

* icv-device.c (omp_set_default_device): Check
GOMP_DEVICE_DEFAULT_OMP_61.
* libgomp-plugin.h (struct interop_obj_t): New.
(enum gomp_interop_flag): New.
(GOMP_OFFLOAD_interop): Declare.
(GOMP_OFFLOAD_get_interop_int): Declare.
(GOMP_OFFLOAD_get_interop_ptr): Declare.
(GOMP_OFFLOAD_get_interop_str): Declare.
(GOMP_OFFLOAD_get_interop_type_desc): Declare.
* libgomp.h (_LIBGOMP_OMP_LOCK_DEFINED): Define.
(struct gomp_device_descr): Add interop_func, get_interop_int_func,
get_interop_ptr_func, get_interop_str_func, get_interop_type_desc_func.
* libgomp.map: Add GOMP_interop.
* libgomp_g.h (GOMP_interop): Declare.
* target.c (resolve_device): Handle GOMP_DEVICE_DEFAULT_OMP_61.
(omp_get_interop_int): Replace stub with actual implementation.
(omp_get_interop_ptr): Likewise.
(omp_get_interop_str): Likewise.
(omp_get_interop_type_desc): Likewise.
(struct interop_data_t): Define.
(gomp_interop_internal): New function.
(GOMP_interop): Likewise.
(gomp_load_plugin_for_device): Load symbols for get_interop_int,
get_interop_ptr, get_interop_str and get_interop_type_desc.
* testsuite/libgomp.c-c++-common/interop-1.c: New test.

gcc/testsuite/ChangeLog:

* c-c++-common/gomp/interop-1.c: Remove dg-prune-output "sorry".
* c-c++-common/gomp/interop-2.c: Likewise.
* c-c++-common/gomp/interop-3.c: Likewise.
* c-c++-common/gomp/interop-4.c: Remove dg-message "not supported".
* g++.dg/gomp/interop-5.C: Likewise.
* gfortran.dg/gomp/interop-4.f90: Likewise.
* c-c++-common/gomp/interop-5.c: New test.
* gfortran.dg/gomp/interop-5.f90: New test.
---
 gcc/builtin-types.def |   3 +
 gcc/c/c-parser.cc |   6 +-
 gcc/cp/parser.cc  |   1 +
 gcc/fortran/trans-openmp.cc   |  20 +-
 gcc/fortran/types.def |   3 +
 gcc/gimple-low.cc |   1 +
 gcc/gimple-pretty-print.cc|  23 ++
 gcc/gimple.cc |  18 ++
 gcc/gimple.def|   4 +
 gcc/gimple.h  |  33 ++-
 gcc/gimplify.cc   |  20 +-
 gcc/omp-builtins.def  |   3 +
 gcc/omp-low.cc| 274 ++
 gcc/testsuite/c-c++-common/gomp/interop-1.c   |   2 -

Re: [PATCH] OpenMP: 'interop' construct - add ME support + target-independent libgomp

2025-03-25 Thread Paul-Antoine Arras

On 24/03/2025 21:17, Sandra Loosemore wrote:

On 3/24/25 08:20, Paul-Antoine Arras wrote:

On 21/03/2025 20:17, Sandra Loosemore wrote:
Does the attached patch reflect what you have in mind?

diff --git libgomp/libgomp_g.h libgomp/libgomp_g.h
index 8993ec610fb..274f4937680 100644
--- libgomp/libgomp_g.h
+++ libgomp/libgomp_g.h
@@ -359,9 +359,10 @@ extern void GOMP_teams (unsigned int, unsigned int);
 extern bool GOMP_teams4 (unsigned int, unsigned int, unsigned int, 
bool);

 extern void *GOMP_target_map_indirect_ptr (void *);
 struct interop_obj_t;
-extern void GOMP_interop (int, int, struct interop_obj_t ***, const 
int *,

-  const char **, int, struct interop_obj_t **, int,
-  struct interop_obj_t ***, unsigned, void **);
+extern void GOMP_interop (int, int, struct interop_obj_t **const *, 
const int *,

+  const char *const *, int, struct interop_obj_t **,
+  int, struct interop_obj_t **const *, unsigned,
+  void **);

 /* teams.c */

diff --git libgomp/target.c libgomp/target.c
index 36ed797b0a9..54c244e0f13 100644
--- libgomp/target.c
+++ libgomp/target.c
@@ -5279,11 +5279,11 @@ ialias (omp_get_interop_rc_desc)
 struct interop_data_t
 {
   int device_num, n_init, n_use, n_destroy;
-  struct interop_obj_t ***init;
+  struct interop_obj_t **const *init;
   struct interop_obj_t **use;
-  struct interop_obj_t ***destroy;
+  struct interop_obj_t **const *destroy;
   const int *target_targetsync;
-  const char **prefer_type;
+  const char *const *prefer_type;
 };

 static void
@@ -5348,10 +5348,10 @@ gomp_interop_internal (void *data)
    'flags' is used for the 'nowait' clause.  */

 void
-GOMP_interop (int device_num, int n_init, struct interop_obj_t ***init,
-  const int *target_targetsync, const char **prefer_type, int 
n_use,

-  struct interop_obj_t **use, int n_destroy,
-  struct interop_obj_t ***destroy, unsigned int flags,
+GOMP_interop (int device_num, int n_init, struct interop_obj_t 
**const *init,

+  const int *target_targetsync, const char *const *prefer_type,
+  int n_use, struct interop_obj_t **use, int n_destroy,
+  struct interop_obj_t **const *destroy, unsigned int flags,
   void **depend)
 {
   struct interop_data_t args;


I think you also need to update BUILT_IN_GOMP_INTEROP in omp- 
builtins.def; at least, that is the source of the decl used for the 
implicit creation/destruction of interop objects in "declare variant" 
expansion.


I took some time to check how other functions defined in target.c are 
declared in omp-builtins.def. It appears that the convention seems to be 
to omit const qualifiers, except in very simple cases like 
omp_get_mapped_ptr.


Besides, I am not sure how to encode complex types like (**const *). 
Does that require creating new definitions in gcc/builtin-types.def and 
gcc/fortran/types.def?
And what difference does it make to have an argument declared as BT_PTR 
instead of, say, BT_PTR_CONST_PTR_PTR? Is is just a matter of optimisation?

If someone could shed some light...

Thanks,
--
PA


Re: [PATCH] OpenMP: 'interop' construct - add ME support + target-independent libgomp

2025-03-27 Thread Paul-Antoine Arras

On 25/03/2025 18:55, Sandra Loosemore wrote:

On 3/25/25 09:25, Paul-Antoine Arras wrote:

On 24/03/2025 21:17, Sandra Loosemore wrote:
[snip]
Besides, I am not sure how to encode complex types like (**const *). 
Does that require creating new definitions in gcc/builtin-types.def 
and gcc/fortran/types.def?


I don't understand what the Fortran front end has to do with this, 
BUILT_IN_GOMP_INTEROP is only referenced from gimplify.cc and omp-low.cc.


DEF_GOMP_BUILTIN defines builtins for both C/C++ and Fortran. If a type 
definition is missing in gcc/fortran/types.def, you get an error, e.g.:


gcc/fortran/../omp-builtins.def: In function 'void 
gfc_init_builtin_functions()':
gcc/fortran/../omp-builtins.def:406:19: error: 
'BT_FN_VOID_INT_INT_PTRPTRCONSTPTR_CONSTPTR_PTRCONSTSTRING_INT_PTRPTR_INT_PTRPTRCONSTPTR_UINT_PTRPTR' 
was not declared in this scope
  406 | 
BT_FN_VOID_INT_INT_PTRPTRCONSTPTR_CONSTPTR_PTRCONSTSTRING_INT_PTRPTR_INT_PTRPTRCONSTPTR_UINT_PTRPTR,
  | 
^~~
gcc/fortran/f95-lang.cc:1291:60: note: in definition of macro 
'DEF_GOMP_BUILTIN'

 1291 |   gfc_define_builtin ("__builtin_" name, builtin_types[type], \
  |^~~~

And what difference does it make to have an argument declared as 
BT_PTR instead of, say, BT_PTR_CONST_PTR_PTR? Is is just a matter of 
optimisation?

If someone could shed some light...


Well, the declaration used by GCC for code generation should match the 
definition in the library, right?


Mainly, I got to thinking about this because the "declare variant" 
interop creation/destruction code that Tobias had sketched out before 
handing it over to me included a bunch of explicit clobbers that 
confused the heck out of me.  AFAICT, the only thing that GOMP_interop 
needs to modify is the actual interop objects whose pointers are in the 
init/destroy arrays, so in my final version of the code those are the 
only things clobbered after the interop objects are destroyed.  If GCC 
knows the arrays themselves are const, that potentially also enables 
optimizations like hoisting the code to set up the argument arrays out a 
loop containing a variant call.


I updated the patch (see attachment) with that in mind. Let me know what 
you think.

--
PAcommit c379d33e55fb7af4d560ae912b9395e33b723b9f
Author: Paul-Antoine Arras 
Date:   Thu Mar 27 17:01:41 2025 +0100

OpenMP: interop - make arrays const

Treat arrays passed to GOMP_interop as const.

gcc/ChangeLog:

* builtin-types.def (BT_PTR_CONST_PTR_PTR): Define.
(BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR): Define.
* omp-builtins.def (BUILT_IN_GOMP_INTEROP): Update.

gcc/fortran/ChangeLog:

* types.def (BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR):
Define.
(BT_FN_VOID_INT_INT_PTRCONSTPTRPTR_CONSTPTR_PTRCONSTSTRING_INT_PTRPTR_INT_PTRCONSTPTRPTR_UINT_PTRPTR):
Define.

libgomp/ChangeLog:

* libgomp_g.h (GOMP_interop): Make arrays const.
* target.c (struct interop_data_t): Likewise.
(GOMP_interop): Likewise.

diff --git gcc/builtin-types.def gcc/builtin-types.def
index 9583d30dfc0..c7b2e1619d1 100644
--- gcc/builtin-types.def
+++ gcc/builtin-types.def
@@ -221,6 +221,11 @@ DEF_PRIMITIVE_TYPE (BT_PTR_CONST_STRING,
 		 (build_qualified_type (string_type_node,
 	TYPE_QUAL_CONST)))
 
+/* The C type `void **const *'.  */
+DEF_PRIMITIVE_TYPE (BT_PTR_CONST_PTR_PTR,
+		build_pointer_type (build_qualified_type (
+		  build_pointer_type (ptr_type_node), TYPE_QUAL_CONST)))
+
 DEF_POINTER_TYPE (BT_PTR_UINT, BT_UINT)
 DEF_POINTER_TYPE (BT_PTR_LONG, BT_LONG)
 DEF_POINTER_TYPE (BT_PTR_ULONG, BT_ULONG)
@@ -1015,9 +1020,11 @@ DEF_FUNCTION_TYPE_11 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_UINT_LONG_INT_ULL_
 		  BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
 		  BT_UINT, BT_LONG, BT_INT,
 		  BT_ULONGLONG, BT_ULONGLONG, BT_ULONGLONG)
-DEF_FUNCTION_TYPE_11 (BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR,
-		  BT_VOID, BT_INT, BT_INT, BT_PTR, BT_PTR, BT_PTR, BT_INT,
-		  BT_PTR, BT_INT, BT_PTR, BT_UINT, BT_PTR)
+DEF_FUNCTION_TYPE_11 (
+  BT_FN_VOID_INT_INT_PTRCONSTPTRPTR_CONSTPTR_PTRCONSTSTRING_INT_PTRPTR_INT_PTRCONSTPTRPTR_UINT_PTRPTR,
+  BT_VOID, BT_INT, BT_INT, BT_PTR_CONST_PTR_PTR, BT_CONST_PTR,
+  BT_PTR_CONST_STRING, BT_INT, BT_PTR_PTR, BT_INT, BT_PTR_CONST_PTR_PTR,
+  BT_UINT, BT_PTR_PTR)
 
 DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
 DEF_FUNCTION_TYPE_VAR_0 (BT_FN_INT_VAR, BT_INT)
diff --git gcc/fortran/types.def gcc/fortran/types.def
index dd9b8df59be..d68d02e819d 100644
--- gcc/fortran/types.def
+++ gcc/fortran/types.def
@@ -266,7 +266,7 @@ DEF_FUNCTION_TYPE_11

[PATCH] RISC-V: Add pattern for vector-scalar multiply-add/sub [PR119100]

2025-03-27 Thread Paul-Antoine Arras
This pattern enables the combine pass to merge a vec_duplicate into a plus-mult
or minus-mult RTL instruction.

Before this patch, we have two instructions, e.g.:
  vfmv.v.fv6,fa0
  vfmadd.vv   v9,v6,v7

After, we get only one:
  vfmadd.vf   v9,fa0,v7

On SPEC2017's 503.bwaves_r, depending on the workload, the reduction in dynamic
instruction count varies from -4.66% to -4.75%.

gcc/ChangeLog:

PR target/119100
* config/riscv/vector.md (*pred__scalar): Define.
---
 gcc/config/riscv/vector.md | 23 +++
 1 file changed, 23 insertions(+)

diff --git gcc/config/riscv/vector.md gcc/config/riscv/vector.md
index 8ee43cf0ce1..6f538eeefda 100644
--- gcc/config/riscv/vector.md
+++ gcc/config/riscv/vector.md
@@ -6633,6 +6633,29 @@
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
 
+(define_insn_and_split "*pred__scalar"
+  [(set (match_operand:V_VLSF 0 "register_operand""=vd, vr")
+(plus_minus:V_VLSF
+   (mult:V_VLSF
+ (vec_duplicate:V_VLSF
+   (match_operand: 1 "register_operand" "  f,f"))
+ (match_operand:V_VLSF 2 "register_operand"  "  0,0"))
+   (match_operand:V_VLSF 3 "register_operand"" vr,   vr")))]
+  "TARGET_VECTOR"
+  "#"
+  "!reload_completed"
+  [(const_int 0)]
+  {
+rtx ops[] = {operands[0], operands[1], operands[2], operands[3],
+ operands[2]};
+riscv_vector::emit_vlmax_insn (code_for_pred_mul_scalar (, 
mode),
+riscv_vector::TERNARY_OP_FRM_DYN, ops);
+DONE;
+  }
+  [(set_attr "type" "vfmuladd")
+   (set_attr "mode" "")]
+)
+
 (define_insn "*pred__scalar"
   [(set (match_operand:V_VLSF 0 "register_operand""=vd, vr")
(if_then_else:V_VLSF
-- 
2.34.1



Re: [PATCH] RISC-V: Add pattern for vector-scalar multiply-add/sub [PR119100]

2025-04-16 Thread Paul-Antoine Arras

Hi Jeff, Robin,

Thanks for your comments.

On 30/03/2025 01:30, Jeff Law wrote:

On 3/27/25 1:39 PM, Robin Dapp wrote:

Hi Paul-Antoine,

This pattern enables the combine pass to merge a vec_duplicate into a 
plus-mult

or minus-mult RTL instruction.

Before this patch, we have two instructions, e.g.:
  vfmv.v.f    v6,fa0
  vfmadd.vv   v9,v6,v7

After, we get only one:
  vfmadd.vf   v9,fa0,v7

On SPEC2017's 503.bwaves_r, depending on the workload, the reduction 
in dynamic

instruction count varies from -4.66% to -4.75%.


The general issue with this kind of optimization (we have discussed it 
a few times already) is that, depending on the uarch, we want the 
local combine optimization that you show but not the fwprop/late- 
combine one where we propagate a vector broadcast into a loop.


So IMHO in order to continue with this and similar patterns we need at 
least accompanying rtx_cost handling that would allow us to tune per 
uarch.


Please find attached an updated patch with an additional cost model. By 
default, an instruction is 4 and the penalty for moving data from 
floating-point to vector register is 2; thus, vfmadd.vf costs 6, which 
still makes it cheaper than vec_duplicate + vfmadd.vv. Different tuning 
parameters can alter this tradeoff though.


Pan Li sent a similar patch for vadd.vv/vadd.vx I think in November 
and I believe he intended to continue when stage 1 opens.


An outstanding question is how to distinguish the combine case from 
the late-combine case.  I haven't yet thought about that in detail.


I experienced with a few variations around the testcase of the PR. When 
the loop body shrinks, the lower register pressure allows the 
vec_duplicate to be hoisted to the loop preamble. In such cases, I did 
not observe that the vec_duplicate got propagated into the loop body.


The other thing we should consider is that we can certainly theorize 
that this kind of register file crossing case can have an extra penalty 
(it traditionally does), we don't have actual evidence that it's causing 
a problem on any RISC-V designs.


So may be the way to go is add a field to the uarch tuning structure 
indicating the additional cost (if any) of a register file crossing 
vector op of this nature.  Then query that in riscv_rtx_costs or 
whatever our rtx_cost function is named.


Default that additional cost to zero initially.  Then uarch experts can 
fill in the appropriate value.  Yea, such a simplistic approach wouldn't 
handle cases like ours where you really need nearby context to be sure, 
but I don't think we want to over-engineer this solution too badly right 
now.


Note that since this isn't a regression it'll need to wait for gcc-16 
development to open before the patch can go forward.


Thanks!
JEff


ps.  I know Baylibre's remit was to test dynamic icounts and there were 
good reasons for that.  So don't worry about not having run it on 
design.  If you happen to still have executables, pass them along 
privately, I can run them on a BPI.  ROMS is a few hours of runtime, but 
that's not a big deal.


We recently received our own BPI board, so I was able to run 
503.bwaves_r on it. Unfortunately, the DIC reduction does not translate 
into similar execution time gains. The vector-scalar is only faster by 
0.33% on average over 3 iterations.


Thanks,
--
PAcommit b0f1dbf8b4ad12c0eff459d0bf6b3d9c466fd5ad
Author: Paul-Antoine Arras 
Date:   Tue Feb 25 16:38:54 2025 +0100

RISC-V: Add pattern for vector-scalar multiply-add/sub [PR119100]

This pattern enables the combine pass to merge a vec_duplicate into a plus-mult
or minus-mult RTL instruction.

Before this patch, we have two instructions, e.g.:
  vfmv.v.fv6,fa0
  vfmadd.vv   v9,v6,v7

After, we get only one:
  vfmadd.vf   v9,fa0,v7

On SPEC2017's 503.bwaves_r, depending on the workload, the reduction in dynamic
instruction count varies from -4.66% to -4.75%.

gcc/ChangeLog:

PR target/119100
* config/riscv/vector.md (*pred__scalar): Define.
* config/riscv/riscv.cc (riscv_rtx_costs): Add cost for moving data from
a scalar floating-point to a vector register.

diff --git gcc/config/riscv/riscv.cc gcc/config/riscv/riscv.cc
index 38f3ae7cd84..0f0cf04bdd9 100644
--- gcc/config/riscv/riscv.cc
+++ gcc/config/riscv/riscv.cc
@@ -3864,6 +3864,18 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
   if (riscv_v_ext_mode_p (mode))
 {
   *total = COSTS_N_INSNS (1);
+  if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS) && outer_code == SET)
+	{
+	  rtx plus_op0 = XEXP (x, 0);
+	  if (GET_CODE (plus_op0) == MULT)
+	{
+	  rtx mult_op0 = XEXP (plus_op0, 0);
+	  if (GET_CODE (mult_op0) == VEC_DUPLICATE)
+		{
+		  *total += get_vector_costs ()->regmove->FR2VR;
+		}
+	}
+	}