157 Commits

Author SHA1 Message Date
Leandro Lupori
bd94662697 [flang] Handle mismatches of procedure type args
Fortran allows type mismatch when passing actual arguments to
procedures and most cases were already being handled correctly by
Flang. However, conversion of data types to and from procedures and
conversion between procedures and char procedures were not always
handled properly. The missing cases were added and these
conversions are supported now.

Fixes #60550

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D145601
2023-03-14 09:52:05 -03:00
Valentin Clement
67318df027
[flang] Handle parent component in user function argument for special cases
In some cases the argument is already handled by a fir.rebox operation. Just
adapat the type to match the parent component in that case.

Depends on D145928

Differential Revision: https://reviews.llvm.org/D145931
2023-03-13 20:48:29 +01:00
Valentin Clement
33fbbf88af
[flang] Handle parent component in user function argument
When the argument is a parent component the box needs to
be updated to reflect the correct type. Use `updateBoxForParentComponent`
to update the argument accordingly.

Depends on D145907

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D145928
2023-03-13 20:30:41 +01:00
Valentin Clement
71e2d7106f
[flang] Handle parent component in intrinsic function arguments
When the argument is a parent component the box needs to
be updated to reflect the correct type. Use `updateBoxForParentComponent`
to update the argument accordingly.

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D145907
2023-03-13 15:28:09 +01:00
Valentin Clement
955eaaf1b5
[flang] Only check for embox/rebox if defining op is present
When the base box is a block argument, the defining op is null.
Only try to recover embox/rebox if there is a defining op.

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D145910
2023-03-13 15:25:56 +01:00
Valentin Clement
fa77f57956
[flang] Simpify parent component handling
This patch simplify the parent component handling when it's the last ref.

The first field is not necessary when the target box type is set correctly.

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D145795
2023-03-12 20:24:24 +01:00
Leandro Lupori
66ec326332 [flang] Fix lowering of optional char proc args
Optional character function arguments were not being lowered
properly. As they are passed as a tuple, containing the (boxed)
function address and the character length, it is not possible for
fir.absent to handle it directly. Instead, a tuple needs to be
created and filled with an absent function address and a dummy
character length.

Fixes #60225

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D144743
2023-03-06 11:33:43 -03:00
Valentin Clement
33a13f300b
[flang] Handle parent component in select type
In select type construct the associating entity in a TYPE IS
type guard statement is obtained with a fir.convert. Update the code
for the parent component to support fir.convert defining op
as well.

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D145367
2023-03-06 14:11:37 +01:00
Jean Perier
6ed4a8b9b1 [flang][hlfir] Lower intrinsic module procedures to HLFIR
Intrinsic module procedures are a bit different from intrinsic
procedures: they are defined in intrinsic module files, but their
signature and representation in semantics is the same as user
procedures.
The code to lower them in lowering (when they are not implemented in
Fortran) is the same as for intrinsic procedures
(Optimizer/Builder/IntrinsicCall.cpp).

The dispatching in in HLFIR procedure reference lowering must be
slightly modified so that these evaluate::ProcRef that have a
semantics::Symbol instead of an evaluate::SpecificIntrinsic can
be dispatched as evaluate::SpecificIntrinsic:
 - move isIntrinsicModuleProcedure to detect them
 - in the helpers dealing with intrinsics, make evaluate::SpecificIntrinsic
   a pointer argument that can be null for intrinsic module procedures.
 - add getProcedureName() to call context to avoid relying on the
   evaluate::SpecificIntrinsic when it is not know to be null.

Differential Revision: https://reviews.llvm.org/D145360
2023-03-06 14:00:39 +01:00
Valentin Clement
42f957f55d
[flang] Add TODO when trying to do a polymorphic temp in getTempExtAddr
Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D144459
2023-02-21 13:24:06 +01:00
Valentin Clement
e97fc5007e
[flang] Add TODO instead of crashing on assert
Current code are crashing on the assert `assert(seqTy && "must be an array");`.

Add a TODO instead until the support is in.

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D144173
2023-02-16 14:06:06 +01:00
Valentin Clement
7889f42496
[flang][NFC] Remove unwanted tab 2023-02-15 18:51:58 +01:00
Valentin Clement
d904ee3d47
[flang] Handle correctly optional intrinsic scalar to unlimited polymorphic optional
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
2023-02-13 15:44:12 +01:00
Valentin Clement
fe655717bf
[flang] Support polymorphic inputs for the TRANSPOSE intrinsic
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
2023-02-12 16:58:50 +01:00
Jean Perier
cfc4860021 [flang][NFC] Move Procedure designator lowering in its own file
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
2023-02-08 12:47:11 +01:00
Valentin Clement
39e6bd9cac
[flang] Add a proper TODO for polymorphic array lowering with vector subscript
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
2023-02-08 10:30:39 +01:00
Jean Perier
ab9c4e9fff [flang][NFC] addSymbol/lookupSymbol clean-up
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
2023-02-07 09:23:09 +01:00
Tom Eccles
6dcb31de1f [flang][NFC] Move IntrinsicCall to Optimizer/Builder/ 6/6
This will allow IntrinsicCall to be used in passes to implement hlfir
transformational intrinsic operations.

Differential Revision: https://reviews.llvm.org/D143084
2023-02-06 10:33:20 +00:00
Valentin Clement
62aa19a5a5
[flang] Keep a fir.box type when doing an array of derived type component
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
2023-01-24 19:45:33 +01:00
Valentin Clement
f55bfde5f1
[flang] Handle passing NULL() to polymorphic pointer argument
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
2023-01-24 14:45:37 +01:00
Valentin Clement
2e28546ba3
[flang] Keep polymorphic aspect when lowering intrinsic arguments
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
2023-01-23 20:25:27 +01:00
Valentin Clement
959caaaa7b
[flang] Add conditional rebox when passing fir.box to optional fir.class
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
2023-01-23 15:42:04 +01:00
Valentin Clement
262dad4a81
[flang] Deal with NULL() passed as actual arg to unlimited polymorphic dummy
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
2023-01-23 09:49:59 +01:00
Valentin Clement
9f1bb307da
[flang] Carry the whole polymorphic box in PolymorphicValue
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
2023-01-12 18:00:16 +01:00
Peixin Qiao
40d9e93cca [flang] Support lowering of IS_CONTIGUOUS
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
2023-01-11 22:35:13 +08:00
Valentin Clement
b71bbbb64f
[flang] Only deallocate intent(out) allocatable through runtime if allocated
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
2023-01-11 09:27:20 +01:00
Kazu Hirata
c09215860f [flang] Use std::optional instead of llvm::Optional (NFC)
This patch replaces (llvm::|)Optional< with std::optional<.  I'll post
a separate patch to remove #include "llvm/ADT/Optional.h".

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
2023-01-07 22:26:48 -08:00
Kazu Hirata
4d4d4785e0 [flang] Add #include <optional> (NFC)
This patch adds #include <optional> to those files containing
llvm::Optional<...> or Optional<...>.

I'll post a separate patch to actually replace llvm::Optional with
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
2023-01-07 20:55:47 -08:00
Jean Perier
2d9b4a50ca [flang][NFC] share Constant<SomeDerived> lowering
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
2023-01-05 14:45:34 +01:00
Peter Klausler
a8234196c5 [flang] Restore checking for some optional values before use
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
2022-12-29 09:37:34 -08:00
Slava Zakharin
2b60ed405b [flang] Use Assign() runtime for copy-in/copy-out.
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
2022-12-21 09:55:33 -08:00
Fangrui Song
15a9a72ee6 [flang] llvm::Optional::value() => => operator*/operator->
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.
2022-12-17 22:22:47 +00:00
Jean Perier
b22fa8659a [flang][NFC] add builder to simplify fir.shape creation
Differential Revision: https://reviews.llvm.org/D140031
2022-12-15 11:14:14 +01:00
Valentin Clement
7602e09b1c
[flang] Handle type generation for unlimited polymorphic function result
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
2022-12-13 15:00:08 +01:00
Jonathon Penix
1ee9080d6b [flang] Preserve bound info for pointer assignments through derived types
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
2022-12-12 14:22:22 -08:00
Valentin Clement
1b41074508
[flang] Embox derived-type when passed to element procedure as passed object
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
2022-12-09 15:37:56 +01:00
Valentin Clement
ee7a62a306
[flang] Generate iteration shape from passed object
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
2022-12-09 09:18:37 +01:00
Valentin Clement
f1307d78c6
[flang] Handle polymorphic passed object in elemental call
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
2022-12-08 09:48:17 +01:00
Jean Perier
1293b5fe5a [flang] turn fatal error into a TODO for FORALL edge-case
See https://github.com/llvm/llvm-project/issues/59337.
This TODO will be implemented as part of HLFIR work
(see https://github.com/llvm/llvm-project/blob/main/flang/docs/HighLevelFIR.md).

Differential Revision: https://reviews.llvm.org/D139410
2022-12-07 09:47:33 +01:00
Valentin Clement
13cde1129e
[flang] Support fir.class in scalar user defined assignment lowering
Support fir.class in genScalarUserDefinedAssignmentCall so
emboxing is done correctly.

Reviewed By: jeanPerier, PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D139435
2022-12-06 22:02:25 +01:00
Kazu Hirata
9a41739565 [flang] Use std::nullopt instead of None (NFC)
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
2022-12-03 12:14:21 -08:00
Valentin Clement
b9e53b96e0
[flang] Handle polymorphic value when creating temporary
Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D138921
2022-11-30 09:58:57 +01:00
Jean Perier
011b2af0f4 [flang][NFC] move genCallOpAndResult into new ConvertCall.cpp file
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
2022-11-24 12:38:53 +01:00
Valentin Clement
3b257a6373
[flang] Accept BaseBoxType in couple of fir.array_* operations
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
2022-11-21 16:54:47 +01:00
Valentin Clement
f677c5ee97
[flang] Initial lowering of SELECT TYPE construct to fir.select_type operation
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
2022-11-14 10:48:41 +01:00
Valentin Clement
880b37f175
[flang] Handle pointer assignment with polymorphic entities
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
2022-11-01 21:46:32 +01:00
Jean Perier
af91b19338 [flang][NFC] move constant lowering into its own unit
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
2022-10-31 15:37:38 +01:00
Valentin Clement
21b825738b
[flang] Carry polymoprhic dynamic type when using coordinate_of polymoprhic array
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
2022-10-28 08:31:35 +02:00
Valentin Clement
ea1e767a06
[flang] Carry dynamic type when emboxing polymorphic pointer
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
2022-10-27 20:57:09 +02:00
Peixin-Qiao
5312198654 [flang] Support lowering of parent component in strecture constructor
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
2022-10-26 09:12:45 +08:00