[flang] Corrections and additions

Original-commit: flang-compiler/f18@000301fcf9
Reviewed-on: https://github.com/flang-compiler/f18/pull/683
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2019-08-28 11:25:55 -07:00
parent c71ba62c9f
commit a26bbed6d6
1 changed files with 101 additions and 64 deletions

View File

@ -1,4 +1,4 @@
<!--
<!--
Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
-->
@ -16,6 +16,31 @@ the Fortran 2018 standard.
This note does not consider calls to intrinsic procedures, statement
functions, or calls to internal runtime support library routines.
## Quick review of terminology
* A *dummy argument* is a function or subroutine parameter.
It is *associated* with an *effective argument* at each call
to the procedure.
* An *explicit-shape* array has all of its bounds specified; lower
bounds default to 1. These can be passed by with a single address
and their contents are contiguous.
* An *assumed-size* array is an explicit-shape array with `*` as its
final dimension, which the most-significant one in Fortran.
* A *deferred-shape* array is a `POINTER` or `ALLOCATABLE`.
`POINTER` target data might not be contiguous.
* An *assumed-shape* (not size!) array is a dummy argument whose
upper bounds take their values from the *shape* of the effective
argument; lower bounds can be set by the procedure that receives
them and default to 1.
* An *assumed-length* `CHARACTER(*)` dummy argument or function
takes its length from the effective argument or from its
eventual declaration in a calling scope (respectively).
* An *assumed-rank* dummy argument array has an unknown number
of dimensions.
* A *polymorphic* dummy argument has a specific derived type or any
possible extension of that type. An *unlimited polymorphic*
dummy argument can have any type.
## Interfaces
Referenced procedures may or may not have declared interfaces
@ -24,7 +49,7 @@ available to their call sites.
Calls to procedures with some post-Fortran '77 features require an
explicit interface (15.4.2.2):
* keyword arguments
* use of argument keywords
* procedures that are `ELEMENTAL` or `BIND(C)`
* procedures that are required to be `PURE` due to the context of the call
(specification expression, `DO CONCURRENT`, `FORALL`)
@ -48,11 +73,16 @@ Note that non-parameterized monomorphic derived type arguments do
not by themselves require the use of an explicit interface.
A procedure that requires an explicit interface must, in a strict
reading of the standard (15.4.2.2, and see 7.4.4.2(5) for assumed-length
`CHARACTER(*)`) have that interface available when the procedure is
passed as an actual argument (but see 15.5.2.9(2), which explicitly
reading of the standard (4.3.4(2) & 15.4.2.2),
have that interface available when the procedure is passed as an
argument.
As a special case, see also 15.5.2.9(2), which explicitly
allows an assumed-length `CHARACTER(*)` function to be passed as an actual
argument to an explicit-length dummy).
argument to an explicit-length dummy); this has implications for
calls to character-valued dummy functions and function pointers.
(In the scopes that reference `CHARACTER` functions, they must have
visible definitions with explicit result lengths.)
### Implicit interfaces
@ -83,7 +113,7 @@ types, possibly by means of implicit typing of their names.
They can also be `CHARACTER(*)` assumed-length character functions.
In other words: procedures that can be referenced with implicit interfaces
have argument lists that comprise only addresses of actual arguments
have argument lists that comprise only addresses of effective arguments
and the length of a `CHARACTER` function result (if any),
and they can return only scalar values of intrinsic types.
None of their arguments or results need be (or can be) implemented
@ -112,7 +142,7 @@ some design alternatives that are explored further below.
### Before the call:
1. Compute &/or copy into temporary storage the values of
some actual argument expressions and designators (see below).
some effective argument expressions and designators (see below).
1. Create and populate descriptors for arguments that use them
(see below).
1. Possibly allocate function result storage,
@ -125,9 +155,15 @@ some design alternatives that are explored further below.
package them into single address (for calls to internal procedures &
for calls that pass internal procedures as arguments).
1. Resolve the target procedure's polymorphic binding, if any.
1. Marshal actual argument addresses (or values for `VALUE`/`%VAL()`) into registers.
1. Marshal effective argument addresses (or values for `VALUE`/`%VAL()`) into registers.
1. Marshal `CHARACTER` argument lengths in additional value arguments for
`CHARACTER` effective arguments not passed via descriptors.
1. Marshal an extra argument for the `CHARACTER` result
length (assumed or explicit) or the function result descriptor.
length when calling a `CHARACTER`-valued function, if there is a chance
that it might be assumed-length or could be called over an implicit
interface.
1. Marshal an extra argument for the function result's descriptor,
if it needs one.
1. Set the "host instance" (static link) register when calling an internal
procedure from its host or another internal procedure, a procedure pointer,
or dummy procedure (when it has a descriptor).
@ -135,13 +171,14 @@ some design alternatives that are explored further below.
### On entry:
1. Shuffle `ENTRY` dummy arguments & jump to common entry point.
1. Capture `CHARACTER` argument &/or assumed-length result length values.
1. Complete `VALUE` copying if this step will not always be done
by the caller (as I think it should be).
1. Finalize &/or re-initialize `INTENT(OUT)` non-pointer
actual arguments (see below).
effective arguments (see below).
1. For interoperable procedures called from C: compact discontiguous
dummy argument values when necessary (`CONTIGUOUS` &/or
explicit-shape/assumed-size arrays of assumed-length `CHARACTER`).
explicit-shape/assumed-size arrays of assumed-length `CHARACTER(*)`).
1. Optionally compact assumed-shape arguments for contiguity on one
or more leading dimensions to improve SIMD vectorization, if not
`TARGET` and not already sufficiently contiguous.
@ -167,9 +204,9 @@ the subroutine's alternate return.
### On return to the caller:
1. Save the result registers, if any.
1. Copy actual argument array designator data that was copied into
1. Copy effective argument array designator data that was copied into
a temporary back into its original storage (see below).
1. Complete deallocation of actual argument temporaries (not `VALUE`).
1. Complete deallocation of effective argument temporaries (not `VALUE`).
1. Reload definable host-escaping local objects from memory, if they
were saved to memory by the host before the call.
1. `GO TO` alternate return, if any.
@ -178,13 +215,13 @@ the subroutine's alternate return.
## The messy details
### Copying actual argument values into temporary storage
### Copying effective argument values into temporary storage
There are several conditions that require the compiler to generate
code that allocates and populates temporary storage for an actual
argument.
First, actual arguments that are expressions, not designators, obviously
First, effective arguments that are expressions, not designators, obviously
need to be computed and captured into memory in order to be passed
by reference.
This includes parenthesized designators like `(X)`, which are
@ -199,7 +236,7 @@ Small scalar or elemental `VALUE` arguments may be passed in registers,
as should arguments wrapped in the legacy VMS `%VAL()` notation.
Multiple elemental `VALUE` arguments might be packed into SIMD registers.
Actual arguments that are designators, not expressions, must also
Effective arguments that are designators, not expressions, must also
be copied into temporaries in the following situations.
1. Coindexed objects need to be copied into the local image.
@ -207,32 +244,32 @@ be copied into temporaries in the following situations.
components, which also need to be copied, along with their
`ALLOCATABLE` components, and may be best implemented with a runtime
library routine working off a description of the type.
1. Actual arguments associated with dummies with the `VALUE`
1. Effective arguments associated with dummies with the `VALUE`
attribute need to copied; this could be done on either
side of the call, but there are optimization opportunities
on the caller's side.
1. In non-elemental calls, the values of array sections with
vector-valued subscripts need to be gathered into temporaries.
These actual arguments are not definable, and they are not allowed to
These effective arguments are not definable, and they are not allowed to
be associated with non-`VALUE` dummy arguments with the attributes
`INTENT(IN)`, `INTENT(IN OUT)`, `ASYNCHRONOUS`, or `VOLATILE`
(15.4.2.4(21)); `INTENT()` can't always be checked.
1. Non-simply-contiguous (9.5.4) arrays being passed to non-`POINTER`
dummy arguments that must be contiguous due to a `CONTIGUOUS`
attribute, implicit interface, or not being assumed-shape/-rank.
This should be a runtime decision, so that actual arguments
This should be a runtime decision, so that effective arguments
that turn out to be contiguous can be passed cheaply.
This rule does not apply to coarray dummies, whose actual arguments
This rule does not apply to coarray dummies, whose effective arguments
are required to be simply contiguous when this rule would otherwise
force the use of a temporary (15.5.2.8); neither does it apply
to `ASYNCHRONOUS` and `VOLATILE` actual arguments, which are
to `ASYNCHRONOUS` and `VOLATILE` effective arguments, which are
disallowed when it matters (C1539, C1540).
*Only temporaries created by this contiguity requirement are
subject to being copied back to the original variable after
candidates for being copied back to the original variable after
the call* (see below).
Fortran requires (18.3.6(5)) that interoperable procedure dummy
arguments with `CONTIGUOUS` &/or assumed-length `CHARACTER`
arguments with `CONTIGUOUS` &/or assumed-length `CHARACTER(*)`
explicit-shape/assumed-size arrays handle the compaction of
discontiguous data *in the callee*, at least when called from C.
And discontiguous data must be compacted on the *caller's* side
@ -240,14 +277,14 @@ when passed from Fortran to C (18.3.6(6)).
We could perform all argument compaction (discretionary or
required) in the callee, but there are many cases where the
compiler knows that the actual argument data are contiguous
compiler knows that the effective argument data are contiguous
when compiling the caller (a temporary is needed for other reasons,
or the actual argument is simply contiguous) and a run-time test for
or the effective argument is simply contiguous) and a run-time test for
discontiguity in the callee can be avoided by using a caller-compaction
convention when we have the freedom to choose.
While we are unlikely to want to _needlessly_ use a temporary for
an actual argument that does not require one for any of these
an effective argument that does not require one for any of these
reasons above, we are specifically disallowed from doing so
by the standard in cases where pointers to the original target
data are required to be valid across the call (15.5.2.4(9-10)).
@ -255,7 +292,7 @@ In particular, compaction of assumed-shape arrays for discretionary
contiguity on the leading dimension to ease SIMD vectorization
cannot be done safely for `TARGET` dummies without `VALUE`.
Actual arguments associated with known `INTENT(OUT)` dummies that
Effective arguments associated with known `INTENT(OUT)` dummies that
require allocation of a temporary -- and this can only be for reasons of
contiguity -- don't have to populate it, but they do have to perform
minimal initialization of any `ALLOCATABLE` components so that
@ -270,16 +307,16 @@ could optionally have their `ALLOCATABLE` components invalidated
across the call as an aid to debugging.
Except for `VALUE` and known `INTENT(IN)` dummy arguments, the contents of
the temporary storage will be copied back into the actual argument
the temporary storage will be copied back into the effective argument
designator after control returns from the procedure, and it may be necessary
to preserve addresses (or the values of subscripts and cosubscripts
needed to recalculate them) of the actual argument designator, or its
needed to recalculate them) of the effective argument designator, or its
elements, in additional temporary storage if they can't be safely or
quickly recomputed after the call.
### `INTENT(OUT)` preparation
Actual arguments that are associated with `INTENT(OUT)`
Effective arguments that are associated with `INTENT(OUT)`
dummy arguments are required to be definable.
This cannot always be checked, as the use of `INTENT(OUT)`
does not by itself mandate the use of an explicit interface.
@ -293,7 +330,7 @@ Derived type components that are `ALLOCATABLE` are finalized
and deallocated.
Components with initializers are (re)initialized.
The preparation of actual arguments for `INTENT(OUT)` could be
The preparation of effective arguments for `INTENT(OUT)` could be
done on either side of the call. If the preparation is
done by the caller, there is an optimization opportunity
in situations where unmodified incoming `INTENT(OUT)` dummy
@ -335,8 +372,9 @@ variable or temporary when it is safe to treat the variable as if
it were an additional `INTENT(OUT)` argument.
(Storage for `CHARACTER` results, assumed or explicit, is always
allocated by the caller, and the length is always passed so that
an assumed-length external function will work when called in an
explicit-length context (15.5.2.9 (2)).)
an assumed-length external function will work when eventually
called from a scope that declares the length that it will use
(15.5.2.9 (2)).)
Note that the lower bounds of the dimensions of non-`POINTER`
non-`ALLOCATABLE` dummy argument arrays are determined by the
@ -356,11 +394,11 @@ descriptors with the assumption that the callee will use 1 for
lower bound values, and callees can rely on them being 1 if
not modified.
### Copying temporary storage back into actual argument designators
### Copying temporary storage back into argument designators
Except for `VALUE` and known `INTENT(IN)` dummy arguments and array sections
with vector-valued subscripts (15.5.2.4(21)), temporary storage into
which actual argument data were compacted for contiguity before the call
which effective argument data were compacted for contiguity before the call
must be redistributed back to its original storage by the caller after
the return.
@ -381,7 +419,7 @@ resolved at compilation time, as are calls to `NON_OVERRIDABLE`
type-bound procedures.
The resolution of calls to overridable type-bound procedures of
polymorphic types must be completed at execution (generic resolution
of type-bound procedure bindings from actual argument types, kinds,
of type-bound procedure bindings from effective argument types, kinds,
and ranks is always a compilation-time task (15.5.6, C.10.6)).
Each derived type that declares or inherits any overridable
@ -398,7 +436,7 @@ Calls to dummy procedures and procedure pointers that resolve to
internal procedures need to pass an additional "host instance" argument that
addresses a block of storage in the stack frame of the their
host subprogram that was active at the time they were passed as an
actual argument or associated with a procedure pointer.
effective argument or associated with a procedure pointer.
This is similar to a static link in implementations of programming
languages with nested subprograms, although Fortran only allows
one level of nesting.
@ -424,7 +462,7 @@ For procedures that can be called with an implicit interface,
we cannot use a "procedure pointer descriptor" to pass them an
a procedure argument -- a Fortran '77 routine
with an `EXTERNAL` dummy argument expects to receive a single
address argument. Instead, when passing an actual procedure
address argument. Instead, when passing an effective procedure
to a procedure that can be called with an implicit interface,
we will need to package the host instance link in a trampoline
that loads its address into the designated register.
@ -443,9 +481,9 @@ that are not always successfully forwarded across implicit interfaces,
sometimes leading to crashes when they turn out to be needed.
F18 will manage a pool of trampolines in its runtime support library
that can be used to pass internal procedures as actual arguments
that can be used to pass internal procedures as effective arguments
to targets that might be called with an implicit interface, so that
a bare code address is used to represent the actual argument.
a bare code address is used to represent the effective argument.
But targets that can only be called with an explicit interface
have the option of using a "fat pointer" (or additional argument)
to represent a dummy procedure closure so as
@ -475,13 +513,11 @@ entry points used for packed SIMD arguments of various widths if we support
calls to these functions in SIMD parallel contexts.
There are already conventions for these names in `libpgmath`.
It would be great to have the option of distinguishing the names of
external procedures that cannot be called via an implicit interface
as a means for catching attempts to do so and causing them to fail with
link-time errors.
But this turns out to not be possible due to the possibility of passing
an `EXTERNAL` procedure without an interface as an argument to
another procedure with an implicit interface.
The names of external procedures that cannot be called via an implicit interface
should be distinguished as such so that incorrect attempts to call or pass
them with an implicit interface will fail to resolve at link time.
Fortran 2018 explicitly enables us to do this with a correction to Fortran
2003 in 4.3.4(2).
Last, there must be reasonably permanent naming conventions used
by the F18 runtime library for those unrestricted specific intrinsic
@ -502,7 +538,8 @@ with letters).
In particular, the period (`.`) seems safe to use as a separator character,
so a `Fa.` prefix can serve to isolate these discretionary names from
other uses and to identify the earliest link-compatible version.
For examples: `Fa.mod.foo`, `Fa.mod.submod.foo`.
For examples: `Fa.mod.foo`, `Fa.mod.submod.foo`, and (for an external
subprogram that requires an explicit interface) `Fa.foo`.
## Summary of checks to be enforced in semantics analysis
@ -514,11 +551,11 @@ For examples: `Fa.mod.foo`, `Fa.mod.submod.foo`.
15.5.2.4 requirements for non-`POINTER` non-`ALLOCATABLE` dummies:
* (2) dummy must be monomorphic for coindexed polymorphic actual
* (2) dummy must be polymorphic for assumed-size polymorphic actual
* (2) dummy cannot be `TYPE(*)` if actual is PDT or has TBPs or `FINAL`
* (4) character length of actual cannot be less than dummy
* (6) coindexed actual with `ALLOCATABLE` ultimate component requires
* (2) dummy cannot be `TYPE(*)` if effective is PDT or has TBPs or `FINAL`
* (4) character length of effective cannot be less than dummy
* (6) coindexed effective with `ALLOCATABLE` ultimate component requires
`INTENT(IN)` &/or `VALUE` dummy
* (13) a coindexed scalar actual requires a scalar dummy
* (13) a coindexed scalar effective requires a scalar dummy
* (14) a non-conindexed scalar usually requires a scalar dummy, with some exceptions
* (15-17) array rank agreement
* (20) `INTENT(OUT)` & `INTENT(IN OUT)` dummies require definable actuals
@ -528,32 +565,32 @@ For examples: `Fa.mod.foo`, `Fa.mod.submod.foo`.
* (C1538 - C1540) checks for `ASYNCHRONOUS` and `VOLATILE`
15.5.2.5 requirements for `ALLOCATABLE` & `POINTER` arguments when both
the dummy and actual arguments have the same attributes:
the dummy and effective arguments have the same attributes:
* (2) both or neither can be polymorphic
* (2) both are unlimited polymorphic or both have the same declared type
* (3) rank compatibility
* (4) actual argument must have deferred the same type parameters as the dummy
* (4) effective argument must have deferred the same type parameters as the dummy
15.5.2.6 `ALLOCATABLE` dummy arguments:
* (2) actual must be `ALLOCATABLE`
* (2) effective must be `ALLOCATABLE`
* (3) corank must match
* (4) coindexed actual requires `INTENT(IN)` dummy
* (4) coindexed effective requires `INTENT(IN)` dummy
* (7) `INTENT(OUT)` & `INTENT(IN OUT)` dummies require definable actuals
15.5.2.7 `POINTER` dummy arguments:
* (C1541) `CONTIGUOUS` dummy requires simply contiguous actual
* (C1542) actual argument cannot be coindexed unless procedure is intrinsic
* (2) actual argument must be `POINTER` unless dummy is `INTENT(IN)` and
actual could be the right-hand side of a pointer assignment statement
* (C1542) effective argument cannot be coindexed unless procedure is intrinsic
* (2) effective argument must be `POINTER` unless dummy is `INTENT(IN)` and
effective could be the right-hand side of a pointer assignment statement
15.5.2.8 corray dummy arguments:
* (1) actual argument must be coarray
* (1) effective argument must be coarray
* (1) `VOLATILE` attributes must match
* (2) `CONTIGUOUS` dummy (or implicitly contiguous non-assumed-shape array) requires simply contiguous actual
15.5.2.9 dummy procedures:
* (1) explicit dummy procedure interface must have same characteristics as actual
* (5) dummy procedure `POINTER` requirements on actual arguments
* (5) dummy procedure `POINTER` requirements on effective arguments
15.6.2.1 procedure definitions:
* `NON_RECURSIVE` procedures cannot recurse.
@ -563,7 +600,7 @@ the dummy and actual arguments have the same attributes:
These also apply to `ELEMENTAL` procedures that are not `IMPURE`.
`ELEMENTAL` requirements (15.8.1): C15100-C15103,
and C1533 (can't pass as actual argument unless intrinsic)
and C1533 (can't pass as effective argument unless intrinsic)
For interoperable procedures and interfaces (18.3.6):
* C1552 - C1559
@ -577,6 +614,6 @@ For interoperable procedures and interfaces (18.3.6):
* Alternate return specifiers
* `%VAL()`, `%REF()`, and `%DESCR()` legacy VMS interoperability extensions
* Unrestricted specific intrinsic functions as actual arguments
* Unrestricted specific intrinsic functions as effective arguments
* SIMD variants of `ELEMENTAL` procedures (& unrestricted specific intrinsics)
* Elemental subroutine calls with array arguments