In order to be passed as passed-object in the dynamic dispatch, the
polymorphic pointer entity are emboxed. In this process, the dynamic
type must be preserve and pass to fir.embox as the tdesc operand. This
patch introduce a new ExtendedValue that allow to carry over the
dynamic type when the value is unboxed.
Depends on D136820
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D136824
Reuse the previous record assignment code. Use gen(expr) to generate
the fir::ExtendedValue of parent component recursively and convert the
structure to a fir.ref<T> type, where T is the record type of parent
component. Then, fir:🏭:genRecordAssignment can be reused to
assign the parent component to the type-casted structure.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D136530
fir.dispatch code generation was not handling fir.class pointer and
allocatable types. Update the code generation part to rertieve correctly the
the type info from those types.
Depends on D136426
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D136429
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>