When an optional intrinsic scalar is passed to a function expecting an
unlimited polymorphic dummy argument, the presence test must be done
before the emboxing otherwise it will result in a program crash.
Depends on D143888
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D143889
Force TRANSPOSE with polymorphic inputs through the runtime call
and carry the polymorphic type information from the matrix to
the result.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D143709
Code move without any change, the goal is to re-use this piece of
code for procedure designator lowering in HLFIR since there is no
significant changes in the way procedure designators will be
lowered.
Differential Revision: https://reviews.llvm.org/D143563
Creation of polymorphic array temporary cannot be done inlined.
Add a TODO so the current code exit in a clean way when lowering
reach it. A solution involving the runtime will be put in place.
Depends on D143490
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D143491
HLFIR requires mapping symbol to a single mlir::Value (produced
by a fir::FortranVariableOpInterface), while the current lowering
maps the value to a fir::ExtdendedValue.
So far, the HLFIR symbol query was a special one. Hence, all the code
directly using symMap.lookupSymbol and symMap.addSymbol did not work
with the lowering to HLFIR.
Refactor the code so that symbol lookup and add symbol go through
the converter in a centralize place that handles the HLFIR case
(translate fir::FortranVariableOpInterface to fir::ExtdendedValue
in lookups, and generate hlfir.declare when adding symbols).
In the refactoring, fir::FortranVariableOpInterface is added as
a symbolBox variant to avoid special casing all lookups (shallowLookup...).
Remove some unused SymbolBox member function instead of updating
them.
Differential Revision: https://reviews.llvm.org/D143395
This will allow IntrinsicCall to be used in passes to implement hlfir
transformational intrinsic operations.
Differential Revision: https://reviews.llvm.org/D143084
When referencing a single component from a polymorphic array in an expression,
the rebox operation should output a boxed array of that component type and
not a polymorphic boxed array as it was done.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D142462
Only updates the assert to check where the box is a BaseBoxType
instead of a BoxType since ClassType are also valid in that case.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D142442
Make sure the source passed to an intrinsic is still polymorphic when
it is an element of a polymorphic array. This was not handled properly
before.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D142380
When a `!fir.box<>` is passed as an actual argument to an optional
`!fir.class<>` dummy it needs a `fir.rebox` in order to propagate
the dynamic type information.
The `fir.rebox` needs to happen only on present argument.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D142340
NULL() passed as actual argument to a procedure with an optional
dummy argument is represented with `fir.box<none>` type. When the dummy
argument is polymoprhic or unlimited polymorphic, the SelectOp will complain
if the types of the two arguments are not identical. Add a conversion from
`fir.box<none>` to `fir.class<none>` in that case.
Other situations with optional will require a fir.rebox and will be done in
a follow up patch.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D142203
Until now, only the address of the type descriptor was hold in
a PolymorphicValue. In some cases, the element size and the
type code are also needed when creating new polymorphic
descriptors from an element of a polymorphic entity.
This patch updates PolymorphicValue to carry the source
descriptor from which the element is extracted. The source
descriptor is then used when emboxing the element to a new
polymorphic descriptor.
This simplify the code done in D141274 and will be used
when creating polymorphic temporary as well.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D141609
This supports the lowering of intrinsic IS_CONTIGUOUS for array argument.
The argument of assumed rank is not supported since it is not implemented
yet as the procedure argument. Add TODO for it.
Reviewed By: PeteSteinfeld, jeanPerier
Differential Revision: https://reviews.llvm.org/D141212
Deallocation of intent(out) allocatable was done in D133348. This patch adds
an if guard when the deallocation is done through a runtime call. The runtime
is crashing if the box is not allocated. Call the runtime only if the box is
allocated. This is the case for derived type, polymorphic and unlimited
polymorphic entities.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D141427
A previous patch (https://reviews.llvm.org/D136955) already refactored
intrinsic constant lowering to place in its own file and allow using it from
both the current lowering and the new lowering to HLFIR.
This patch does the same for derived types. The core function
"genStructComponentInInitializer" is moved from ConvertExpr.cpp and
renamed "genInlinedStructureCtorLitImpl" into ConvertConstant.cpp
without significant logic change.
Then, genScalarLit, genArrayLit (and genInlinedArrayLit/genOutlinedArrayLit)
are updated to support derived types.
The core aspect of derived type constant lowering that differs between
the current lowering and the HLFIR update is the way
addresses/initial target descriptors are built when part of a derived
type constant. This part happens in ConvertVariable.cpp (since the
address of a variable is taken in an initializer and is left TODO).
The mangling of derived type global literal constant is fixed: it did not embed
the derived type name and could cause "conflicts" between unrelated
derived types containing the same data. However, the hash remains
unstable between two compilation of the same file. This is not a
correctness issue and would require a lot of work to hash the derived
type constant data without hashing some irrelevant (but not out of bound)
data in the compile time data structure that holds derived type
constants (Constant<SomeDerived>). This may have to be revisited later.
Differential Revision: https://reviews.llvm.org/D140986
Recent commits (2098ad7f00324ee0f2a6538f418a6f81dfdd2edb and
15a9a72ee68166c0cff3f036cacd3c82be66c729) replaced usage of "o.value()"
on optionals with "*o". Those optional values are expected to be
present -- but now, if it ever turns out that they're not,
compilation will proceed with garbage data rather than crashing
immediately (and more debuggably) with an uncaught exception.
Add asserts for presence to restore the previous level of safety.
(I could have revert these patches so as to resume used of .value()
but I didn't want to just have them get broken again.)
Differential Revision: https://reviews.llvm.org/D140340
The loops generated under IsContiguous check for copy-in/copy-out
result in LLVM backend spending too much time optimizing them.
At the same time, the copy loops do not provide any optimization
opportunities with the surrounding code (since they are executed
under runtime IsContiguous check), so the copy code may be optimized
on its own and this can be done in runtime.
I thought I could implement and use new APIs for packing/unpacking
non-contiguous data (interfaces added in D136378), but then I found
that Assign() is already doing what is needed. If performance
becomes an issue for these loops, we can optimize code in Assign()
rather than creating new APIs.
Thus, this change makes use of Assign() for copy-in/copy-out
of boxed objects, and this is done only if the objects
are non-contiguous during execution. Copies for non-boxed
objects (e.g. for passing as VALUE dummy argument) are still
done inline, because they can potentially be optimized with
surrounding loops.
I added internal -inline-copyinout-for-boxes option to revert to the old
behavior just to make it easier to triage performance regressions,
if any appear after the change.
CPU2017/521.wrf compiles for 2179 seconds without the change and
the module_dm.f90 compiled with -O0 (without -O0 this single
module compiles for 5775 seconds). With the change total compilation
time of the benchmark reduces to 722 seconds.
Differential Revision: https://reviews.llvm.org/D140446
std::optional::value() has undesired exception checking semantics and is
unavailable in older Xcode (see _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS). The
call sites block std::optional migration.
An unlimited polymorphic entity is considered to have a derived category
in its dynamic type but no type descriptor. Avoid a nullptr dereference when
an unlimited polymorphic type needs to be generated.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D139923
Doing a pointer assignment to another pointer which is a derived type component
could result in the bound information being lost, potentially leading to
incorrect array accesses. Fix this by trying to retain the bound info during
the assignment.
Fixes#57441
Differential Revision: https://reviews.llvm.org/D139800
In elemental procedure lowering the passed object is always emboxed. The current code
was not correctly dealing with scalar derived-type used as passed object.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D139667
When call an elemental subroutine with a monomorphic or polymorphic
passed object, the iteration shape could not be computed. Use the
passed object to infer the implicit iteration shape so the loop
can be constructed.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D139635
The passed object is placed in the passed arguments by semantics.
When the TBP to be called is an elemental subroutine or function it has to be
handled accordingly.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D139537
Support fir.class in genScalarUserDefinedAssignmentCall so
emboxing is done correctly.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D139435
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated. The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.
This is part of an effort to migrate from llvm::Optional to
std::optional:
https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
Move genCallOpAndResult from ConvertExpr.cpp into a new file so that
it can be shared with lowering to FIR and HLFIR during the transition.
After the transition, call lowering to HLFIR will be implemented in
this new file.
Differential Revision: https://reviews.llvm.org/D138643
Couple of operation are expecting BoxType but can totally handle
ClassType as well. This patch updates couple of locations to support
BaseBoxType instead of BoxType only.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D138422
This patch is the initial path to lower the SELECT TYPE construct to the
fir.select_type operation. More work is required in the AssocEntity
mapping but it will be done in a follow up patch to ease the review.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D137728
This patch forces pointer and allocatable polymorphic entities to be
tracked as descriptor. It also enables the pointer assignment between
polymorphic entities. Pointer association between a non-polymorphic
pointer and a polyrmophic target might require some more work as
per 10.2.2.3 point 1.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D137150
This patch moves intrinsic evaluate::Constant<T> lowering into its own
unit outside of ScalarExpr and genarr lowering so that it can
be used by the new lowering without any changes.
DerivedType lowering cannot be shared at that stage because it is too
correlated with the current lowering (requires structure constructor
and designator lowering).
The code had to be refactored quite a bit so that it could be carved
out, but the only "functional" change is that the length of character
arrays lowered by genarr is now `index` instead of `i64` (see test change).
One non-functional benefit of the change is that `toEvExpr` is not
needed anymore and some compile time copies of big constant arrays
that it was causing are removed (see old calls in previous genarr code),
although I am not sure any compile time speed-ups are visible here.
Differential Revision: https://reviews.llvm.org/D136955
Dynamic type of a polymorphic array element was retrieved by finding the
coordinate operation and use the base array. This patch remove this hack and use
the newly PolymorphicValue to carray the dynamic type together with the element.
The patch also rearrange some tests in the `allocatable-polymorphic.f90`.
Depends on D136824
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D136857
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