public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
* Fortran LTO and array descriptors.
@ 2018-02-03 17:09 Thomas Koenig
  2018-02-03 17:17 ` Thomas Koenig
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Thomas Koenig @ 2018-02-03 17:09 UTC (permalink / raw)
  To: fortran, Richard Guenther, Jakub Jelinek

I have been looking at PR 68649 and 68717. They are the
same bug, really (and there are quite a few more).

Jakub has written a good analysis of the problem at
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68649#c12 .

To sum it up, we create different types for each rank of
array, and then call the library. When we call the
same function with different ranks, lto complains, with
good reason.

The last comment, by Richard, ends with the rather
pessimistic "Thus even the proposed fix won't end up working."

This problem prevents users from a lot of LTO use cases. It also
prevents us from using LTO with the library (although I
strongly suspect that there are also other stumbling blocks).

So, what to do?  On the libfortran side, I tried out the patch

Index: libgfortran.h
===================================================================
--- libgfortran.h       (Revision 257347)
+++ libgfortran.h       (Arbeitskopie)
@@ -345,7 +345,7 @@ struct {\
    size_t offset;\
    dtype_type dtype;\
    index_type span;\
-  descriptor_dimension dim[r];\
+  descriptor_dimension dim[];\
  }

which works well, but that only solves the lesser half of the problem.

Would it be possible and useful, when passing a pointer to an
array descriptor, to cast this to a type with a flexible array
member?

Formally, this should still be OK for stage 4, because several
of the bugs associated with this problems are regressions.

Comments?  Good/bad idea?  Anybody volunteer to do it (I don't have
the trans-* fu for it)?

Regards

	Thomas

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

* Re: Fortran LTO and array descriptors.
  2018-02-03 17:09 Fortran LTO and array descriptors Thomas Koenig
@ 2018-02-03 17:17 ` Thomas Koenig
  2018-02-04 11:42   ` Richard Biener
  2018-02-04 12:36 ` Richard Biener
  2018-02-05  7:54 ` Jakub Jelinek
  2 siblings, 1 reply; 9+ messages in thread
From: Thomas Koenig @ 2018-02-03 17:17 UTC (permalink / raw)
  To: fortran, Richard Guenther, Jakub Jelinek

I wrote:

> -  descriptor_dimension dim[r];\
> +  descriptor_dimension dim[];\
>   }

> which works well

... up to a point, there are numerous dtio failures
when regression testing this.

So, clearly not ready for prime time :-)

	Thomas

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

* Re: Fortran LTO and array descriptors.
  2018-02-03 17:17 ` Thomas Koenig
@ 2018-02-04 11:42   ` Richard Biener
  2018-02-04 11:48     ` Richard Biener
  2018-02-04 20:15     ` Thomas Koenig
  0 siblings, 2 replies; 9+ messages in thread
From: Richard Biener @ 2018-02-04 11:42 UTC (permalink / raw)
  To: Thomas Koenig, fortran, Jakub Jelinek

On February 3, 2018 6:17:15 PM GMT+01:00, Thomas Koenig <tkoenig@netcologne.de> wrote:
>I wrote:
>
>> -  descriptor_dimension dim[r];\
>> +  descriptor_dimension dim[];\
>>   }
>
>> which works well
>
>... up to a point, there are numerous dtio failures
>when regression testing this.
>
>So, clearly not ready for prime time :-)

As far as I remember libgfortran has function signatures with the array descriptor with the maximum number of dimensions and the frontend generates aliased function decls with descriptors of the number of dimensions of the actual argument? 

I believe the solution to the problem is to have the frontend emit only one declaration matching the library one and passing down pointers to descriptors that are accessed via the same full dimension type. 

That can be achieved by either making all array descriptor instances full size or by doing _all_ actual accesses via that type. Like in pseudo C code:

Array2 two_dim;
((arrayFullDim *) & two_dim) - >data =... ;

The middle end supports this well enough by supporting placement new. I understand that really making all descriptors large would be a bigger ABI change or even non-conforming? 

Richard. 

>	Thomas

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

* Re: Fortran LTO and array descriptors.
  2018-02-04 11:42   ` Richard Biener
@ 2018-02-04 11:48     ` Richard Biener
  2018-02-04 20:15     ` Thomas Koenig
  1 sibling, 0 replies; 9+ messages in thread
From: Richard Biener @ 2018-02-04 11:48 UTC (permalink / raw)
  To: Thomas Koenig, fortran, Jakub Jelinek

On February 4, 2018 12:42:11 PM GMT+01:00, Richard Biener <rguenther@suse.de> wrote:
>On February 3, 2018 6:17:15 PM GMT+01:00, Thomas Koenig
><tkoenig@netcologne.de> wrote:
>>I wrote:
>>
>>> -  descriptor_dimension dim[r];\
>>> +  descriptor_dimension dim[];\
>>>   }
>>
>>> which works well
>>
>>... up to a point, there are numerous dtio failures
>>when regression testing this.
>>
>>So, clearly not ready for prime time :-)
>
>As far as I remember libgfortran has function signatures with the array
>descriptor with the maximum number of dimensions and the frontend
>generates aliased function decls with descriptors of the number of
>dimensions of the actual argument? 
>
>I believe the solution to the problem is to have the frontend emit only
>one declaration matching the library one and passing down pointers to
>descriptors that are accessed via the same full dimension type. 
>
>That can be achieved by either making all array descriptor instances
>full size or by doing _all_ actual accesses via that type. Like in
>pseudo C code:
>
>Array2 two_dim;
>((arrayFullDim *) & two_dim) - >data =... ;
>
>The middle end supports this well enough by supporting placement new. I
>understand that really making all descriptors large would be a bigger
>ABI change or even non-conforming? 

There's also the possibility of a middle end feature like __attribute __((alias_set(T))) that would make otherwise unrelated types share the alias set of another one. This is already possible with using variant types but I guess using those would open a rathole of issues. 

An existing big hammer is to make the libgfortran API use may-alias variants of their argument types.

But as Honza noted one of the issues to fix in the frontend is the presence of multiple incompatible decls of the same libgfortran functions. 

>Richard. 
>
>>	Thomas

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

* Re: Fortran LTO and array descriptors.
  2018-02-03 17:09 Fortran LTO and array descriptors Thomas Koenig
  2018-02-03 17:17 ` Thomas Koenig
@ 2018-02-04 12:36 ` Richard Biener
  2018-02-05  7:54 ` Jakub Jelinek
  2 siblings, 0 replies; 9+ messages in thread
From: Richard Biener @ 2018-02-04 12:36 UTC (permalink / raw)
  To: Thomas Koenig, fortran, Jakub Jelinek

On February 3, 2018 6:09:41 PM GMT+01:00, Thomas Koenig <tkoenig@netcologne.de> wrote:
>I have been looking at PR 68649 and 68717. They are the
>same bug, really (and there are quite a few more).
>
>Jakub has written a good analysis of the problem at
>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68649#c12 .
>
>To sum it up, we create different types for each rank of
>array, and then call the library. When we call the
>same function with different ranks, lto complains, with
>good reason.
>
>The last comment, by Richard, ends with the rather
>pessimistic "Thus even the proposed fix won't end up working."
>
>This problem prevents users from a lot of LTO use cases. It also
>prevents us from using LTO with the library (although I
>strongly suspect that there are also other stumbling blocks).
>
>So, what to do?  On the libfortran side, I tried out the patch
>
>Index: libgfortran.h
>===================================================================
>--- libgfortran.h       (Revision 257347)
>+++ libgfortran.h       (Arbeitskopie)
>@@ -345,7 +345,7 @@ struct {\
>    size_t offset;\
>    dtype_type dtype;\
>    index_type span;\
>-  descriptor_dimension dim[r];\
>+  descriptor_dimension dim[];\
>  }
>
>which works well, but that only solves the lesser half of the problem.

Note that using this type on the library side is a good thing in any case. Maybe your problem with this is that you change the macroized version that is eventually used in sizeof expressions rather than only for function argument declarations? 

Richard. 

>Would it be possible and useful, when passing a pointer to an
>array descriptor, to cast this to a type with a flexible array
>member?
>
>Formally, this should still be OK for stage 4, because several
>of the bugs associated with this problems are regressions.
>
>Comments?  Good/bad idea?  Anybody volunteer to do it (I don't have
>the trans-* fu for it)?
>
>Regards
>
>	Thomas

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

* Re: Fortran LTO and array descriptors.
  2018-02-04 11:42   ` Richard Biener
  2018-02-04 11:48     ` Richard Biener
@ 2018-02-04 20:15     ` Thomas Koenig
  2018-02-05  6:42       ` Richard Biener
  1 sibling, 1 reply; 9+ messages in thread
From: Thomas Koenig @ 2018-02-04 20:15 UTC (permalink / raw)
  To: Richard Biener, fortran, Jakub Jelinek

Hi Richard,
> On February 3, 2018 6:17:15 PM GMT+01:00, Thomas Koenig <tkoenig@netcologne.de> wrote:
>> I wrote:
>>
>>> -  descriptor_dimension dim[r];\
>>> +  descriptor_dimension dim[];\
>>>    }
>>
>>> which works well
>>
>> ... up to a point, there are numerous dtio failures
>> when regression testing this.
>>
>> So, clearly not ready for prime time :-)
> 
> As far as I remember libgfortran has function signatures with the array descriptor with the maximum number of dimensions and the frontend generates aliased function decls with descriptors of the number of dimensions of the actual argument?
> 
> I believe the solution to the problem is to have the frontend
> emit only one declaration matching the library one

That is definitely preferred.

> and passing down pointers to descriptors that are accessed via the same full dimension type.
> 
> That can be achieved by either making all array descriptor instances full size

Unfortunately, this is quite wasteful of memory. On a 64-bit system, we
have 24 bytes per dimension; if we allocated a full rank 15
descriptor for a rank one array, we would have 336 unused bytes
on the stack.

> or by doing _all_ actual accesses via that type. Like in pseudo C code:
> 
> Array2 two_dim;
> ((arrayFullDim *) & two_dim) - >data =... ;

Would it also be OK to make this a cast to a flexible member type?

Regards

	Thomas

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

* Re: Fortran LTO and array descriptors.
  2018-02-04 20:15     ` Thomas Koenig
@ 2018-02-05  6:42       ` Richard Biener
  0 siblings, 0 replies; 9+ messages in thread
From: Richard Biener @ 2018-02-05  6:42 UTC (permalink / raw)
  To: Thomas Koenig, fortran, Jakub Jelinek

On February 4, 2018 9:14:53 PM GMT+01:00, Thomas Koenig <tkoenig@netcologne.de> wrote:
>Hi Richard,
>> On February 3, 2018 6:17:15 PM GMT+01:00, Thomas Koenig
><tkoenig@netcologne.de> wrote:
>>> I wrote:
>>>
>>>> -  descriptor_dimension dim[r];\
>>>> +  descriptor_dimension dim[];\
>>>>    }
>>>
>>>> which works well
>>>
>>> ... up to a point, there are numerous dtio failures
>>> when regression testing this.
>>>
>>> So, clearly not ready for prime time :-)
>> 
>> As far as I remember libgfortran has function signatures with the
>array descriptor with the maximum number of dimensions and the frontend
>generates aliased function decls with descriptors of the number of
>dimensions of the actual argument?
>> 
>> I believe the solution to the problem is to have the frontend
>> emit only one declaration matching the library one
>
>That is definitely preferred.
>
>> and passing down pointers to descriptors that are accessed via the
>same full dimension type.
>> 
>> That can be achieved by either making all array descriptor instances
>full size
>
>Unfortunately, this is quite wasteful of memory. On a 64-bit system, we
>have 24 bytes per dimension; if we allocated a full rank 15
>descriptor for a rank one array, we would have 336 unused bytes
>on the stack.
>
>> or by doing _all_ actual accesses via that type. Like in pseudo C
>code:
>> 
>> Array2 two_dim;
>> ((arrayFullDim *) & two_dim) - >data =... ;
>
>Would it also be OK to make this a cast to a flexible member type?

Yes. I think that would even be preferred. 

Richard. 

>Regards
>
>	Thomas

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

* Re: Fortran LTO and array descriptors.
  2018-02-03 17:09 Fortran LTO and array descriptors Thomas Koenig
  2018-02-03 17:17 ` Thomas Koenig
  2018-02-04 12:36 ` Richard Biener
@ 2018-02-05  7:54 ` Jakub Jelinek
  2018-02-05 10:17   ` Richard Biener
  2 siblings, 1 reply; 9+ messages in thread
From: Jakub Jelinek @ 2018-02-05  7:54 UTC (permalink / raw)
  To: Thomas Koenig; +Cc: fortran, Richard Guenther

On Sat, Feb 03, 2018 at 06:09:41PM +0100, Thomas Koenig wrote:
> I have been looking at PR 68649 and 68717. They are the
> same bug, really (and there are quite a few more).
> 
> Jakub has written a good analysis of the problem at
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68649#c12 .
> 
> To sum it up, we create different types for each rank of
> array, and then call the library. When we call the
> same function with different ranks, lto complains, with
> good reason.
> 
> The last comment, by Richard, ends with the rather
> pessimistic "Thus even the proposed fix won't end up working."
> 
> This problem prevents users from a lot of LTO use cases. It also
> prevents us from using LTO with the library (although I
> strongly suspect that there are also other stumbling blocks).
> 
> So, what to do?  On the libfortran side, I tried out the patch

Trying Richi's testcase with real flexible array member doesn't help:
struct Xflex
{
  int n;
  int a[];
};
struct Xspecific
{
  int n;
  int a[7];
} x;

int
foo (struct Xflex *f)
{
  f->a[6] = 2;
  x.a[6] = 1;
  return f->a[6];
}

still returns 2 at -O2.  What seems to work is:
struct Xflex
{
  int n;
  int a[];
};
union Uspecific
{
struct Xflex flex;
struct Xspecific
{
  int n;
  int a[7];
} specific;
} x;

int
foo (struct Xflex *f)
{
  f->a[6] = 2;
  x.specific.a[6] = 1;
  return f->a[6];
}

i.e. have a generic struct with flexible array member, which is what e.g.
the libgfortran APIs take as arguments, and when you actually need an object
on the stack or static object, make it a union of that generic struct with
flexible array member and the struct specific for how big rank you want.

I can try to implement that next week if that's what we agree on.

	Jakub

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

* Re: Fortran LTO and array descriptors.
  2018-02-05  7:54 ` Jakub Jelinek
@ 2018-02-05 10:17   ` Richard Biener
  0 siblings, 0 replies; 9+ messages in thread
From: Richard Biener @ 2018-02-05 10:17 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Thomas Koenig, fortran

On Sat, 3 Feb 2018, Jakub Jelinek wrote:

> On Sat, Feb 03, 2018 at 06:09:41PM +0100, Thomas Koenig wrote:
> > I have been looking at PR 68649 and 68717. They are the
> > same bug, really (and there are quite a few more).
> > 
> > Jakub has written a good analysis of the problem at
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68649#c12 .
> > 
> > To sum it up, we create different types for each rank of
> > array, and then call the library. When we call the
> > same function with different ranks, lto complains, with
> > good reason.
> > 
> > The last comment, by Richard, ends with the rather
> > pessimistic "Thus even the proposed fix won't end up working."
> > 
> > This problem prevents users from a lot of LTO use cases. It also
> > prevents us from using LTO with the library (although I
> > strongly suspect that there are also other stumbling blocks).
> > 
> > So, what to do?  On the libfortran side, I tried out the patch
> 
> Trying Richi's testcase with real flexible array member doesn't help:
> struct Xflex
> {
>   int n;
>   int a[];
> };
> struct Xspecific
> {
>   int n;
>   int a[7];
> } x;
> 
> int
> foo (struct Xflex *f)
> {
>   f->a[6] = 2;
>   x.a[6] = 1;
>   return f->a[6];
> }
> 
> still returns 2 at -O2.  What seems to work is:
> struct Xflex
> {
>   int n;
>   int a[];
> };
> union Uspecific
> {
> struct Xflex flex;
> struct Xspecific
> {
>   int n;
>   int a[7];
> } specific;
> } x;
> 
> int
> foo (struct Xflex *f)
> {
>   f->a[6] = 2;
>   x.specific.a[6] = 1;
>   return f->a[6];
> }
> 
> i.e. have a generic struct with flexible array member, which is what e.g.
> the libgfortran APIs take as arguments, and when you actually need an object
> on the stack or static object, make it a union of that generic struct with
> flexible array member and the struct specific for how big rank you want.
> 
> I can try to implement that next week if that's what we agree on.

Note given you control what IL is presented to GCC in the Fortran FE
you don't need to jump through hoops using a union -- you can
rely on the middle-end behavior and simply emit code as if you'd
write in C:

 ((struct Xflex *)&x)->a[6] = 1;

or in GENERIC terms you wrap the Xspecific objects in
a MEM_REF with operand 1 being build_int_cst (pointer_to_Xflex_type_node, 
0) which tells GCC to use the alias-set of Xflex.

So wherever you build "decls" of one of the array-descriptor types
(or embed them into a struct!) when you access the descriptor
use the trailing-array variant.

I think I've seen all array descriptor accesses code-generation
abstracted away in some helper routines.

Richard.

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

end of thread, other threads:[~2018-02-05 10:17 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-03 17:09 Fortran LTO and array descriptors Thomas Koenig
2018-02-03 17:17 ` Thomas Koenig
2018-02-04 11:42   ` Richard Biener
2018-02-04 11:48     ` Richard Biener
2018-02-04 20:15     ` Thomas Koenig
2018-02-05  6:42       ` Richard Biener
2018-02-04 12:36 ` Richard Biener
2018-02-05  7:54 ` Jakub Jelinek
2018-02-05 10:17   ` Richard Biener

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).