public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
@ 2018-01-23  8:13 Dominique d'Humières
  2018-01-23 17:56 ` Paul Richard Thomas
  0 siblings, 1 reply; 16+ messages in thread
From: Dominique d'Humières @ 2018-01-23  8:13 UTC (permalink / raw)
  To: Paul Richard Thomas
  Cc: jvdelisle, Thomas Koenig, Steve Kargl, gfortran, gcc-patches

Dear Paul,

The test suite passed without new regression with both -m32 and -m64.

Thanks for the work,

Dominique

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-23  8:13 [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15 Dominique d'Humières
@ 2018-01-23 17:56 ` Paul Richard Thomas
  2018-01-23 19:17   ` Thomas Koenig
  0 siblings, 1 reply; 16+ messages in thread
From: Paul Richard Thomas @ 2018-01-23 17:56 UTC (permalink / raw)
  To: Dominique d'Humières
  Cc: jvdelisle, Thomas Koenig, Steve Kargl, gfortran, gcc-patches

Could somebody please review the patch?

Thanks

Paul


On 23 January 2018 at 06:13, Dominique d'Humières
<dominiq@tournesol.lps.ens.fr> wrote:
> Dear Paul,
>
> The test suite passed without new regression with both -m32 and -m64.
>
> Thanks for the work,
>
> Dominique



-- 
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-23 17:56 ` Paul Richard Thomas
@ 2018-01-23 19:17   ` Thomas Koenig
  0 siblings, 0 replies; 16+ messages in thread
From: Thomas Koenig @ 2018-01-23 19:17 UTC (permalink / raw)
  To: Paul Richard Thomas, Dominique d'Humières
  Cc: jvdelisle, Steve Kargl, gfortran, gcc-patches

Hi Paul,

> Could somebody please review the patch?

I'd say the patch is OK for trunk. I have also tested this on
a big-endian system, and things worked.

I will look at the resulting fallout of the GFC_DTYPE_TYPE_SIZE
stuff.

Thanks a lot for your work!

Regards

	Thomas

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-24  9:59           ` Paul Richard Thomas
@ 2018-01-29 13:02             ` Tom de Vries
  0 siblings, 0 replies; 16+ messages in thread
From: Tom de Vries @ 2018-01-29 13:02 UTC (permalink / raw)
  To: Paul Richard Thomas, Jakub Jelinek; +Cc: Janne Blomqvist, fortran, gcc-patches

Hi,

this ( r257065 ) caused: PR84088 - "[nvptx] 
libgomp.oacc-fortran/declare-*.f90 execution fails" ( 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84088 ).

Thanks,
- Tom

On 01/24/2018 10:05 AM, Paul Richard Thomas wrote:
> Hi Jakub,
> 
> The lateness is indeed embarrassing but couldn't be helped.
> 
>> Given above my preference would be to keep version an int, and
>> change rank and type to signed char and attribute to signed short.
>> That way there will be no padding on either 32-bit or 64-bit targets,
>> and the structure will be at least a little bit smaller.
>> How much work would that be to change it in the patch?  I'd expect
>> just a few lines in gcc/fortran and few lines in libgfortran...
>>
>>          Jakub
> 
> I can do that this afternoon. It's little more work than changing a
> couple of typedefs. There are one or two other, cosmetic changes to
> make too.
> 
> Thanks
> 
> Paul
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-24  9:05         ` Jakub Jelinek
@ 2018-01-24  9:59           ` Paul Richard Thomas
  2018-01-29 13:02             ` Tom de Vries
  0 siblings, 1 reply; 16+ messages in thread
From: Paul Richard Thomas @ 2018-01-24  9:59 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Janne Blomqvist, fortran, gcc-patches

Hi Jakub,

The lateness is indeed embarrassing but couldn't be helped.

> Given above my preference would be to keep version an int, and
> change rank and type to signed char and attribute to signed short.
> That way there will be no padding on either 32-bit or 64-bit targets,
> and the structure will be at least a little bit smaller.
> How much work would that be to change it in the patch?  I'd expect
> just a few lines in gcc/fortran and few lines in libgfortran...
>
>         Jakub

I can do that this afternoon. It's little more work than changing a
couple of typedefs. There are one or two other, cosmetic changes to
make too.

Thanks

Paul

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-24  8:41       ` Janne Blomqvist
@ 2018-01-24  9:05         ` Jakub Jelinek
  2018-01-24  9:59           ` Paul Richard Thomas
  0 siblings, 1 reply; 16+ messages in thread
From: Jakub Jelinek @ 2018-01-24  9:05 UTC (permalink / raw)
  To: Janne Blomqvist; +Cc: Paul Richard Thomas, fortran, gcc-patches

On Wed, Jan 24, 2018 at 10:30:41AM +0200, Janne Blomqvist wrote:
> On Tue, Jan 23, 2018 at 10:30 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> > On Tue, Jan 23, 2018 at 07:30:49PM +0000, Paul Richard Thomas wrote:
> >> Janne, Thanks.
> >>
> >> Jakub, is this OK with you?
> >
> > It is indeed quite late for such large ABI changes, some distributions are
> > about to start using the compiler by now.
> 
> Yes, we're (painfully) aware that it's quite late. The motivation is
> that the ABI for GCC 8 has already been broken, and if we get this
> patch in, we hope to avoid having to break it again for the next
> release. See also the discussion thread starting at
> 
> https://gcc.gnu.org/ml/fortran/2018-01/msg00150.html

Ok.

> >  How much was it tested (on which
> > targets)?
> 
> Dominique tested on Darwin, both -m32 and -m64:
> https://gcc.gnu.org/ml/fortran/2018-01/msg00156.html
> 
> Thomas tested on a "big-endian target" (I guess gcc110, that is,
> powerpc64-unknown-linux-gnu.):
> https://gcc.gnu.org/ml/fortran/2018-01/msg00163.html

Good.

> In addition to bumping up the max number of dimensions, another
> motivation is to bring the descriptor closer to the F2018 C
> interoperability descriptor. See
> https://gcc.gnu.org/wiki/ArrayDescriptorUpdate for an overview. One
> idea has been to use this C descriptor as the native GFortran
> descriptor; that might or might not ever happen.
> 
> But yes, the rank, type, and attribute fields could be of type
> (signed/unsigned) char, which would reduce the sizeof(dtype_type) from
> 24 to 16 bytes on a 64-bit target. For the F2018 C descriptor the type
> field must be signed, but currently we're not using the type field in
> the same way. The others can be unsigned or signed.

Given above my preference would be to keep version an int, and
change rank and type to signed char and attribute to signed short.
That way there will be no padding on either 32-bit or 64-bit targets,
and the structure will be at least a little bit smaller.
How much work would that be to change it in the patch?  I'd expect
just a few lines in gcc/fortran and few lines in libgfortran...

	Jakub

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-23 20:54     ` Jakub Jelinek
@ 2018-01-24  8:41       ` Janne Blomqvist
  2018-01-24  9:05         ` Jakub Jelinek
  0 siblings, 1 reply; 16+ messages in thread
From: Janne Blomqvist @ 2018-01-24  8:41 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Paul Richard Thomas, fortran, gcc-patches

On Tue, Jan 23, 2018 at 10:30 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Tue, Jan 23, 2018 at 07:30:49PM +0000, Paul Richard Thomas wrote:
>> Janne, Thanks.
>>
>> Jakub, is this OK with you?
>
> It is indeed quite late for such large ABI changes, some distributions are
> about to start using the compiler by now.

Yes, we're (painfully) aware that it's quite late. The motivation is
that the ABI for GCC 8 has already been broken, and if we get this
patch in, we hope to avoid having to break it again for the next
release. See also the discussion thread starting at

https://gcc.gnu.org/ml/fortran/2018-01/msg00150.html

>  How much was it tested (on which
> targets)?

Dominique tested on Darwin, both -m32 and -m64:
https://gcc.gnu.org/ml/fortran/2018-01/msg00156.html

Thomas tested on a "big-endian target" (I guess gcc110, that is,
powerpc64-unknown-linux-gnu.):
https://gcc.gnu.org/ml/fortran/2018-01/msg00163.html

>  Has the debug info side of things been adjusted too (the
> get_array_descr_info langhook)?

The patch at least modifies this function.

>> >> I took the design choice choice to replace the dtype with a structure:
>> >> typedef struct dtype_type
>> >> {
>> >>   size_t elem_len;
>> >>   int version;
>> >>   int rank;
>> >>   int type;
>> >>   int attribute;
>> >> }
>> >> dtype_type;
>
> Isn't this too wasteful?  rank will be just 0-15, right?
> What values can version have?  What type?  Do you need negative values for
> any of those?
> I think using unsigned char or unsigned short for some of those fields
> should be sufficient, yeah, they don't necessarily need to be bitfields.

In addition to bumping up the max number of dimensions, another
motivation is to bring the descriptor closer to the F2018 C
interoperability descriptor. See
https://gcc.gnu.org/wiki/ArrayDescriptorUpdate for an overview. One
idea has been to use this C descriptor as the native GFortran
descriptor; that might or might not ever happen.

But yes, the rank, type, and attribute fields could be of type
(signed/unsigned) char, which would reduce the sizeof(dtype_type) from
24 to 16 bytes on a 64-bit target. For the F2018 C descriptor the type
field must be signed, but currently we're not using the type field in
the same way. The others can be unsigned or signed.




-- 
Janne Blomqvist

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-23 20:31   ` Paul Richard Thomas
@ 2018-01-23 20:54     ` Jakub Jelinek
  2018-01-24  8:41       ` Janne Blomqvist
  0 siblings, 1 reply; 16+ messages in thread
From: Jakub Jelinek @ 2018-01-23 20:54 UTC (permalink / raw)
  To: Paul Richard Thomas; +Cc: Janne Blomqvist, fortran, gcc-patches

On Tue, Jan 23, 2018 at 07:30:49PM +0000, Paul Richard Thomas wrote:
> Janne, Thanks.
> 
> Jakub, is this OK with you?

It is indeed quite late for such large ABI changes, some distributions are
about to start using the compiler by now.  How much was it tested (on which
targets)?  Has the debug info side of things been adjusted too (the
get_array_descr_info langhook)?

> >> I took the design choice choice to replace the dtype with a structure:
> >> typedef struct dtype_type
> >> {
> >>   size_t elem_len;
> >>   int version;
> >>   int rank;
> >>   int type;
> >>   int attribute;
> >> }
> >> dtype_type;

Isn't this too wasteful?  rank will be just 0-15, right?
What values can version have?  What type?  Do you need negative values for
any of those?
I think using unsigned char or unsigned short for some of those fields
should be sufficient, yeah, they don't necessarily need to be bitfields.

	Jakub

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-23 19:25 ` Janne Blomqvist
@ 2018-01-23 20:31   ` Paul Richard Thomas
  2018-01-23 20:54     ` Jakub Jelinek
  0 siblings, 1 reply; 16+ messages in thread
From: Paul Richard Thomas @ 2018-01-23 20:31 UTC (permalink / raw)
  To: Janne Blomqvist, Jakub Jelinek; +Cc: fortran, gcc-patches

Janne, Thanks.

Jakub, is this OK with you?

Paul

On 23 January 2018 at 19:09, Janne Blomqvist <blomqvist.janne@gmail.com> wrote:
> On Mon, Jan 22, 2018 at 9:12 PM, Paul Richard Thomas
> <paul.richard.thomas@gmail.com> wrote:
>> This patch has been triggered by Thomas's recent message to the list.
>> Not only did I start work late relative to stage 3 but debugging took
>> somewhat longer than anticipated. Therefore, to get this committed
>> asap, we will have to beg the indulgence of the release managers and
>> prompt review and/or testing by fortran maintainers. (Dominique has
>> already undertaken to test -m32.)
>>
>> The patch delivers rank up to 15 for F2008, the descriptor information
>> needed to enact the F2018 C descriptor macros and an attribute field
>> to store such information as pointer/allocatable, contiguous etc..
>> Only the first has been enabled so far but it was necessary to submit
>> the array descriptor changes now to avoid any further ABI breakage in
>> 9.0.0.
>>
>> I took the design choice choice to replace the dtype with a structure:
>> typedef struct dtype_type
>> {
>>   size_t elem_len;
>>   int version;
>>   int rank;
>>   int type;
>>   int attribute;
>> }
>> dtype_type;
>>
>> This choice was intended to reduce the changes to a minimum, since in
>> most references to the dtype, one dtype is assigned to another.
>>
>> The F2018 interop defines the 'type and 'attribute fields to be signed
>> char types. I used this intially but found that using int was the best
>> way to silence the warnings about padding since it also allows for
>> more attribute information to be carried.
>>
>> Some parts of the patch (eg. in get_scalar_to_descriptor_type) look as
>> if latent bugs were uncovered by the change to the descriptor. If so,
>> the time spent debugging was well worthwhile.
>>
>> It should be noted that some of the intrinsics, which use switch/case
>> for the type/kind selection, limit the effective element size that
>> they handle to the maximum value of size_t, less 7 bits. A bit of
>> straightforward work there would fix this limitation and would allow
>> the GFC_DTYPE shifts and masks to be eliminated.
>>
>> Bootstraps and regtests on FC23/x86_64 - OK for trunk?
>
> In trans-types.c:
>
> structure dtype_type dtype;
>
> Should be "struct dtype_type dtype". (This is in a comment, so doesn't
> affect the code, but still).
>
> I have to say, the patch is much smaller and less invasive than I had
> feared for such a fundamental change. I guess you were right about
> making dtype it's own type.
>
> As for the DTYPE shifting and masking thing, now that I have read the
> patch, if I understood it correctly, that's an internal issue in
> libgfortran and has no effect on the descriptor.  That being said, the
> F2018 C descriptor has both the type and kind encoded into the type
> field, see table 18.4 in F2018 N2146. (In a way that's redundant,
> since the type and the elem_len fields suffice to figure out the
> type&kind combination). Anyway, is there a case for following suit,
> and if so, is it a too invasive change at this point?
>
> In any case, since we seem to agree that we have no big lingering
> issues that would require us to break the ABI again for GCC 9, IMHO
> this is Ok for trunk. You might want to get an explicit Ok from the
> release manager, though.
>
> --
> Janne Blomqvist



-- 
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-22 19:46 Paul Richard Thomas
  2018-01-22 20:24 ` Janne Blomqvist
@ 2018-01-23 19:25 ` Janne Blomqvist
  2018-01-23 20:31   ` Paul Richard Thomas
  1 sibling, 1 reply; 16+ messages in thread
From: Janne Blomqvist @ 2018-01-23 19:25 UTC (permalink / raw)
  To: Paul Richard Thomas; +Cc: fortran, gcc-patches

On Mon, Jan 22, 2018 at 9:12 PM, Paul Richard Thomas
<paul.richard.thomas@gmail.com> wrote:
> This patch has been triggered by Thomas's recent message to the list.
> Not only did I start work late relative to stage 3 but debugging took
> somewhat longer than anticipated. Therefore, to get this committed
> asap, we will have to beg the indulgence of the release managers and
> prompt review and/or testing by fortran maintainers. (Dominique has
> already undertaken to test -m32.)
>
> The patch delivers rank up to 15 for F2008, the descriptor information
> needed to enact the F2018 C descriptor macros and an attribute field
> to store such information as pointer/allocatable, contiguous etc..
> Only the first has been enabled so far but it was necessary to submit
> the array descriptor changes now to avoid any further ABI breakage in
> 9.0.0.
>
> I took the design choice choice to replace the dtype with a structure:
> typedef struct dtype_type
> {
>   size_t elem_len;
>   int version;
>   int rank;
>   int type;
>   int attribute;
> }
> dtype_type;
>
> This choice was intended to reduce the changes to a minimum, since in
> most references to the dtype, one dtype is assigned to another.
>
> The F2018 interop defines the 'type and 'attribute fields to be signed
> char types. I used this intially but found that using int was the best
> way to silence the warnings about padding since it also allows for
> more attribute information to be carried.
>
> Some parts of the patch (eg. in get_scalar_to_descriptor_type) look as
> if latent bugs were uncovered by the change to the descriptor. If so,
> the time spent debugging was well worthwhile.
>
> It should be noted that some of the intrinsics, which use switch/case
> for the type/kind selection, limit the effective element size that
> they handle to the maximum value of size_t, less 7 bits. A bit of
> straightforward work there would fix this limitation and would allow
> the GFC_DTYPE shifts and masks to be eliminated.
>
> Bootstraps and regtests on FC23/x86_64 - OK for trunk?

In trans-types.c:

structure dtype_type dtype;

Should be "struct dtype_type dtype". (This is in a comment, so doesn't
affect the code, but still).

I have to say, the patch is much smaller and less invasive than I had
feared for such a fundamental change. I guess you were right about
making dtype it's own type.

As for the DTYPE shifting and masking thing, now that I have read the
patch, if I understood it correctly, that's an internal issue in
libgfortran and has no effect on the descriptor.  That being said, the
F2018 C descriptor has both the type and kind encoded into the type
field, see table 18.4 in F2018 N2146. (In a way that's redundant,
since the type and the elem_len fields suffice to figure out the
type&kind combination). Anyway, is there a case for following suit,
and if so, is it a too invasive change at this point?

In any case, since we seem to agree that we have no big lingering
issues that would require us to break the ABI again for GCC 9, IMHO
this is Ok for trunk. You might want to get an explicit Ok from the
release manager, though.

-- 
Janne Blomqvist

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-23  4:44     ` Jerry DeLisle
@ 2018-01-23 19:06       ` Thomas Koenig
  0 siblings, 0 replies; 16+ messages in thread
From: Thomas Koenig @ 2018-01-23 19:06 UTC (permalink / raw)
  To: Jerry DeLisle, Janne Blomqvist, Paul Richard Thomas; +Cc: fortran, gcc-patches

Hi Jerry,

> Do you mean adding something like this:
> 
> diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
> index 4c643b7e17b..c86e0b45e1d 100644
> --- a/libgfortran/libgfortran.h
> +++ b/libgfortran/libgfortran.h
> @@ -600,6 +600,7 @@ typedef struct st_parameter_common
>     GFC_INTEGER_4 line;
>     CHARACTER2 (iomsg);
>     GFC_INTEGER_4 *iostat;
> +  void *reserved;
>   }
>   st_parameter_common;

Yes, this is what I had in mind.

Regards

	Thomas

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-22 21:10   ` Thomas Koenig
@ 2018-01-23  4:44     ` Jerry DeLisle
  2018-01-23 19:06       ` Thomas Koenig
  0 siblings, 1 reply; 16+ messages in thread
From: Jerry DeLisle @ 2018-01-23  4:44 UTC (permalink / raw)
  To: Thomas Koenig, Janne Blomqvist, Paul Richard Thomas; +Cc: fortran, gcc-patches

On 01/22/2018 12:24 PM, Thomas Koenig wrote:
> Am 22.01.2018 um 20:59 schrieb Janne Blomqvist:
>> On Mon, Jan 22, 2018 at 9:12 PM, Paul Richard Thomas
>> <paul.richard.thomas@gmail.com> wrote:
>>> This patch has been triggered by Thomas's recent message to the list.
>>> Not only did I start work late relative to stage 3 but debugging took
>>> somewhat longer than anticipated. Therefore, to get this committed
>>> asap, we will have to beg the indulgence of the release managers and
>>> prompt review and/or testing by fortran maintainers. (Dominique has
>>> already undertaken to test -m32.)
>>
>> I think that if we can "guarantee" that we're happy with the current
>> ABI for GCC 9 (and hopefully 10, 11, ...?) we have a quite strong case
>> for committing it now. But if anybody if planning on doing some
>> ABI-breaking work in the foreseeable future then maybe we should wait
>> until GCC 9 stage1 opens. Anybody with such plans?
> 
> For asynchronous I/O, we could add a pointer to void (unused at
> present) for later use.  That's all from my side.
> 

Do you mean adding something like this:

diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index 4c643b7e17b..c86e0b45e1d 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -600,6 +600,7 @@ typedef struct st_parameter_common
   GFC_INTEGER_4 line;
   CHARACTER2 (iomsg);
   GFC_INTEGER_4 *iostat;
+  void *reserved;
 }
 st_parameter_common;

and the corresponding front end side.
> ---- snip --

Regarding Paul's patch, assuming the -m32 tests can be confirmed I think the
patch should go in now.

Jerry

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-22 20:24 ` Janne Blomqvist
  2018-01-22 21:10   ` Thomas Koenig
@ 2018-01-22 23:03   ` Steve Kargl
  1 sibling, 0 replies; 16+ messages in thread
From: Steve Kargl @ 2018-01-22 23:03 UTC (permalink / raw)
  To: Janne Blomqvist; +Cc: Paul Richard Thomas, fortran, gcc-patches

On Mon, Jan 22, 2018 at 09:59:41PM +0200, Janne Blomqvist wrote:
> On Mon, Jan 22, 2018 at 9:12 PM, Paul Richard Thomas
> <paul.richard.thomas@gmail.com> wrote:
> > This patch has been triggered by Thomas's recent message to the list.
> > Not only did I start work late relative to stage 3 but debugging took
> > somewhat longer than anticipated. Therefore, to get this committed
> > asap, we will have to beg the indulgence of the release managers and
> > prompt review and/or testing by fortran maintainers. (Dominique has
> > already undertaken to test -m32.)
> 
> I think that if we can "guarantee" that we're happy with the current
> ABI for GCC 9 (and hopefully 10, 11, ...?) we have a quite strong case
> for committing it now. But if anybody if planning on doing some
> ABI-breaking work in the foreseeable future then maybe we should wait
> until GCC 9 stage1 opens. Anybody with such plans?
> 

I don't have any plans to break the ABI in 9.0.  OTOH, if the
patch isn't included in 8.0, then we know that the ABI will be
broken for 9.0.  I think we should shoot for stabilizing the
ABI by including this in 8.0.

-- 
Steve

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-22 20:24 ` Janne Blomqvist
@ 2018-01-22 21:10   ` Thomas Koenig
  2018-01-23  4:44     ` Jerry DeLisle
  2018-01-22 23:03   ` Steve Kargl
  1 sibling, 1 reply; 16+ messages in thread
From: Thomas Koenig @ 2018-01-22 21:10 UTC (permalink / raw)
  To: Janne Blomqvist, Paul Richard Thomas; +Cc: fortran, gcc-patches

Am 22.01.2018 um 20:59 schrieb Janne Blomqvist:
> On Mon, Jan 22, 2018 at 9:12 PM, Paul Richard Thomas
> <paul.richard.thomas@gmail.com> wrote:
>> This patch has been triggered by Thomas's recent message to the list.
>> Not only did I start work late relative to stage 3 but debugging took
>> somewhat longer than anticipated. Therefore, to get this committed
>> asap, we will have to beg the indulgence of the release managers and
>> prompt review and/or testing by fortran maintainers. (Dominique has
>> already undertaken to test -m32.)
> 
> I think that if we can "guarantee" that we're happy with the current
> ABI for GCC 9 (and hopefully 10, 11, ...?) we have a quite strong case
> for committing it now. But if anybody if planning on doing some
> ABI-breaking work in the foreseeable future then maybe we should wait
> until GCC 9 stage1 opens. Anybody with such plans?

For asynchronous I/O, we could add a pointer to void (unused at
present) for later use.  That's all from my side.


>> It should be noted that some of the intrinsics, which use switch/case
>> for the type/kind selection, limit the effective element size that
>> they handle to the maximum value of size_t, less 7 bits. A bit of
>> straightforward work there would fix this limitation and would allow
>> the GFC_DTYPE shifts and masks to be eliminated.
> 
> Hmm, is this a hidden ABI break, then?

No.

This concerns code like

   type_size = GFC_DTYPE_TYPE_SIZE(array);

   switch(type_size)
     {
     case GFC_DTYPE_LOGICAL_1:
     case GFC_DTYPE_INTEGER_1:
     case GFC_DTYPE_DERIVED_1:
       pack_i1 ((gfc_array_i1 *) ret, (gfc_array_i1 *) array,
                (gfc_array_l1 *) mask, (gfc_array_i1 *) vector);
       return;

for example in patck_generic.c.

I think that, if we commit Paul's patch now, we can then fix these cases
before gcc 8 is released.  This is rather straigtforward.

Regards

	Thomas

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
  2018-01-22 19:46 Paul Richard Thomas
@ 2018-01-22 20:24 ` Janne Blomqvist
  2018-01-22 21:10   ` Thomas Koenig
  2018-01-22 23:03   ` Steve Kargl
  2018-01-23 19:25 ` Janne Blomqvist
  1 sibling, 2 replies; 16+ messages in thread
From: Janne Blomqvist @ 2018-01-22 20:24 UTC (permalink / raw)
  To: Paul Richard Thomas; +Cc: fortran, gcc-patches

On Mon, Jan 22, 2018 at 9:12 PM, Paul Richard Thomas
<paul.richard.thomas@gmail.com> wrote:
> This patch has been triggered by Thomas's recent message to the list.
> Not only did I start work late relative to stage 3 but debugging took
> somewhat longer than anticipated. Therefore, to get this committed
> asap, we will have to beg the indulgence of the release managers and
> prompt review and/or testing by fortran maintainers. (Dominique has
> already undertaken to test -m32.)

I think that if we can "guarantee" that we're happy with the current
ABI for GCC 9 (and hopefully 10, 11, ...?) we have a quite strong case
for committing it now. But if anybody if planning on doing some
ABI-breaking work in the foreseeable future then maybe we should wait
until GCC 9 stage1 opens. Anybody with such plans?

> The patch delivers rank up to 15 for F2008, the descriptor information
> needed to enact the F2018 C descriptor macros and an attribute field
> to store such information as pointer/allocatable, contiguous etc..
> Only the first has been enabled so far but it was necessary to submit
> the array descriptor changes now to avoid any further ABI breakage in
> 9.0.0.
>
> I took the design choice choice to replace the dtype with a structure:
> typedef struct dtype_type
> {
>   size_t elem_len;
>   int version;
>   int rank;
>   int type;
>   int attribute;
> }
> dtype_type;
>
> This choice was intended to reduce the changes to a minimum, since in
> most references to the dtype, one dtype is assigned to another.

The only potential objection I can come up with is that if we at some
point want to make the F2018 C interoperability descriptor the native
descriptor type, then we have to mash those fields into the parent
descriptor anyway.  But I don't really think this is a very strong
objection, as I don't think it's a huge difference in the amount of
work whichever path is taken. If this is the easiest path for now, so
be it.

> The F2018 interop defines the 'type and 'attribute fields to be signed
> char types. I used this intially but found that using int was the best
> way to silence the warnings about padding since it also allows for
> more attribute information to be carried.

To be pedantic, F2018 doesn't require that they be signed char, it's
just what I wrote on https://gcc.gnu.org/wiki/ArrayDescriptorUpdate as
*one* potential implementation of ISO_Fortran_binding.h. What the
(draft) F2018 standard says is:

CFI_attribute_t is a typedef name for a standard integer type capable
of representing the values of the attribute codes.

CFI_type_t is a typedef name for a standard integer type capable of
representing the values for the supported type specifiers.

CFI_rank_t is a typedef name for a standard integer type capable of
representing the largest supported rank.

So using int is standard conforming.

(elem_len and version are explicitly specified to be size_t and int,
respectively)

> It should be noted that some of the intrinsics, which use switch/case
> for the type/kind selection, limit the effective element size that
> they handle to the maximum value of size_t, less 7 bits. A bit of
> straightforward work there would fix this limitation and would allow
> the GFC_DTYPE shifts and masks to be eliminated.

Hmm, is this a hidden ABI break, then? Are you saying that even after
this patch we encode the type/kind into the elem_len field? If at some
point we stop doing that and use the type field, it's an ABI break
even though the descriptor layout doesn't change?

(I haven't had time to look into the patch itself, yet. If we decide
to do this for GCC 8 I'll try to find some time.)


-- 
Janne Blomqvist

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15
@ 2018-01-22 19:46 Paul Richard Thomas
  2018-01-22 20:24 ` Janne Blomqvist
  2018-01-23 19:25 ` Janne Blomqvist
  0 siblings, 2 replies; 16+ messages in thread
From: Paul Richard Thomas @ 2018-01-22 19:46 UTC (permalink / raw)
  To: fortran, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 5082 bytes --]

This patch has been triggered by Thomas's recent message to the list.
Not only did I start work late relative to stage 3 but debugging took
somewhat longer than anticipated. Therefore, to get this committed
asap, we will have to beg the indulgence of the release managers and
prompt review and/or testing by fortran maintainers. (Dominique has
already undertaken to test -m32.)

The patch delivers rank up to 15 for F2008, the descriptor information
needed to enact the F2018 C descriptor macros and an attribute field
to store such information as pointer/allocatable, contiguous etc..
Only the first has been enabled so far but it was necessary to submit
the array descriptor changes now to avoid any further ABI breakage in
9.0.0.

I took the design choice choice to replace the dtype with a structure:
typedef struct dtype_type
{
  size_t elem_len;
  int version;
  int rank;
  int type;
  int attribute;
}
dtype_type;

This choice was intended to reduce the changes to a minimum, since in
most references to the dtype, one dtype is assigned to another.

The F2018 interop defines the 'type and 'attribute fields to be signed
char types. I used this intially but found that using int was the best
way to silence the warnings about padding since it also allows for
more attribute information to be carried.

Some parts of the patch (eg. in get_scalar_to_descriptor_type) look as
if latent bugs were uncovered by the change to the descriptor. If so,
the time spent debugging was well worthwhile.

It should be noted that some of the intrinsics, which use switch/case
for the type/kind selection, limit the effective element size that
they handle to the maximum value of size_t, less 7 bits. A bit of
straightforward work there would fix this limitation and would allow
the GFC_DTYPE shifts and masks to be eliminated.

Bootstraps and regtests on FC23/x86_64 - OK for trunk?

Paul

2018-22-01  Paul Thomas  <pault@gcc.gnu.org>

    PR fortran/37577
    * array.c (gfc_match_array_ref): If standard earlier than F2008
    it is an error if the reference dimension is greater than 7.
    libgfortran.h : Increase GFC_MAX_DIMENSIONS to 15. Change the
    dtype masks and shifts accordingly.
    * trans-array.c (gfc_conv_descriptor_dtype): Use the dtype
    type node to check the field.
    (gfc_conv_descriptor_dtype): Access the rank field of dtype.
    (duplicate_allocatable_coarray): Access the rank field of the
    dtype descriptor rather than the dtype itself.
    * trans-expr.c (get_scalar_to_descriptor_type): Store the type
    of 'scalar' on entry and use its TREE_TYPE if it is ARRAY_TYPE
    (ie. a character).
    (gfc_conv_procedure_call): Pass TREE_OPERAND (tmp,0) to
    get_scalar_to_descriptor_type if the actual expression is a
    constant.
    (gfc_trans_structure_assign): Assign the rank directly to the
    dtype rank field.
    (gfc_conv_intrinsic_sizeof): Obtain the element size from the
    'elem_len' field of the dtype.
    * trans-io.c (gfc_build_io_library_fndecls): Replace
    gfc_int4_type_node with dtype_type_node where necessary.
    (transfer_namelist_element): Use gfc_get_dtype_rank_type for
    scalars.
    * trans-types.c : Provide 'get_dtype_type_node' to acces the
    dtype_type_node and, if necessary, build it.
    The maximum size of an array element is now determined by the
    maximum value of size_t.
    Update the description of the array descriptor, including the
    type def for the dtype_type.
    (gfc_get_dtype_rank_type): Build a constructor for the dtype.
    Distinguish RECORD_TYPEs that are BT_DERIVED or BT_CLASS.
    (gfc_get_array_descriptor_base): Change the type of the dtype
    field to dtype_type_node.
    (gfc_get_array_descr_info): Get the offset to the rank field of
    the dtype.
    * trans-types.h : Add a prototype for 'get_dtype_type_node ()'.
    * trans.h : Define the indices of the dtype fields.

2018-22-01  Paul Thomas  <pault@gcc.gnu.org>

    PR fortran/37577
    * gfortran.dg/coarray_18.f90: Allow dimension 15 for F2008.
    * gfortran.dg/coarray_lib_this_image_2.f90: Change 'array1' to
    'array01' in the tree dump comparison.
    * gfortran.dg/coarray_lib_token_4.f90: Likewise.
    * gfortran.dg/inline_sum_1.f90: Similar - allow two digits.
    * gfortran.dg/rank_1.f90: Allow dimension 15 for F2008.

2018-22-01  Paul Thomas  <pault@gcc.gnu.org>

    PR fortran/37577
    * caf/single.c (_gfortran_caf_failed_images): Access the 'type'
    and 'elem_len' fields of the dtype instead of the shifts.
    (_gfortran_caf_stopped_images): Likewise.
    * intrinsics/associated.c (associated): Compare the 'type' and
    'elem_len' fields instead of the dtype.
    * caf/date_and_time.c : Access the dtype fields rather using
    shifts and masks.
    * io/transfer.c (transfer_array ): Comment on item count.
    (set_nml_var,st_set_nml_var): Change dtype type and use fields.
    (st_set_nml_dtio_var): Likewise.
    * libgfortran.h : Change definition of GFC_ARRAY_DESCRIPTOR and
    add a typedef for the dtype_type. Change the GFC_DTYPE_* macros
    to access the dtype fields.

[-- Attachment #2: submit.diff --]
[-- Type: text/plain, Size: 41075 bytes --]

Index: gcc/fortran/array.c
===================================================================
*** gcc/fortran/array.c	(revision 256606)
--- gcc/fortran/array.c	(working copy)
*************** gfc_match_array_ref (gfc_array_ref *ar,
*** 197,202 ****
--- 197,207 ----
  	}
      }
  
+   if (ar->dimen >= 7
+       && !gfc_notify_std (GFC_STD_F2008,
+ 			  "Array reference at %C has more than 7 dimensions"))
+     return MATCH_ERROR;
+ 
    gfc_error ("Array reference at %C cannot have more than %d dimensions",
  	     GFC_MAX_DIMENSIONS);
    return MATCH_ERROR;
Index: gcc/fortran/libgfortran.h
===================================================================
*** gcc/fortran/libgfortran.h	(revision 256606)
--- gcc/fortran/libgfortran.h	(working copy)
*************** typedef enum
*** 150,164 ****
  #define GFC_STDOUT_UNIT_NUMBER 6
  #define GFC_STDERR_UNIT_NUMBER 0
  
  
! /* FIXME: Increase to 15 for Fortran 2008. Also needs changes to
!    GFC_DTYPE_RANK_MASK. See PR 36825.  */
! #define GFC_MAX_DIMENSIONS 7
! 
! #define GFC_DTYPE_RANK_MASK 0x07
! #define GFC_DTYPE_TYPE_SHIFT 3
! #define GFC_DTYPE_TYPE_MASK 0x38
! #define GFC_DTYPE_SIZE_SHIFT 6
  
  /* Basic types.  BT_VOID is used by ISO C Binding so funcs like c_f_pointer
     can take any arg with the pointer attribute as a param.  These are also
--- 150,162 ----
  #define GFC_STDOUT_UNIT_NUMBER 6
  #define GFC_STDERR_UNIT_NUMBER 0
  
+ /* F2008 onward. For std < F2008, error caught in array.c(gfc_match_array_ref).  */
+ #define GFC_MAX_DIMENSIONS 15
  
! #define GFC_DTYPE_RANK_MASK 0x0F
! #define GFC_DTYPE_TYPE_SHIFT 4
! #define GFC_DTYPE_TYPE_MASK 0x70
! #define GFC_DTYPE_SIZE_SHIFT 7
  
  /* Basic types.  BT_VOID is used by ISO C Binding so funcs like c_f_pointer
     can take any arg with the pointer attribute as a param.  These are also
Index: gcc/fortran/trans-array.c
===================================================================
*** gcc/fortran/trans-array.c	(revision 256607)
--- gcc/fortran/trans-array.c	(working copy)
*************** gfc_conv_descriptor_dtype (tree desc)
*** 239,245 ****
    gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
  
    field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
!   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
    return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
  			  desc, field, NULL_TREE);
--- 239,246 ----
    gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
  
    field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
!   gcc_assert (field != NULL_TREE
! 	      && TREE_TYPE (field) == get_dtype_type_node ());
  
    return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
  			  desc, field, NULL_TREE);
*************** gfc_conv_descriptor_rank (tree desc)
*** 283,292 ****
    tree dtype;
  
    dtype = gfc_conv_descriptor_dtype (desc);
!   tmp = build_int_cst (TREE_TYPE (dtype), GFC_DTYPE_RANK_MASK);
!   tmp = fold_build2_loc (input_location, BIT_AND_EXPR, TREE_TYPE (dtype),
! 			 dtype, tmp);
!   return fold_convert (gfc_get_int_type (gfc_default_integer_kind), tmp);
  }
  
  
--- 284,294 ----
    tree dtype;
  
    dtype = gfc_conv_descriptor_dtype (desc);
!   tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), GFC_DTYPE_RANK);
!   gcc_assert (tmp!= NULL_TREE
! 	      && TREE_TYPE (tmp) == integer_type_node);
!   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp),
! 			  dtype, tmp, NULL_TREE);
  }
  
  
*************** duplicate_allocatable_coarray (tree dest
*** 8205,8211 ****
    else
      {
        /* Set the rank or unitialized memory access may be reported.  */
!       tmp = gfc_conv_descriptor_dtype (dest);
        gfc_add_modify (&globalblock, tmp, build_int_cst (TREE_TYPE (tmp), rank));
  
        if (rank)
--- 8207,8213 ----
    else
      {
        /* Set the rank or unitialized memory access may be reported.  */
!       tmp = gfc_conv_descriptor_rank (dest);
        gfc_add_modify (&globalblock, tmp, build_int_cst (TREE_TYPE (tmp), rank));
  
        if (rank)
Index: gcc/fortran/trans-expr.c
===================================================================
*** gcc/fortran/trans-expr.c	(revision 256607)
--- gcc/fortran/trans-expr.c	(working copy)
*************** get_scalar_to_descriptor_type (tree scal
*** 66,74 ****
  tree
  gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
  {
!   tree desc, type;
  
    type = get_scalar_to_descriptor_type (scalar, attr);
    desc = gfc_create_var (type, "desc");
    DECL_ARTIFICIAL (desc) = 1;
  
--- 66,75 ----
  tree
  gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
  {
!   tree desc, type, etype;
  
    type = get_scalar_to_descriptor_type (scalar, attr);
+   etype = TREE_TYPE (scalar);
    desc = gfc_create_var (type, "desc");
    DECL_ARTIFICIAL (desc) = 1;
  
*************** gfc_conv_scalar_to_descriptor (gfc_se *s
*** 81,88 ****
      }
    if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
      scalar = gfc_build_addr_expr (NULL_TREE, scalar);
    gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
! 		  gfc_get_dtype (type));
    gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
  
    /* Copy pointer address back - but only if it could have changed and
--- 82,91 ----
      }
    if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
      scalar = gfc_build_addr_expr (NULL_TREE, scalar);
+   else if (TREE_TYPE (etype) && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE)
+     etype = TREE_TYPE (etype);
    gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
! 		  gfc_get_dtype_rank_type (0, etype));
    gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
  
    /* Copy pointer address back - but only if it could have changed and
*************** gfc_conv_procedure_call (gfc_se * se, gf
*** 5323,5329 ****
  		    {
  		      tmp = parmse.expr;
  		      if (TREE_CODE (tmp) == ADDR_EXPR
! 			  && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (tmp, 0))))
  			tmp = TREE_OPERAND (tmp, 0);
  		      parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
  								   fsym->attr);
--- 5326,5333 ----
  		    {
  		      tmp = parmse.expr;
  		      if (TREE_CODE (tmp) == ADDR_EXPR
! 			   && (POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (tmp, 0)))
! 			       || e->expr_type == EXPR_CONSTANT))
  			tmp = TREE_OPERAND (tmp, 0);
  		      parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
  								   fsym->attr);
*************** gfc_trans_structure_assign (tree dest, g
*** 7611,7618 ****
  		rank = 1;
  	      size = integer_zero_node;
  	      desc = field;
! 	      gfc_add_modify (&block, gfc_conv_descriptor_dtype (desc),
! 			      build_int_cst (gfc_array_index_type, rank));
  	    }
  	  else
  	    {
--- 7615,7622 ----
  		rank = 1;
  	      size = integer_zero_node;
  	      desc = field;
! 	      gfc_add_modify (&block, gfc_conv_descriptor_rank (desc),
! 			      build_int_cst (integer_type_node, rank));
  	    }
  	  else
  	    {
Index: gcc/fortran/trans-intrinsic.c
===================================================================
*** gcc/fortran/trans-intrinsic.c	(revision 256606)
--- gcc/fortran/trans-intrinsic.c	(working copy)
*************** gfc_conv_intrinsic_sizeof (gfc_se *se, g
*** 6777,6782 ****
--- 6777,6783 ----
    tree lower;
    tree upper;
    tree byte_size;
+   tree field;
    int n;
  
    gfc_init_se (&argse, NULL);
*************** gfc_conv_intrinsic_sizeof (gfc_se *se, g
*** 6799,6808 ****
  	    ? GFC_DECL_SAVED_DESCRIPTOR (tmp) : tmp;
        if (POINTER_TYPE_P (TREE_TYPE (tmp)))
  	tmp = build_fold_indirect_ref_loc (input_location, tmp);
!       tmp = fold_convert (size_type_node, gfc_conv_descriptor_dtype (tmp));
!       tmp = fold_build2_loc (input_location, RSHIFT_EXPR, TREE_TYPE (tmp), tmp,
! 			     build_int_cst (TREE_TYPE (tmp),
! 					    GFC_DTYPE_SIZE_SHIFT));
        byte_size = fold_convert (gfc_array_index_type, tmp);
      }
    else if (arg->ts.type == BT_CLASS)
--- 6800,6812 ----
  	    ? GFC_DECL_SAVED_DESCRIPTOR (tmp) : tmp;
        if (POINTER_TYPE_P (TREE_TYPE (tmp)))
  	tmp = build_fold_indirect_ref_loc (input_location, tmp);
! 
!       tmp = gfc_conv_descriptor_dtype (tmp);
!       field = gfc_advance_chain (TYPE_FIELDS (get_dtype_type_node ()),
! 				 GFC_DTYPE_ELEM_LEN);
!       tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
! 			     tmp, field, NULL_TREE);
! 
        byte_size = fold_convert (gfc_array_index_type, tmp);
      }
    else if (arg->ts.type == BT_CLASS)
Index: gcc/fortran/trans-io.c
===================================================================
*** gcc/fortran/trans-io.c	(revision 256606)
--- gcc/fortran/trans-io.c	(working copy)
*************** gfc_build_io_library_fndecls (void)
*** 478,489 ****
    iocall[IOCALL_SET_NML_VAL] = gfc_build_library_function_decl_with_spec (
  	get_identifier (PREFIX("st_set_nml_var")), ".w.R",
  	void_type_node, 6, dt_parm_type, pvoid_type_node, pvoid_type_node,
! 	gfc_int4_type_node, gfc_charlen_type_node, gfc_int4_type_node);
  
    iocall[IOCALL_SET_NML_DTIO_VAL] = gfc_build_library_function_decl_with_spec (
  	get_identifier (PREFIX("st_set_nml_dtio_var")), ".w.R",
  	void_type_node, 8, dt_parm_type, pvoid_type_node, pvoid_type_node,
! 	gfc_int4_type_node, gfc_charlen_type_node, gfc_int4_type_node,
  	pvoid_type_node, pvoid_type_node);
  
    iocall[IOCALL_SET_NML_VAL_DIM] = gfc_build_library_function_decl_with_spec (
--- 478,489 ----
    iocall[IOCALL_SET_NML_VAL] = gfc_build_library_function_decl_with_spec (
  	get_identifier (PREFIX("st_set_nml_var")), ".w.R",
  	void_type_node, 6, dt_parm_type, pvoid_type_node, pvoid_type_node,
! 	gfc_int4_type_node, gfc_charlen_type_node, get_dtype_type_node());
  
    iocall[IOCALL_SET_NML_DTIO_VAL] = gfc_build_library_function_decl_with_spec (
  	get_identifier (PREFIX("st_set_nml_dtio_var")), ".w.R",
  	void_type_node, 8, dt_parm_type, pvoid_type_node, pvoid_type_node,
! 	gfc_int4_type_node, gfc_charlen_type_node, get_dtype_type_node(),
  	pvoid_type_node, pvoid_type_node);
  
    iocall[IOCALL_SET_NML_VAL_DIM] = gfc_build_library_function_decl_with_spec (
*************** transfer_namelist_element (stmtblock_t *
*** 1662,1668 ****
    tree dtio_proc = null_pointer_node;
    tree vtable = null_pointer_node;
    int n_dim;
-   int itype;
    int rank = 0;
  
    gcc_assert (sym || c);
--- 1662,1667 ----
*************** transfer_namelist_element (stmtblock_t *
*** 1699,1706 ****
      }
    else
      {
!       itype = ts->type;
!       dtype = IARG (itype << GFC_DTYPE_TYPE_SHIFT);
      }
  
    /* Build up the arguments for the transfer call.
--- 1698,1705 ----
      }
    else
      {
!       dt =  gfc_typenode_for_spec (ts);
!       dtype = gfc_get_dtype_rank_type (0, dt);
      }
  
    /* Build up the arguments for the transfer call.
Index: gcc/fortran/trans-types.c
===================================================================
*** gcc/fortran/trans-types.c	(revision 256606)
--- gcc/fortran/trans-types.c	(working copy)
*************** int gfc_size_kind;
*** 130,135 ****
--- 130,176 ----
  int gfc_numeric_storage_size;
  int gfc_character_storage_size;
  
+ tree dtype_type_node = NULL_TREE;
+ 
+ 
+ /* Build the dtype_type_node if necessary.  */
+ tree get_dtype_type_node (void)
+ {
+   tree field;
+   tree dtype_node;
+   tree *dtype_chain = NULL;
+ 
+   if (dtype_type_node == NULL_TREE)
+     {
+       dtype_node = make_node (RECORD_TYPE);
+       TYPE_NAME (dtype_node) = get_identifier ("dtype_type");
+       TYPE_NAMELESS (dtype_node) = 1;
+       field = gfc_add_field_to_struct_1 (dtype_node,
+ 					 get_identifier ("elem_len"),
+ 					 size_type_node, &dtype_chain);
+       TREE_NO_WARNING (field) = 1;
+       field = gfc_add_field_to_struct_1 (dtype_node,
+ 					 get_identifier ("version"),
+ 					 integer_type_node, &dtype_chain);
+       TREE_NO_WARNING (field) = 1;
+       field = gfc_add_field_to_struct_1 (dtype_node,
+ 					 get_identifier ("rank"),
+ 					 integer_type_node, &dtype_chain);
+       TREE_NO_WARNING (field) = 1;
+       field = gfc_add_field_to_struct_1 (dtype_node,
+ 					 get_identifier ("type"),
+ 					 integer_type_node, &dtype_chain);
+       TREE_NO_WARNING (field) = 1;
+       field = gfc_add_field_to_struct_1 (dtype_node,
+ 					 get_identifier ("attribute"),
+ 					 integer_type_node, &dtype_chain);
+       TREE_NO_WARNING (field) = 1;
+       gfc_finish_type (dtype_node);
+       TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (dtype_node)) = 1;
+       dtype_type_node = dtype_node;
+     }
+   return dtype_type_node;
+ }
  
  bool
  gfc_check_any_c_kind (gfc_typespec *ts)
*************** gfc_init_types (void)
*** 1003,1009 ****
       by the number of bits available to store this field in the array
       descriptor.  */
  
!   n = TYPE_PRECISION (gfc_array_index_type) - GFC_DTYPE_SIZE_SHIFT;
    gfc_max_array_element_size
      = wide_int_to_tree (size_type_node,
  			wi::mask (n, UNSIGNED,
--- 1044,1050 ----
       by the number of bits available to store this field in the array
       descriptor.  */
  
!   n = TYPE_PRECISION (size_type_node);
    gfc_max_array_element_size
      = wide_int_to_tree (size_type_node,
  			wi::mask (n, UNSIGNED,
*************** gfc_get_element_type (tree type)
*** 1255,1266 ****
  
      struct gfc_array_descriptor
      {
!       array *data
        index offset;
!       index dtype;
        struct descriptor_dimension dimension[N_DIM];
      }
  
      struct descriptor_dimension
      {
        index stride;
--- 1296,1316 ----
  
      struct gfc_array_descriptor
      {
!       array *data;
        index offset;
!       structure dtype_type dtype;
        struct descriptor_dimension dimension[N_DIM];
      }
  
+     struct dtype_type
+     {
+       size_t elem_len;
+       int version;
+       int rank;
+       int type;
+       int attribute;
+     }
+ 
      struct descriptor_dimension
      {
        index stride;
*************** gfc_get_element_type (tree type)
*** 1277,1287 ****
     are gfc_array_index_type and the data node is a pointer to the
     data.  See below for the handling of character types.
  
-    The dtype member is formatted as follows:
-     rank = dtype & GFC_DTYPE_RANK_MASK // 3 bits
-     type = (dtype & GFC_DTYPE_TYPE_MASK) >> GFC_DTYPE_TYPE_SHIFT // 3 bits
-     size = dtype >> GFC_DTYPE_SIZE_SHIFT
- 
     I originally used nested ARRAY_TYPE nodes to represent arrays, but
     this generated poor code for assumed/deferred size arrays.  These
     require use of PLACEHOLDER_EXPR/WITH_RECORD_EXPR, which isn't part
--- 1327,1332 ----
*************** gfc_get_dtype_rank_type (int rank, tree
*** 1468,1476 ****
  {
    tree size;
    int n;
-   HOST_WIDE_INT i;
    tree tmp;
    tree dtype;
  
    switch (TREE_CODE (etype))
      {
--- 1513,1522 ----
  {
    tree size;
    int n;
    tree tmp;
    tree dtype;
+   tree field;
+   vec<constructor_elt, va_gc> *v = NULL;
  
    switch (TREE_CODE (etype))
      {
*************** gfc_get_dtype_rank_type (int rank, tree
*** 1490,1507 ****
        n = BT_COMPLEX;
        break;
  
-     /* We will never have arrays of arrays.  */
      case RECORD_TYPE:
!       n = BT_DERIVED;
        break;
  
      case ARRAY_TYPE:
        n = BT_CHARACTER;
        break;
  
      case POINTER_TYPE:
        n = BT_ASSUMED;
!       break;
  
      default:
        /* TODO: Don't do dtype for temporary descriptorless arrays.  */
--- 1536,1556 ----
        n = BT_COMPLEX;
        break;
  
      case RECORD_TYPE:
!       if (GFC_CLASS_TYPE_P (etype))
! 	n = BT_CLASS;
!       else
! 	n = BT_DERIVED;
        break;
  
+     /* We will never have arrays of arrays.  */
      case ARRAY_TYPE:
        n = BT_CHARACTER;
        break;
  
      case POINTER_TYPE:
        n = BT_ASSUMED;
!     break;
  
      default:
        /* TODO: Don't do dtype for temporary descriptorless arrays.  */
*************** gfc_get_dtype_rank_type (int rank, tree
*** 1509,1540 ****
        return gfc_index_zero_node;
      }
  
-   gcc_assert (rank <= GFC_DTYPE_RANK_MASK);
    size = TYPE_SIZE_UNIT (etype);
  
!   i = rank | (n << GFC_DTYPE_TYPE_SHIFT);
!   if (size && INTEGER_CST_P (size))
!     {
!       if (tree_int_cst_lt (gfc_max_array_element_size, size))
! 	gfc_fatal_error ("Array element size too big at %C");
! 
!       i += TREE_INT_CST_LOW (size) << GFC_DTYPE_SIZE_SHIFT;
!     }
!   dtype = build_int_cst (gfc_array_index_type, i);
  
!   if (size && !INTEGER_CST_P (size))
!     {
!       tmp = build_int_cst (gfc_array_index_type, GFC_DTYPE_SIZE_SHIFT);
!       tmp  = fold_build2_loc (input_location, LSHIFT_EXPR,
! 			      gfc_array_index_type,
! 			      fold_convert (gfc_array_index_type, size), tmp);
!       dtype = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
! 			       tmp, dtype);
!     }
!   /* If we don't know the size we leave it as zero.  This should never happen
!      for anything that is actually used.  */
!   /* TODO: Check this is actually true, particularly when repacking
!      assumed size parameters.  */
  
    return dtype;
  }
--- 1558,1584 ----
        return gfc_index_zero_node;
      }
  
    size = TYPE_SIZE_UNIT (etype);
+   if (n == BT_CHARACTER && size == NULL_TREE)
+     size = TYPE_SIZE_UNIT (TREE_TYPE (etype));
  
!   tmp = get_dtype_type_node ();
!   field = gfc_advance_chain (TYPE_FIELDS (tmp),
! 			     GFC_DTYPE_ELEM_LEN);
!   CONSTRUCTOR_APPEND_ELT (v, field,
! 			  fold_convert (TREE_TYPE (field), size));
! 
!   field = gfc_advance_chain (TYPE_FIELDS (dtype_type_node),
! 			     GFC_DTYPE_RANK);
!   CONSTRUCTOR_APPEND_ELT (v, field,
! 			  build_int_cst (TREE_TYPE (field), rank));
! 
!   field = gfc_advance_chain (TYPE_FIELDS (dtype_type_node),
! 			     GFC_DTYPE_TYPE);
!   CONSTRUCTOR_APPEND_ELT (v, field,
! 			  build_int_cst (TREE_TYPE (field), n));
  
!   dtype = build_constructor (tmp, v);
  
    return dtype;
  }
*************** gfc_get_array_descriptor_base (int dimen
*** 1820,1826 ****
    /* Add the dtype component.  */
    decl = gfc_add_field_to_struct_1 (fat_type,
  				    get_identifier ("dtype"),
! 				    gfc_array_index_type, &chain);
    TREE_NO_WARNING (decl) = 1;
  
    /* Add the span component.  */
--- 1864,1870 ----
    /* Add the dtype component.  */
    decl = gfc_add_field_to_struct_1 (fat_type,
  				    get_identifier ("dtype"),
! 				    get_dtype_type_node (), &chain);
    TREE_NO_WARNING (decl) = 1;
  
    /* Add the span component.  */
*************** gfc_get_array_descr_info (const_tree typ
*** 3232,3237 ****
--- 3276,3282 ----
    tree etype, ptype, t, base_decl;
    tree data_off, dim_off, dtype_off, dim_size, elem_size;
    tree lower_suboff, upper_suboff, stride_suboff;
+   tree dtype, field, rank_off;
  
    if (! GFC_DESCRIPTOR_TYPE_P (type))
      {
*************** gfc_get_array_descr_info (const_tree typ
*** 3313,3323 ****
        t = base_decl;
        if (!integer_zerop (dtype_off))
  	t = fold_build_pointer_plus (t, dtype_off);
        t = build1 (NOP_EXPR, build_pointer_type (gfc_array_index_type), t);
        t = build1 (INDIRECT_REF, gfc_array_index_type, t);
!       info->rank = build2 (BIT_AND_EXPR, gfc_array_index_type, t,
! 			   build_int_cst (gfc_array_index_type,
! 					  GFC_DTYPE_RANK_MASK));
        t = build0 (PLACEHOLDER_EXPR, TREE_TYPE (dim_off));
        t = size_binop (MULT_EXPR, t, dim_size);
        dim_off = build2 (PLUS_EXPR, TREE_TYPE (dim_off), t, dim_off);
--- 3358,3372 ----
        t = base_decl;
        if (!integer_zerop (dtype_off))
  	t = fold_build_pointer_plus (t, dtype_off);
+       dtype = TYPE_MAIN_VARIANT (get_dtype_type_node ());
+       field = gfc_advance_chain (TYPE_FIELDS (dtype), GFC_DTYPE_RANK);
+       rank_off = byte_position (field);
+       if (!integer_zerop (dtype_off))
+ 	t = fold_build_pointer_plus (t, rank_off);
+ 
        t = build1 (NOP_EXPR, build_pointer_type (gfc_array_index_type), t);
        t = build1 (INDIRECT_REF, gfc_array_index_type, t);
!       info->rank = t;
        t = build0 (PLACEHOLDER_EXPR, TREE_TYPE (dim_off));
        t = size_binop (MULT_EXPR, t, dim_size);
        dim_off = build2 (PLUS_EXPR, TREE_TYPE (dim_off), t, dim_off);
Index: gcc/fortran/trans-types.h
===================================================================
*** gcc/fortran/trans-types.h	(revision 256606)
--- gcc/fortran/trans-types.h	(working copy)
*************** void gfc_init_kinds (void);
*** 73,78 ****
--- 73,79 ----
  void gfc_init_types (void);
  void gfc_init_c_interop_kinds (void);
  
+ tree get_dtype_type_node (void);
  tree gfc_get_int_type (int);
  tree gfc_get_real_type (int);
  tree gfc_get_complex_type (int);
Index: gcc/fortran/trans.h
===================================================================
*** gcc/fortran/trans.h	(revision 256606)
--- gcc/fortran/trans.h	(working copy)
*************** extern GTY(()) tree gfor_fndecl_ieee_pro
*** 914,919 ****
--- 914,925 ----
  /* gfortran-specific declaration information, the _CONT versions denote
     arrays with CONTIGUOUS attribute.  */
  
+ #define GFC_DTYPE_ELEM_LEN 0
+ #define GFC_DTYPE_VERSION 1
+ #define GFC_DTYPE_RANK 2
+ #define GFC_DTYPE_TYPE 3
+ #define GFC_DTYPE_ATTRIBUTE 4
+ 
  enum gfc_array_kind
  {
    GFC_ARRAY_UNKNOWN,
Index: gcc/testsuite/gfortran.dg/coarray_18.f90
===================================================================
*** gcc/testsuite/gfortran.dg/coarray_18.f90	(revision 256606)
--- gcc/testsuite/gfortran.dg/coarray_18.f90	(working copy)
***************
*** 5,12 ****
  ! dimensions (normal + codimensions).
  !
  ! Fortran 2008 allows (co)arrays with 15 ranks
! ! Currently, gfortran only supports 7, cf. PR 37577
! ! Thus, the program is valid Fortran 2008 ...
  !
  ! See also general coarray PR 18918
  !
--- 5,11 ----
  ! dimensions (normal + codimensions).
  !
  ! Fortran 2008 allows (co)arrays with 15 ranks
! ! Previously gfortran only supported 7, cf. PR 37577
  !
  ! See also general coarray PR 18918
  !
*************** program ar
*** 19,32 ****
    integer :: ic(2)[*]
    integer :: id(2,2)[2,*]
    integer :: ie(2,2,2)[2,2,*]
!   integer :: ig(2,2,2,2)[2,2,2,*] ! { dg-error "has more than 7 dimensions" }
!   integer :: ih(2,2,2,2,2)[2,2,2,2,*] ! { dg-error "has more than 7 dimensions" }
!   integer :: ij(2,2,2,2,2,2)[2,2,2,2,2,*] ! { dg-error "has more than 7 dimensions" }
!   integer :: ik(2,2,2,2,2,2,2)[2,2,2,2,2,2,*] ! { dg-error "has more than 7 dimensions" }
!   integer :: il[2,2,2,2,2,2,2,*] ! { dg-error "has more than 7 dimensions" }
!   integer :: im[2,2,2,2,2,2,2,2,*] ! { dg-error "has more than 7 dimensions" }
!   integer :: in[2,2,2,2,2,2,2,2,2,*] ! { dg-error "has more than 7 dimensions" }
!   integer :: io[2,2,2,2,2,2,2,2,2,2,*] ! { dg-error "has more than 7 dimensions" }
     real :: x2(2,2,4)[2,*]
     complex :: c2(4,2)[2,*]
     double precision :: d2(1,5,9)[2,*]
--- 18,37 ----
    integer :: ic(2)[*]
    integer :: id(2,2)[2,*]
    integer :: ie(2,2,2)[2,2,*]
! ! Previously, these would give errors.
!   integer :: ig(2,2,2,2)[2,2,2,*]
!   integer :: ih(2,2,2,2,2)[2,2,2,2,*]
!   integer :: ij(2,2,2,2,2,2)[2,2,2,2,2,*]
!   integer :: ik(2,2,2,2,2,2,2)[2,2,2,2,2,2,*]
!   integer :: il[2,2,2,2,2,2,2,*] 
!   integer :: im[2,2,2,2,2,2,2,2,*]
!   integer :: in[2,2,2,2,2,2,2,2,2,*]
!   integer :: io[2,2,2,2,2,2,2,2,2,2,*]
! ! Now with max dimensions 15.....
!   integer :: ip(2,2,2,2,2,2,2,2)[2,2,2,2,2,2,2,*] ! { dg-error "has more than 15 dimensions" }
!   integer :: iq[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,*] ! { dg-error "has more than 15 dimensions" }
! ! Check a non-coarray
!   integer :: ir(2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2) ! { dg-error "has more than 15 dimensions" }
     real :: x2(2,2,4)[2,*]
     complex :: c2(4,2)[2,*]
     double precision :: d2(1,5,9)[2,*]
Index: gcc/testsuite/gfortran.dg/coarray_lib_this_image_2.f90
===================================================================
*** gcc/testsuite/gfortran.dg/coarray_lib_this_image_2.f90	(revision 256606)
--- gcc/testsuite/gfortran.dg/coarray_lib_this_image_2.f90	(working copy)
*************** contains
*** 16,22 ****
    end subroutine bar
  end
  
! ! { dg-final { scan-tree-dump-times "bar \\(struct array1_real\\(kind=4\\) & restrict x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) caf_offset..\\)" 1 "original" } }
  ! { dg-final { scan-tree-dump-times "mylcobound = 5;" 1 "original" } }
  ! { dg-final { scan-tree-dump-times "parm...dim\\\[1\\\].lbound = 5;" 1 "original" } }
  ! { dg-final { scan-tree-dump-times "myucobound =\[^\n\r\]* parm...dim\\\[1\\\].lbound \\+ \[^\n\r\]*_gfortran_caf_num_images \\(0, -1\\).? \\+ -?\[0-9\]+\\);" 1 "original" } }
--- 16,22 ----
    end subroutine bar
  end
  
! ! { dg-final { scan-tree-dump-times "bar \\(struct array01_real\\(kind=4\\) & restrict x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) caf_offset..\\)" 1 "original" } }
  ! { dg-final { scan-tree-dump-times "mylcobound = 5;" 1 "original" } }
  ! { dg-final { scan-tree-dump-times "parm...dim\\\[1\\\].lbound = 5;" 1 "original" } }
  ! { dg-final { scan-tree-dump-times "myucobound =\[^\n\r\]* parm...dim\\\[1\\\].lbound \\+ \[^\n\r\]*_gfortran_caf_num_images \\(0, -1\\).? \\+ -?\[0-9\]+\\);" 1 "original" } }
Index: gcc/testsuite/gfortran.dg/coarray_lib_token_4.f90
===================================================================
*** gcc/testsuite/gfortran.dg/coarray_lib_token_4.f90	(revision 256606)
--- gcc/testsuite/gfortran.dg/coarray_lib_token_4.f90	(working copy)
*************** end program test_caf
*** 35,43 ****
  
  ! { dg-final { scan-tree-dump-times "expl \\(integer\\(kind=4\\).0:. . restrict z, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } }
  !
! ! { dg-final { scan-tree-dump-times "bar \\(struct array1_integer\\(kind=4\\) & restrict y, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } }
  !
! ! { dg-final { scan-tree-dump-times "foo \\(struct array1_integer\\(kind=4\\) & restrict x, struct array1_integer\\(kind=4\\) & restrict y, integer\\(kind=4\\) & restrict test, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } }
  !
  ! { dg-final { scan-tree-dump-times "bar \\(&parm.\[0-9\]+, caf_token.\[0-9\]+, \\(\\(integer\\(kind=.\\)\\) parm.\[0-9\]+.data - \\(integer\\(kind=.\\)\\) x.\[0-9\]+\\) \\+ caf_offset.\[0-9\]+\\);" 1 "original" } }
  !
--- 35,43 ----
  
  ! { dg-final { scan-tree-dump-times "expl \\(integer\\(kind=4\\).0:. . restrict z, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } }
  !
! ! { dg-final { scan-tree-dump-times "bar \\(struct array01_integer\\(kind=4\\) & restrict y, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } }
  !
! ! { dg-final { scan-tree-dump-times "foo \\(struct array01_integer\\(kind=4\\) & restrict x, struct array01_integer\\(kind=4\\) & restrict y, integer\\(kind=4\\) & restrict test, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } }
  !
  ! { dg-final { scan-tree-dump-times "bar \\(&parm.\[0-9\]+, caf_token.\[0-9\]+, \\(\\(integer\\(kind=.\\)\\) parm.\[0-9\]+.data - \\(integer\\(kind=.\\)\\) x.\[0-9\]+\\) \\+ caf_offset.\[0-9\]+\\);" 1 "original" } }
  !
Index: gcc/testsuite/gfortran.dg/inline_sum_1.f90
===================================================================
*** gcc/testsuite/gfortran.dg/inline_sum_1.f90	(revision 256606)
--- gcc/testsuite/gfortran.dg/inline_sum_1.f90	(working copy)
*************** contains
*** 188,193 ****
      o = i
    end subroutine tes
  end
! ! { dg-final { scan-tree-dump-times "struct array._integer\\(kind=4\\) atmp" 13 "original" } }
  ! { dg-final { scan-tree-dump-times "struct array\[^\\n\]*atmp" 13 "original" } }
  ! { dg-final { scan-tree-dump-times "_gfortran_sum_" 0 "original" } }
--- 188,193 ----
      o = i
    end subroutine tes
  end
! ! { dg-final { scan-tree-dump-times "struct array.._integer\\(kind=4\\) atmp" 13 "original" } }
  ! { dg-final { scan-tree-dump-times "struct array\[^\\n\]*atmp" 13 "original" } }
  ! { dg-final { scan-tree-dump-times "_gfortran_sum_" 0 "original" } }
Index: gcc/testsuite/gfortran.dg/rank_1.f90
===================================================================
*** gcc/testsuite/gfortran.dg/rank_1.f90	(revision 256606)
--- gcc/testsuite/gfortran.dg/rank_1.f90	(working copy)
***************
*** 4,10 ****
  ! Fortran < 2008 allows 7  dimensions
  ! Fortran   2008 allows 15 dimensions (including co-array ranks)
  !
! ! FIXME: Rank patch was reverted because of PR 36825.
! integer :: a(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) ! { dg-error "has more than 7 dimensions" }
! integer :: b(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) ! { dg-error "has more than 7 dimensions" }
  end
--- 4,9 ----
  ! Fortran < 2008 allows 7  dimensions
  ! Fortran   2008 allows 15 dimensions (including co-array ranks)
  !
! integer :: a(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
! integer :: b(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) ! { dg-error "has more than 15 dimensions" }
  end
Index: libgfortran/caf/single.c
===================================================================
*** libgfortran/caf/single.c	(revision 256606)
--- libgfortran/caf/single.c	(working copy)
*************** _gfortran_caf_failed_images (gfc_descrip
*** 332,339 ****
    int local_kind = kind != NULL ? *kind : 4;
  
    array->base_addr = NULL;
!   array->dtype = ((BT_INTEGER << GFC_DTYPE_TYPE_SHIFT)
! 		  | (local_kind << GFC_DTYPE_SIZE_SHIFT));
     /* Setting lower_bound higher then upper_bound is what the compiler does to
        indicate an empty array.  */
    array->dim[0].lower_bound = 0;
--- 332,339 ----
    int local_kind = kind != NULL ? *kind : 4;
  
    array->base_addr = NULL;
!   array->dtype.type = BT_INTEGER;
!   array->dtype.elem_len = local_kind;
     /* Setting lower_bound higher then upper_bound is what the compiler does to
        indicate an empty array.  */
    array->dim[0].lower_bound = 0;
*************** _gfortran_caf_stopped_images (gfc_descri
*** 354,361 ****
    int local_kind = kind != NULL ? *kind : 4;
  
    array->base_addr = NULL;
!   array->dtype =  ((BT_INTEGER << GFC_DTYPE_TYPE_SHIFT)
! 		   | (local_kind << GFC_DTYPE_SIZE_SHIFT));
    /* Setting lower_bound higher then upper_bound is what the compiler does to
       indicate an empty array.  */
    array->dim[0].lower_bound = 0;
--- 354,361 ----
    int local_kind = kind != NULL ? *kind : 4;
  
    array->base_addr = NULL;
!   array->dtype.type =  BT_INTEGER;
!   array->dtype.elem_len =  local_kind;
    /* Setting lower_bound higher then upper_bound is what the compiler does to
       indicate an empty array.  */
    array->dim[0].lower_bound = 0;
Index: libgfortran/intrinsics/associated.c
===================================================================
*** libgfortran/intrinsics/associated.c	(revision 256606)
--- libgfortran/intrinsics/associated.c	(working copy)
*************** associated (const gfc_array_void *pointe
*** 37,43 ****
      return 0;
    if (GFC_DESCRIPTOR_DATA (pointer) != GFC_DESCRIPTOR_DATA (target))
      return 0;
!   if (GFC_DESCRIPTOR_DTYPE (pointer) != GFC_DESCRIPTOR_DTYPE (target))
      return 0;
  
    rank = GFC_DESCRIPTOR_RANK (pointer);
--- 37,45 ----
      return 0;
    if (GFC_DESCRIPTOR_DATA (pointer) != GFC_DESCRIPTOR_DATA (target))
      return 0;
!   if (GFC_DESCRIPTOR_DTYPE (pointer).elem_len != GFC_DESCRIPTOR_DTYPE (target).elem_len)
!     return 0;
!   if (GFC_DESCRIPTOR_DTYPE (pointer).type != GFC_DESCRIPTOR_DTYPE (target).type)
      return 0;
  
    rank = GFC_DESCRIPTOR_RANK (pointer);
Index: libgfortran/intrinsics/date_and_time.c
===================================================================
*** libgfortran/intrinsics/date_and_time.c	(revision 256606)
--- libgfortran/intrinsics/date_and_time.c	(working copy)
*************** secnds (GFC_REAL_4 *x)
*** 270,279 ****
    /* Make the INTEGER*4 array for passing to date_and_time.  */
    gfc_array_i4 *avalues = xmalloc (sizeof (gfc_array_i4));
    avalues->base_addr = &values[0];
!   GFC_DESCRIPTOR_DTYPE (avalues) = ((BT_REAL << GFC_DTYPE_TYPE_SHIFT)
! 				        & GFC_DTYPE_TYPE_MASK) +
! 				    (4 << GFC_DTYPE_SIZE_SHIFT);
! 
    GFC_DIMENSION_SET(avalues->dim[0], 0, 7, 1);
  
    date_and_time (NULL, NULL, NULL, avalues, 0, 0, 0);
--- 270,278 ----
    /* Make the INTEGER*4 array for passing to date_and_time.  */
    gfc_array_i4 *avalues = xmalloc (sizeof (gfc_array_i4));
    avalues->base_addr = &values[0];
!   GFC_DESCRIPTOR_DTYPE (avalues).type = BT_REAL;
!   GFC_DESCRIPTOR_DTYPE (avalues).elem_len = 4;
!   GFC_DESCRIPTOR_DTYPE (avalues).rank = 1;
    GFC_DIMENSION_SET(avalues->dim[0], 0, 7, 1);
  
    date_and_time (NULL, NULL, NULL, avalues, 0, 0, 0);
Index: libgfortran/io/transfer.c
===================================================================
*** libgfortran/io/transfer.c	(revision 256606)
--- libgfortran/io/transfer.c	(working copy)
*************** transfer_array (st_parameter_dt *dtp, gf
*** 2406,2411 ****
--- 2406,2413 ----
    char *data;
    bt iotype;
  
+   /* Adjust item_count before emitting error message.  */
+  
    if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
      return;
  
*************** transfer_array (st_parameter_dt *dtp, gf
*** 2413,2418 ****
--- 2415,2421 ----
    size = iotype == BT_CHARACTER ? (index_type) charlen : GFC_DESCRIPTOR_SIZE (desc);
  
    rank = GFC_DESCRIPTOR_RANK (desc);
+ 
    for (n = 0; n < rank; n++)
      {
        count[n] = 0;
*************** st_wait (st_parameter_wait *wtp __attrib
*** 4208,4214 ****
  static void
  set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
  	     GFC_INTEGER_4 len, gfc_charlen_type string_length,
! 	     GFC_INTEGER_4 dtype, void *dtio_sub, void *vtable)
  {
    namelist_info *t1 = NULL;
    namelist_info *nml;
--- 4211,4217 ----
  static void
  set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
  	     GFC_INTEGER_4 len, gfc_charlen_type string_length,
! 	     dtype_type dtype, void *dtio_sub, void *vtable)
  {
    namelist_info *t1 = NULL;
    namelist_info *nml;
*************** set_nml_var (st_parameter_dt *dtp, void
*** 4227,4235 ****
    nml->len = (int) len;
    nml->string_length = (index_type) string_length;
  
!   nml->var_rank = (int) (dtype & GFC_DTYPE_RANK_MASK);
!   nml->size = (index_type) (dtype >> GFC_DTYPE_SIZE_SHIFT);
!   nml->type = (bt) ((dtype & GFC_DTYPE_TYPE_MASK) >> GFC_DTYPE_TYPE_SHIFT);
  
    if (nml->var_rank > 0)
      {
--- 4230,4238 ----
    nml->len = (int) len;
    nml->string_length = (index_type) string_length;
  
!   nml->var_rank = (int) (dtype.rank);
!   nml->size = (index_type) (dtype.elem_len);
!   nml->type = (bt) (dtype.type);
  
    if (nml->var_rank > 0)
      {
*************** set_nml_var (st_parameter_dt *dtp, void
*** 4259,4271 ****
  }
  
  extern void st_set_nml_var (st_parameter_dt *dtp, void *, char *,
! 			    GFC_INTEGER_4, gfc_charlen_type, GFC_INTEGER_4);
  export_proto(st_set_nml_var);
  
  void
  st_set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
  		GFC_INTEGER_4 len, gfc_charlen_type string_length,
! 		GFC_INTEGER_4 dtype)
  {
    set_nml_var (dtp, var_addr, var_name, len, string_length,
  	       dtype, NULL, NULL);
--- 4262,4274 ----
  }
  
  extern void st_set_nml_var (st_parameter_dt *dtp, void *, char *,
! 			    GFC_INTEGER_4, gfc_charlen_type, dtype_type);
  export_proto(st_set_nml_var);
  
  void
  st_set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
  		GFC_INTEGER_4 len, gfc_charlen_type string_length,
! 		dtype_type dtype)
  {
    set_nml_var (dtp, var_addr, var_name, len, string_length,
  	       dtype, NULL, NULL);
*************** st_set_nml_var (st_parameter_dt *dtp, vo
*** 4275,4281 ****
  /* Essentially the same as previous but carrying the dtio procedure
     and the vtable as additional arguments.  */
  extern void st_set_nml_dtio_var (st_parameter_dt *dtp, void *, char *,
! 				 GFC_INTEGER_4, gfc_charlen_type, GFC_INTEGER_4,
  				 void *, void *);
  export_proto(st_set_nml_dtio_var);
  
--- 4278,4284 ----
  /* Essentially the same as previous but carrying the dtio procedure
     and the vtable as additional arguments.  */
  extern void st_set_nml_dtio_var (st_parameter_dt *dtp, void *, char *,
! 				 GFC_INTEGER_4, gfc_charlen_type, dtype_type,
  				 void *, void *);
  export_proto(st_set_nml_dtio_var);
  
*************** export_proto(st_set_nml_dtio_var);
*** 4283,4289 ****
  void
  st_set_nml_dtio_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
  		     GFC_INTEGER_4 len, gfc_charlen_type string_length,
! 		     GFC_INTEGER_4 dtype, void *dtio_sub, void *vtable)
  {
    set_nml_var (dtp, var_addr, var_name, len, string_length,
  	       dtype, dtio_sub, vtable);
--- 4286,4292 ----
  void
  st_set_nml_dtio_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
  		     GFC_INTEGER_4 len, gfc_charlen_type string_length,
! 		     dtype_type dtype, void *dtio_sub, void *vtable)
  {
    set_nml_var (dtp, var_addr, var_name, len, string_length,
  	       dtype, dtio_sub, vtable);
Index: libgfortran/libgfortran.h
===================================================================
*** libgfortran/libgfortran.h	(revision 256606)
--- libgfortran/libgfortran.h	(working copy)
*************** typedef struct descriptor_dimension
*** 327,340 ****
    index_type lower_bound;
    index_type _ubound;
  }
- 
  descriptor_dimension;
  
  #define GFC_ARRAY_DESCRIPTOR(r, type) \
  struct {\
    type *base_addr;\
    size_t offset;\
!   index_type dtype;\
    index_type span;\
    descriptor_dimension dim[r];\
  }
--- 327,349 ----
    index_type lower_bound;
    index_type _ubound;
  }
  descriptor_dimension;
  
+ typedef struct dtype_type
+ {
+   size_t elem_len;
+   int version;
+   int rank;
+   int type;
+   int attribute;
+ }
+ dtype_type;
+ 
  #define GFC_ARRAY_DESCRIPTOR(r, type) \
  struct {\
    type *base_addr;\
    size_t offset;\
!   dtype_type dtype;\
    index_type span;\
    descriptor_dimension dim[r];\
  }
*************** typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DI
*** 375,384 ****
  typedef gfc_array_i1 gfc_array_s1;
  typedef gfc_array_i4 gfc_array_s4;
  
! #define GFC_DESCRIPTOR_RANK(desc) ((desc)->dtype & GFC_DTYPE_RANK_MASK)
! #define GFC_DESCRIPTOR_TYPE(desc) (((desc)->dtype & GFC_DTYPE_TYPE_MASK) \
!                                    >> GFC_DTYPE_TYPE_SHIFT)
! #define GFC_DESCRIPTOR_SIZE(desc) ((desc)->dtype >> GFC_DTYPE_SIZE_SHIFT)
  #define GFC_DESCRIPTOR_DATA(desc) ((desc)->base_addr)
  #define GFC_DESCRIPTOR_DTYPE(desc) ((desc)->dtype)
  
--- 384,392 ----
  typedef gfc_array_i1 gfc_array_s1;
  typedef gfc_array_i4 gfc_array_s4;
  
! #define GFC_DESCRIPTOR_RANK(desc) ((desc)->dtype.rank)
! #define GFC_DESCRIPTOR_TYPE(desc) ((desc)->dtype.type)
! #define GFC_DESCRIPTOR_SIZE(desc) ((desc)->dtype.elem_len)
  #define GFC_DESCRIPTOR_DATA(desc) ((desc)->base_addr)
  #define GFC_DESCRIPTOR_DTYPE(desc) ((desc)->dtype)
  
*************** typedef gfc_array_i4 gfc_array_s4;
*** 411,428 ****
  #define GFC_DTYPE_SIZE_MASK (-((index_type) 1 << GFC_DTYPE_SIZE_SHIFT))
  #define GFC_DTYPE_TYPE_SIZE_MASK (GFC_DTYPE_SIZE_MASK | GFC_DTYPE_TYPE_MASK)
  
! #define GFC_DTYPE_TYPE_SIZE(desc) ((desc)->dtype & GFC_DTYPE_TYPE_SIZE_MASK)
  
  /* Macros to set size and type information.  */
  
  #define GFC_DTYPE_COPY(a,b) do { (a)->dtype = (b)->dtype; } while(0)
  #define GFC_DTYPE_COPY_SETRANK(a,b,n) \
    do { \
!   (a)->dtype = (((b)->dtype & ~GFC_DTYPE_RANK_MASK) | n ); \
    } while (0)
  
! #define GFC_DTYPE_IS_UNSET(a) (unlikely((a)->dtype == 0))
! #define GFC_DTYPE_CLEAR(a) do { (a)->dtype = 0; } while(0)
  
  #define GFC_DTYPE_INTEGER_1 ((BT_INTEGER << GFC_DTYPE_TYPE_SHIFT) \
     | (sizeof(GFC_INTEGER_1) << GFC_DTYPE_SIZE_SHIFT))
--- 419,442 ----
  #define GFC_DTYPE_SIZE_MASK (-((index_type) 1 << GFC_DTYPE_SIZE_SHIFT))
  #define GFC_DTYPE_TYPE_SIZE_MASK (GFC_DTYPE_SIZE_MASK | GFC_DTYPE_TYPE_MASK)
  
! #define GFC_DTYPE_TYPE_SIZE(desc) (( ((desc)->dtype.type << GFC_DTYPE_TYPE_SHIFT) \
!     | ((desc)->dtype.elem_len << GFC_DTYPE_SIZE_SHIFT) ) & GFC_DTYPE_TYPE_SIZE_MASK)
  
  /* Macros to set size and type information.  */
  
  #define GFC_DTYPE_COPY(a,b) do { (a)->dtype = (b)->dtype; } while(0)
  #define GFC_DTYPE_COPY_SETRANK(a,b,n) \
    do { \
!   (a)->dtype.rank = ((b)->dtype.rank | n ); \
    } while (0)
  
! #define GFC_DTYPE_IS_UNSET(a) (unlikely((a)->dtype.elem_len == 0))
! #define GFC_DTYPE_CLEAR(a) do { (a)->dtype.elem_len = 0; \
! 				(a)->dtype.version = 0; \
! 				(a)->dtype.rank = 0; \
! 				(a)->dtype.type = 0; \
! 				(a)->dtype.attribute = 0; \
! } while(0)
  
  #define GFC_DTYPE_INTEGER_1 ((BT_INTEGER << GFC_DTYPE_TYPE_SHIFT) \
     | (sizeof(GFC_INTEGER_1) << GFC_DTYPE_SIZE_SHIFT))

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2018-01-29 11:47 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-23  8:13 [Patch, fortran] PR37577 - [meta-bug] change internal array descriptor format for better syntax, C interop TR, rank 15 Dominique d'Humières
2018-01-23 17:56 ` Paul Richard Thomas
2018-01-23 19:17   ` Thomas Koenig
  -- strict thread matches above, loose matches on Subject: below --
2018-01-22 19:46 Paul Richard Thomas
2018-01-22 20:24 ` Janne Blomqvist
2018-01-22 21:10   ` Thomas Koenig
2018-01-23  4:44     ` Jerry DeLisle
2018-01-23 19:06       ` Thomas Koenig
2018-01-22 23:03   ` Steve Kargl
2018-01-23 19:25 ` Janne Blomqvist
2018-01-23 20:31   ` Paul Richard Thomas
2018-01-23 20:54     ` Jakub Jelinek
2018-01-24  8:41       ` Janne Blomqvist
2018-01-24  9:05         ` Jakub Jelinek
2018-01-24  9:59           ` Paul Richard Thomas
2018-01-29 13:02             ` Tom de Vries

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).