This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFH: Impose code-movement restrictions and value assumption (for ASYNCHRONOUS/Coarrays)


On 07/14/2011 11:21 AM, Richard Guenther wrote:
That Fortran passes everything by reference is really really not helping
optimizers.

I think it also does not harm optimizers. The problem is just that optimizers are not tuned for it - but for C with later (C99?) attached qualifiers.


Whether one has
  int func(int arg) {
    do_something_with_arg
    return arg;
  }
or
  subroutine func(arg)  ! arg passed by reference
     integer :: arg

shouldn't make any difference for optimizers. The value can only change by either directly modifying "arg" or by calling a procedure with it as explicit actual argument, which modifies it.

In Fortran, any tricks like modifying "arg" via a global variable (which shares the memory location with "arg") are invalid. It is not even allowed to read the value of the global variable (having the same memory address as "arg"), if the value of "arg" is modified in "func" - not even before it is modified.

If one wants to play those tricks, "arg" needs to have at least the TARGET attribute (i.e. some pointer may point to it) - or even the POINTER attribute, for which nearly anything goes.

Some of the restrictions are compile-time checkable, i.e. if you try to pass a non-target, non-pointer variable as actual argument to a pointer-dummy argument, you will get a compile-time error.

For others, it's the users responsibility. For instance, you may pass a non-TARGET variable to a function taking a TARGET as dummy argument, but as soon as that function returns, all pointers to the dummy become undefined.

The advantage of Fortran is that it not only applies to basic types like "int" but also to character strings, arrays - and to "allocatables". Allocatables have to be allocated before one can use them, allowing one to change the array size or (for deferred-length strings) the string length. Still, they share the same semantics, i.e. no aliasing unless there is TARGET or (for non-ALLOCATABLEs) a POINTER attribute.

(Side remark: allocatables [unless SAVE, i.e. in static memory] are automatically freed, when one leaves their "scoping unit", e.g. for a variable local to a function, when one leaves that function. That's Fortran's way of garbage collection. If one does not want it, one has to use pointers.)

In that sense, the lack of a qualifier in C, which matches Fortran, is "really really not helping optimizers". ;-)


It's also not helping that my Fortran FU is weak
so I'm not able to produce testcases that will immediately show
issues with (proposed) middle-end representations.

Yes, that's indeed a problem, though I don't see how one can best solve it. I can only offer to help with questions, finding the relevant sections in the standard, and helping to interpret them.



For what it is worth, in the Fortran 2008 standard, one finds regarding this issue (cf. PR 49733) more at:


* "12.5.2.13 Restrictions on entities associated with dummy arguments"
Namely, rules when a dummy argument may be changed behind the scenes, including when the standard guarantees that the actual and the dummy argument actually point to the same memory.
That also forbids that one passes twice the same variable as actual argument, if one modifies either argument. (Unless one has a pointer - or a TARGET (+ some additional restrictions).)


The additional restrictions are there to avoid issues, when copy-in/copy-out happens. In some cases Fortran has to make a copy - and pass the copy instead of the (address of the) actual argument, e.g. if the dummy argument wants to have a contiguous array but the actual argument has strides.


* "16.5.2.5 Events that cause the association status of pointers to become undefined"
For instance, the issue mentioned above: One has a pointer to some object which has locally a target attribute - or exists only locally - then the pointer becomes undefined, if one returns from that function.


There are some more relevant spots in the standard, e.g. those where pointer and target is defined. Or the place, where argument passing is handled, cf. "12.5.2 Actual arguments, dummy arguments, and argument association".

For instance an actual argument may only passed to a pointer dummy argument, if it is a pointer - or if the dummy argument has the target attribute and the dummy argument is INTENT(IN); the first avoids alias issues and the second ensures that one does not modify the memory address to which the argument points to. Cf. "12.5.2.7 Pointer dummy variables" for the latter.

Tobias


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]