fir.dispatch code generation uses the binding table stored in the
type descriptor. There is no runtime call involved. The binding table
is always build from the parent type so the index of a specific binding
is the same in the parent derived-type or in the extended type.
Follow-up patches will deal cases not present here such as allocatable
polymorphic entities or pointers.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D136189
non-polymorphic derived-type can call type-bound procedure with passed-object.
In that case, the derived-type is emboxed in order to be passed to the call.
Until now the emboxing was done to a fir.box followed by a fir.convert.
This patch update the createBox function so that we can directly embox to
a fir.class and avoid the extra fir.convert.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D135790
Lower call with polymorphic entities to fir.dispatch operation. This patch only
focus one lowering with simple scalar polymorphic entities. A follow-up patch
will deal with allocatble, pointer and array of polymorphic entities as they
require box manipulation for the passed-object.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D135649
This patch updates lowering to produce the correct fir.class types for
various polymorphic and unlimited polymoprhic entities cases. This is only the
lowering. Some TODOs have been added to the CodeGen part to avoid errors since
this part still need to be updated as well.
The fir.class<*> representation for unlimited polymorphic entities mentioned in
the document has been updated to fir.class<none> to avoid useless work in pretty
parse/printer.
This patch is part of the implementation of the poltymorphic
entities.
https://github.com/llvm/llvm-project/blob/main/flang/docs/PolymorphicEntities.md
Depends on D134957
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D134959
Copy-in/copy-out was not triggered when calling a procedure with a
CONTIGUOUS assumed shape. The actual argument must be copied-in/out
if it is not contiguous.
The copy-in/copy-out takes care of argument optionality, and uses a
runtime check in order to only do the copy if the actual is not
contiguous at runtime.
This was already implemented for explicit shape dummy arguments. This
patch takes advantage of this implementation to deal with the copy-in
copy-out aspects. It only need add code to deals with wrapping the
created bare contiguous address into a fir.box (runtime descriptor),
taking care of the optional box aspects.
Using this existing code is only possible for actual argument that can
be passed via a bare address. Add a TODO for polymorphic entity, PDTs
and assumed rank where the existing copy-in/copy-out code may fail
(these copies are more complex) and that cannot be tested currently.
Differential Revision: https://reviews.llvm.org/D134543
BIND(C) Function returning character must return it by value and
not as hidden argument like done currently. This patch update the
code to return it by value for both use cases.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D134530
Add TODO for whole array allocatable assignment inside FORALL
Whole allocatable array assignment inside FORALL are otherwise currently
hitting more cryptic asserts.
Add TODO in FORALL assignment when a designator appear with a part ref
that is an allocatable or pointer component (a(i)%pointer%k). The lowering
code does not handle this case well because of the pointer dereference.
Differential Revision: https://reviews.llvm.org/D134440
Parent component refers to the parent derived-type of an extended type.
The parent component is skipped when a specififc component is
referred to. This is fine since all the components in extended type
are available in the type itself. When the parent component is referred,
it need to be taken into account correctly.
This patch fixes the case when the parent component is referred. In a
box, an approriate slice is created or updated to point to the first
component of the parent component. For scalar, a simple conversion to
the parent component type is done.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D134170
From Fortran 2018 standard 9.7.3.2 point 6:
When a procedure is invoked, any allocated allocatable object that is an actual
argument corresponding to an INTENT (OUT) allocatable dummy argument is
deallocated; any allocated allocatable object that is a subobject of an actual
argument corresponding to an INTENT (OUT) dummy argument is deallocated.
Deallocation is done on the callee side. For BIND(C) procedure, the deallocation
is also done on the caller side.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D133348
As Fortran 2018 18.2.3.3, the intrinsic module procedure
C_F_POINTER(CPTR, FPTR [, SHAPE]) associates a data pointer with the
target of a C pointer and specify its shape. CPTR shall be a scalar of
type C_PTR, and its value is the C address or the result of a reference
to C_LOC. FPTR is one pointer, either scalar or array. SHAPE is a
rank-one integer array, and it shall be present if and only if FPTR is
an array.
C_PTR is the derived type with only one component of integer 64, and the
integer 64 component value is the address. Build the right "source"
fir::ExtendedValue based on the address and shape, and use
associateMutableBox to associate the pointer with the target of the C
pointer.
Refactor the getting the address of C_PTR to reuse the code.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D132303
Lowering was truncating 128 bits integer to 64 bits. This
patch makes use of APInt to lower 128 bits integer correctly.
```
program bug
print *, 170141183460469231731687303715884105727_16
end
! Before patch: 18446744073709551615
! With patch: 170141183460469231731687303715884105727
```
Reviewed By: vdonaldson
Differential Revision: https://reviews.llvm.org/D133206
Runtime functions expect clean unallocated state for descriptor. This
patch adds a call to the runtime function to initialize the temporary
derived-type created.
Reviewed By: vdonaldson
Differential Revision: https://reviews.llvm.org/D133189
This patch adds contiguity check with the runtime to avoid copyin/copyout
in case the actual argument is actually contiguous.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D133097
This patch adds contiguity check with the runtime to avoid copyin/copyout
in case the actual argument is actually contiguous.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D133097
As Fortran 2018 18.2.3.5, the intrinsic c_funloc(x) gets the C address
of argument x. It returns the scalar of type C_FUNPTR. As defined in
iso_c_binding in flang/module/__fortran_builtins.f90, C_FUNPTR is the
derived type with only one component of integer 64.
This follows the implementation of https://reviews.llvm.org/D129659. The
argument is lowered as ProcBox and the address is generated using
fir.box_addr.
Reviewed By: jeanPerier, clementval
Differential Revision: https://reviews.llvm.org/D132273
This patch creates a temporary of the appropriate length while lowering SetLength.
The corresponding character can be truncated or padded if necessary.
This fix issue with array constructor in argument and also with statement function.
D132464 was fixing the same issue in genval.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D132866
As Fortran 2018 18.3.2, C_PTR is interoperable with any C object pointer
type. C_FUNPTR is interoperable with any C function pointer type. As
18.3.6, a C pointer can correspond to a Fortran dummy argument of type
C_PTR with the VALUE attribute.
The interface for type(C_PTR)/type(C_FUNPTR) argument with value
attribute is different from the the usual derived type. For type(C_PTR)
or type(C_FUNPTR), the component is the address, and the interface is
a pointer even with VALUE attribute. For a usual derived type such as
the drived type with the component of integer 64, the interface is a i64
value when it has VALUE attribute on aarch64 linux.
To lower the type(C_PTR)/type(C_FUNPTR) argument with value attribute,
get the value of the component of the type(C_PTR)/type(C_FUNPTR), which
is the address, and then convert it to the pointer and pass it.
Reviewed By: Jean Perier
Differential Revision: https://reviews.llvm.org/D131583
As the comment tells, the TODO was added because
there was no conversion for abstract results in function types inside GlobalOps.
Since the conversion was added, this TODO is obsolete, so it is removed.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D130369
This patch creates a temporary of the appropriate length while lowering SetLength.
The corresponding character can be truncated or padded if necessary.
This fix issue with array constructor in argument and also with statement function.
```
character(7) :: str = "1234567"
call s(str(1:1))
contains
subroutine s(a)
character(*) :: a
call s2([Character(3)::a])
end subroutine
subroutine s2(c)
character(3) :: c(1)
print "(4a)", c(1), "end"
end subroutine
end
```
The example prior the patch prints `123end` instead of `1. end`
Reviewed By: PeteSteinfeld, jeanPerier
Differential Revision: https://reviews.llvm.org/D132464
Function returning CHARACTER with adjustable length or dynamic arrays
can have negative length or extents passed to them. This patch makes sure
any negative inputs is rounded to 0.
Reviewed By: vdonaldson
Differential Revision: https://reviews.llvm.org/D132139
This commit addresses concerns raised in D129497.
Propagate lowering options from driver to expressions lowering
via AbstractConverter instance. A single use case so far is
using optimized TRANSPOSE lowering with O1/O2/O3.
bbc does not support optimization level switches, so it uses
default LoweringOptions (e.g. optimized TRANSPOSE lowering
is enabled by default, but an engineering -opt-transpose=false
option can still override this).
Differential Revision: https://reviews.llvm.org/D130204
When an array is defined with "unknown" size, such as fir.array<2x?x5xi32>,
it should be converted to llvm.array<10 x i32>. The code so far has
been converting it to llvm.ptr<i32>.
Using a different function to check the if there starting are constant
dimensions, rather than if ALL dimensions are constant, it now produces
the correct array form.
Some tests has been updated, so they are now checking the new behaviour
rather than the old behaviour - so there's no need to add further tests
for this particular scenario.
This was originally found when compiling Spec 17 code, where an assert
in a GepOP was hit. That is bug #56141, which this change fixes.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D129196
Calling runtime TRANSPOSE requires a temporary array for the result,
and, sometimes, a temporary array for the argument. Lowering it inline
should provide faster code.
I added -opt-transpose control just for debugging purposes temporary.
I am going to make driver changes that will disable inline lowering
for -O0. For the time being I would like to enable it by default
to expose the code to more tests.
Differential Revision: https://reviews.llvm.org/D129497
Flang C++ Style Guide tells us to avoid .has_value() in the predicate
expressions of control flow statements. I am treating ternary
expressions as control flow statements for the purpose of this patch.
Differential Revision: https://reviews.llvm.org/D128622
Array-value-copy fails to generate a temporary array for case like this:
subroutine bug(b)
real, allocatable :: b(:)
b = b(2:1:-1)
end subroutine
Since LHS may need to be reallocated, lowering produces the following FIR:
%rhs_load = fir.array_load %b %slice
%lhs_mem = fir.if %b_is_allocated_with_right_shape {
fir.result %b
} else {
%new_storage = fir.allocmem %rhs_shape
fir.result %new_storage
}
%lhs = fir.array_load %lhs_mem
%loop = fir.do_loop {
....
}
fir.array_merge_store %lhs, %loop to %lhs_mem
// deallocate old storage if reallocation occured,
// and update b descriptor if needed.
Since %b in array_load and %lhs_mem in array_merge_store are not the same SSA
values, array-value-copy does not detect the conflict and does not produce
a temporary array. This causes incorrect result in runtime.
The suggested change in lowering is to generate this:
%rhs_load = fir.array_load %b %slice
%lhs_mem = fir.if %b_is_allocated_with_right_shape {
%lhs = fir.array_load %b
%loop = fir.do_loop {
....
}
fir.array_merge_store %lhs, %loop to %b
fir.result %b
} else {
%new_storage = fir.allocmem %rhs_shape
%lhs = fir.array_load %new_storage
%loop = fir.do_loop {
....
}
fir.array_merge_store %lhs, %loop to %new_storage
fir.result %new_storage
}
// deallocate old storage if reallocation occured,
// and update b descriptor if needed.
Note that there are actually 3 branches in FIR, so the assignment loops
are currently produced in three copies, which is a code-size issue.
It is possible to generate just two branches with two copies of the loops,
but it is not addressed in this change-set.
Differential Revision: https://reviews.llvm.org/D129314
This patch is part of the upstreaming effort from fir-dev branch.
This is the last patch for the upstreaming effort.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D129187
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D128976
Co-authored-by: V Donaldson <vdonaldson@nvidia.com>
Fix for broken/degenerate forall case where there is no assignment to an
array under the explicit iteration space. While this is a multiple
assignment, semantics only raises a warning.
The fix is to add a test that the explicit space has any sort of array
to be updated, and if not then the do_loop nest will not require a
terminator to forward array values to the next iteration.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D128973
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D128935
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
Co-authored-by: Peter Steinfeld <psteinfeld@nvidia.com>
As Fortran 2018 16.9.163, the reshape is the only intrinsic which
requires the shape argument to be rank-one integer array and the SIZE
of it to be one constant expression. The current expression lowering
converts the shape expression with slice in intrinsic into one box value
with the box element type of unknown extent. However, the genReshape
requires the box element type to be constant size. So, convert the box
value into one with box element type of sequence of 1 x constant. This
corner case is found in cam4 in SPEC 2017
https://github.com/llvm/llvm-project/issues/56140.
Reviewed By: Jean Perier
Differential Revision: https://reviews.llvm.org/D128597
The names of CHARACTER strings were being truncated leading to invalid
collisions and other failures. This change makes sure to use the entire
string as the seed for the unique name.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D128884
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
Here is a character SELECT CASE construct that requires a temp to hold the
result of the TRIM intrinsic call:
```
module m
character(len=6) :: s
contains
subroutine sc
n = 0
if (lge(s,'00')) then
select case(trim(s))
case('11')
n = 1
case default
continue
case('22')
n = 2
case('33')
n = 3
case('44':'55','66':'77','88':)
n = 4
end select
end if
print*, n
end subroutine
end module m
```
This SELECT CASE construct is implemented as an IF/ELSE-IF/ELSE comparison
sequence. The temp must be retained until some comparison is successful.
At that point the temp may be freed. Generalize statement context processing
to allow multiple finalize calls to do this, such that the program always
executes exactly one freemem call.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: klausler, vdonaldson
Differential Revision: https://reviews.llvm.org/D128852
Co-authored-by: V Donaldson <vdonaldson@nvidia.com>
- Add verifiers that determine if an Op requires type parameters or
not and checks that the correct number of parameters is specified.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D128828
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
This patch fixes a couple of issues with the lowering of user defined assignment.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D128730
Co-authored-by: Jean Perier <jperier@nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
For the rapid triage push, just add a TODO for the degenerate POINTER
assignment case. The LHD ought to be a variable of type !fir.box, but it
is currently returning a shadow variable for the raw data pointer. More
investigation is needed there.
Make sure that conversions are applied in FORALL degenerate contexts.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D128724
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
This patch restores several calls to Optional::value() in preference
to Optional::operator*.
The Flang C++ Style Guide tells us to use x.value() where no presence
test is obviously protecting a *x reference to the contents.
Differential Revision: https://reviews.llvm.org/D128590
When there is a substring operation on a scalar assignment in a FORALL
context, we have to lower the entire substring and not the entire
CHARACTER variable.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: PeteSteinfeld, klausler
Differential Revision: https://reviews.llvm.org/D128459
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
Character conversion requires memory storage as it operates on a
sequence of code points.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D128438
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
* Make Semantics test doconcurrent01.f90 an expected failure pending a fix
for a problem in recognizing a PURE prefix specifier for a specific procedure
that occurs in new intrinsic module source code,
* review update
* review update
* Increase support for intrinsic module procedures
The f18 standard defines 5 intrinsic modules that define varying numbers
of procedures, including several operators:
2 iso_fortran_env
55 ieee_arithmetic
10 ieee_exceptions
0 ieee_features
6 iso_c_binding
There are existing fortran source files for each of these intrinsic modules.
This PR adds generic procedure declarations to these files for procedures
that do not already have them, together with associated specific procedure
declarations. It also adds the capability of recognizing intrinsic module
procedures in lowering code, making it possible to use existing language
intrinsic code generation for intrinsic module procedures for both scalar
and elemental calls. Code can then be generated for intrinsic module
procedures using existing options, including front end folding, direct
inlining, and calls to runtime support routines. Detailed code generation
is provided for several procedures in this PR, with others left to future PRs.
Procedure calls that reach lowering and don't have detailed implementation
support will generate a "not yet implemented" message with a recognizable name.
The generic procedures in these modules may each have as many as 36 specific
procedures. Most specific procedures are generated via macros that generate
type specific interface declarations. These specific declarations provide
detailed argument information for each individual procedure call, similar
to what is done via other means for standard language intrinsics. The
modules only provide interface declarations. There are no procedure
definitions, again in keeping with how language intrinsics are processed.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D128431
Co-authored-by: V Donaldson <vdonaldson@nvidia.com>
The case where the dummy argument is OPTIONAL was missing in the
handling of VALUE numerical and logical dummies (passBy::BaseAddressValueAttribute).
This caused segfaults while unconditionally copying actual arguments that were legally
absent at runtime.
Takes this bug as an opportunity to share the code that lowers arguments
that must be passed by BaseAddress, BaseAddressValueAttribute, BoxChar,
and CharBoxValueAttribute.
It has to deal with the exact same issues (being able to make contiguous
copies of the actual argument, potentially conditionally at runtime,
and potentially requiring a copy-back).
The VALUE case is the same as the non value case, except there is never
a copy-back and there is always a copy-in for variables. This two
differences are easily controlled by a byValue flag.
This as the benefit of implementing CHARACTER, VALUE for free that was
previously a hard TODO.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D128418
Co-authored-by: Jean Perier <jperier@nvidia.com>