77 Commits

Author SHA1 Message Date
jeanPerier
c373f58134
[flang] Lower procedure pointer components (#75453)
Lower procedure pointer components, except in the context of structure
constructor (left TODO).

Procedure pointer components lowering share most of the lowering logic
of procedure poionters with the following particularities:
- They are components, so an hlfir.designate must be generated to
retrieve the procedure pointer address from its derived type base.
- They may have a PASS argument. While there is no dispatching as with
type bound procedure, special care must be taken to retrieve the derived
type component base in this case since semantics placed it in the
argument list and not in the evaluate::ProcedureDesignator.

These components also bring a new level of recursive MLIR types since a
fir.type may now contain a component with an MLIR function type where
one of the argument is the fir.type itself. This required moving the
"derived type in construction" stackto the converter so that the object
and function type lowering utilities share the same state (currently the
function type utilty would end-up creating a new stack when lowering its
arguments, leading to infinite loops). The BoxedProcedurePass also
needed an update to deal with this recursive aspect.
2023-12-19 17:17:09 +01:00
Valentin Clement (バレンタイン クレメン)
67f9b5ae7d
[flang] Fix issue with lookup in the binding table (#74416)
This patch is fixing two issue relative to the dynamic dispatch for
polymorphic entities.

1. Fix the `requireDispatchCall` function. It was checking for the first
symbol of the component but this is not the one to be checked. Instead
the last symbol of the base of the component object is the one to check
to know if it is polymorphic object with a dispatch call or not. This is
demonstrated in the new added test in `flang/test/Lower/dispatch.f90`
where the first symbol would point to `q` which is monomorphic and would
result in a simple `fir.call`
2. Fix the pass object in a no pass situation. In a no pass situation
the pass object is lowered anyway to be able to do the lookup in the
binding table. It was previously lowered wrongly an lead to unresolved
lookup. The base of the component is the passed object and should be
lowered. To achieve this, the `gen(DataRef)` entry point is exposed form
`ConvertExprToHLFIR` through a `convertDataRefToValue` function. The
same test added in `flang/test/Lower/dispatch.f90` is checking for the
correct passed object.

In addition couple of tests were updated to HLFIR since the lowering
used only works with it.
2023-12-05 08:59:40 -08:00
Daniel Chen
af09219edd [Flang] Add partial support for lowering procedure pointer assignment. (#70461)
**Scope of the PR:**
1. Lowering global and local procedure pointer declaration statement
with explicit or implicit interface. The explicit interface can be from
an interface block, a module procedure or an internal procedure.
2. Lowering procedure pointer assignment, where the target procedure
could be external, module or internal procedures.
3. Lowering reference to procedure pointers so that it works end to end.

**PR notes:**
1. The first commit of the PR does not include testing. I would like to
collect some comments first, which may alter the output. Once I confirm
the implementation, I will add some testing as a follow up commit to
this PR.
2. No special handling of the host-associated entities when an internal
procedure is the target of a procedure pointer assignment in this PR.

**Implementation notes:**
1. The implementation is using the HLFIR path.
2. Flang currently uses `getUntypedBoxProcType` to get the
`fir::BoxProcType` for `ProcedureDesignator` when getting the address of
a procedure in order to pass it as an actual argument. This PR inherits
the same design decision for procedure pointer as the `fir::StoreOp`
requires the same memory type.

Note: this commit is actually resubmitting the original commit from
PR #70461 that was reverted. See PR #73221.
2023-11-23 13:43:35 +01:00
Muhammad Omair Javaid
49f55d1075 Revert "[Flang] Add partial support for lowering procedure pointer assignment. (#70461)"
This reverts commit e07fec10ac208c2868a24c5c0be88e45778b297e.

This change appears to have broken following buildbots:
https://lab.llvm.org/buildbot/#/builders/176
https://lab.llvm.org/buildbot/#/builders/179
https://lab.llvm.org/buildbot/#/builders/184
https://lab.llvm.org/buildbot/#/builders/197
https://lab.llvm.org/buildbot/#/builders/198

All bots fails in testsuite where following tests seems broken:
(eg: https://lab.llvm.org/buildbot/#/builders/176/builds/7131)

test-suite::gfortran-regression-compile-regression__proc_ptr_46_f90.test
test-suite::gfortran-regression-compile-regression__proc_ptr_37_f90.test
2023-11-23 12:30:40 +05:00
Daniel Chen
e07fec10ac
[Flang] Add partial support for lowering procedure pointer assignment. (#70461)
**Scope of the PR:**
1. Lowering global and local procedure pointer declaration statement
with explicit or implicit interface. The explicit interface can be from
an interface block, a module procedure or an internal procedure.
2. Lowering procedure pointer assignment, where the target procedure
could be external, module or internal procedures.
3. Lowering reference to procedure pointers so that it works end to end.

**PR notes:**
1. The first commit of the PR does not include testing. I would like to
collect some comments first, which may alter the output. Once I confirm
the implementation, I will add some testing as a follow up commit to
this PR.
2. No special handling of the host-associated entities when an internal
procedure is the target of a procedure pointer assignment in this PR.

**Implementation notes:**
1. The implementation is using the HLFIR path.
2. Flang currently uses `getUntypedBoxProcType` to get the
`fir::BoxProcType` for `ProcedureDesignator` when getting the address of
a procedure in order to pass it as an actual argument. This PR inherits
the same design decision for procedure pointer as the `fir::StoreOp`
requires the same memory type.
2023-11-22 11:51:12 -05:00
jeanPerier
7046202c3d
[flang] Move whole allocatable assignment implicit conversion to lowering (#70317)
The front-end is making implicit conversions explicit in assignment and
structure constructors.

While this generally helps and is needed by semantics to fold structure
constructors correctly, this is incorrect when the LHS or component is
an allocatable. The RHS may have non default lower bounds that should be
propagated to the LHS, and making the conversion explicit changes the
semantics. In the structure constructor, the situation is even worse
since Fortran 2018 7.5.10 point 7 allows the value to be a reference to
an unallocated allocatable, and adding an explicit conversion in
semantics will cause a segfault.

This patch removes the explicit convert in semantics when the
LHS/component is a whole allocatable, and update lowering to deal with
the conversion insertion, dealing with preserving the lower bounds and
the tricky structure constructor case.
2023-10-27 09:07:48 +02:00
jeanPerier
b6b0756ce5
[flang] Allow lowering of sub-expressions to be overridden (#69944)
OpenACC/OpenMP atomic lowering needs a finer control over expression
lowering. This patch allows mapping evaluate::Expr<T> to mlir::Value so
that any subsequent expression lowering will use these values when an
operand is a mapped Expr<T>.

This is an alternative to
https://github.com/llvm/llvm-project/pull/69866 From which I took the
test and some of the logic to extract the non-atomic sub-expression.

---------

Co-authored-by: Nimish Mishra <neelam.nimish@gmail.com>
2023-10-25 09:22:23 +02:00
jeanPerier
e45f6e93d0
[flang][hlfir] Make the parent type the first component (#69348)
Type extension is currently handled in FIR by inlining the parents
components as the first member of the record type.

This is not correct from a memory layout point of view since the storage
size of the parent type may be bigger than the sum of the size of its
component (due to alignment requirement). To avoid making FIR types
target dependent and fix this issue, make the parent component a single
component with the parent type at the beginning of the record type.

This also simplifies addressing since parent component is now a "normal"
component that can be designated with hlfir.designate.

StructureComponent lowering however is a bit more complex since the
symbols in the structure component may refer to subcomponents of parent
types.

Notes:
1. The fix is only done in HLFIR for now, a similar fix should be done
in ConvertExpr.cpp to fix the path without HLFIR (I will likely still do
it in a new patch since it would be an annoying bug to investigate for
people testing flang without HLFIR).
2. The private component extra mangling is useless after this patch. I
will remove it after 1.
3. The "parent component" TODO in constant CTOR is free to implement for
HLFIR after this patch, but I would rather remove it and test it in a
different patch.
2023-10-20 11:30:59 +02:00
Pete Steinfeld
5db4779c3f
[flang] Regularize TODO messages for coarray related features (#69227)
I want to make "not yet implemented" messages for features related to
coarrays easy to identify and make them easy for users to read.
2023-10-16 12:37:57 -07:00
Anthony Cabrera
561fbe441e
[flang][hlfir] address char_convert issues as mentioned in #64315 (#67570)
As shown in #64315, there were issues when trying to lower two flavors
of Fortran code that implicitly perform `CHARACTER` conversion.
This PR addresses those issues.
2023-10-09 16:27:09 -05:00
jeanPerier
99a54b839a
[flang] Lower PRIVATE component names safely (#66076)
It is possible for a derived type extending a type with private
components to define components with the same name as the private
components.

This was not properly handled by lowering where several fir.record type
component names could end-up being the same, leading to bad generated
code (only the first component was accessed via fir.field_index, leading
to bad generated code).

This patch handles the situation by adding the derived type mangled name
to private component.
2023-09-18 14:59:56 +02:00
Slava Zakharin
f8843efbb2
[flang][hlfir] Lower Cray pointee references. (#65563)
A Cray pointee reference must be done using the characteristics
(bounds, type params) of the original pointee declaration, but
using the actual address value of the associated Cray pointer.
There might be multiple Cray pointees associated with the same
Cray pointer.

The proposed solution is to lower each Cray pointee into a POINTER
variable with a descriptor. The descriptor is initialized at the point
of declaration of the pointee, though its base_addr is set to null.
Before each reference of the Cray pointee its descriptor's base_addr
is updated to the current value of the Cray pointer.

The update of the base_addr is done using PointerAssociateScalar
runtime call, which just updates the base_addr of the descriptor.
This is a temporary solution just to make Cray pointers work
to the same extent they work with FIR lowering.
2023-09-07 11:41:22 -07:00
Peter Klausler
031b4e5e79
[flang] Support SELECT RANK on allocatables & pointers
Unlike other executable constructs with associating selectors, the
selector of a SELECT RANK construct can have the ALLOCATABLE or POINTER
attribute, and will work as an allocatable or object pointer within
each rank case, so long as there is no RANK(*) case.

Getting this right exposed a correctness risk with the popular
predicate IsAllocatableOrPointer() -- it will be true for procedure
pointers as well as object pointers, and in many contexts, a procedure
pointer should not be acceptable.  So this patch adds the new predicate
IsAllocatableOrObjectPointer(), and updates some call sites of the original
function to use the new one.

Differential Revision: https://reviews.llvm.org/D159043
2023-08-29 14:56:15 -07:00
Slava Zakharin
9184eb84a1 [flang][hlfir] Fixed nullptr dereference.
In case of unlimited polymorphic type, there is no derived type
spec, so use NoneType explicitly.

Reviewed By: tblah

Differential Revision: https://reviews.llvm.org/D157751
2023-08-14 08:56:04 -07:00
Slava Zakharin
5a4c5c864f [flang][hlfir] Support parenthesized polymorphic arrays.
The parenthesis' operand is used as a mold for the generated
hlfir.elemental.

Depends on D157316

Reviewed By: tblah, clementval

Differential Revision: https://reviews.llvm.org/D157318
2023-08-08 09:58:48 -07:00
cabreraam
a033bf242f [flang][hlfir] work towards handling char_convert in hlfir
This patch aims to address the TODO for handling character conversion in HLFIR found [here](1defa78124/flang/lib/Lower/ConvertExprToHLFIR.cpp (L1388)) using [this similar operation but for FIR as inspiration](3ea673a97b/flang/lib/Lower/ConvertExpr.cpp (L1212-L1271)).

Reviewed By: vzakhari, tblah

Differential Revision: https://reviews.llvm.org/D155650
2023-07-31 10:45:10 -04:00
Slava Zakharin
1fa4a0a012 [flang][hlfir] Fixed character allocatable in structure constructor.
The problem appeared as a segfault for case like this:
```
type t
character(11), allocatable :: c
end type
character(12), alloctable :: x
type(t) y
y = t(x)
```

The frontend representes `y = t(x)` as `y=t(c=%SET_LENGTH(x,11_8))`.
When 'x' is unallocated the hlfir.set_length lowering results in
segfault. It could probably be handled in hlfir.set_length lowering
by using NULL base for the hlfir.declare depending on the allocation
status of 'x', but I am not sure if !hlfir.expr, in general, is supposed
to represent an expression created from unallocated allocatable.
I believe in Fortran that would mean referencing an unallocated
allocatable, which is not allowed.

I decided to special case `SET_LENGTH` in structure constructor,
so that we use its 'x' operand as the RHS for the assign operation
implying the isAllocatable check for cases when 'x' is allocatable.
This requires setting keep_lhs_length_if_realloc flag for the assign
operation. Note that when the component being intialized has
deferred length the frontend does not produce `SET_LENGTH`.

Differential Revision: https://reviews.llvm.org/D155151
2023-07-13 09:44:39 -07:00
Slava Zakharin
fba06f7a7c [flang][hlfir] Moved TODO for polymorphic vector subscripted expressions.
If I understand it correctly, the TODO is intended to catch cases
when we may need to create a temporary array for polymorphic entities
resulting from a vector subscription, i.e. when the final expression
type of hlfir.elemental_addr is polymorphic. The TODO check was done
very early, so it kicked in for cases where the it should not have.
For example,
```
type t
  integer n
end type
class(t), pointer :: p(:)
... p(vector_of_indices)%n
```

Such designators are supported by FIR lowering and can be currently
supported by HLFIR, but the TODO prevented this. I just moved the TODO
check later in the lowering pipeline.

I also updated the comment trying to describe my understanding of how
the correct mold entity can be computed for the elemental operation
producing HLFIR expression of polymorphic type.

This change provides 34 new passes in my nag testing.

Reviewed By: tblah

Differential Revision: https://reviews.llvm.org/D154814
2023-07-12 13:52:38 -07:00
Slava Zakharin
07593a39a4 [flang][hlfir] Fixed NULL() handling in structure constructor.
When an initializer value is missing for an allocatable component
in a structure constructor, the RHS is NULL() expression.
We should just skip this part of the initializer, since the component
must become unallocated (as it is from the initialization).
Runtime detected rank mismatch when we tried to pass NULL() box
RHS for assigning it to the unallocated component of rank 1, 2, etc.

Reviewed By: tblah

Differential Revision: https://reviews.llvm.org/D154906
2023-07-11 09:40:08 -07:00
Jean Perier
2d46264ca6 [flang] add nested DEC STRUCTURE in DerivedTypeDetails component names
Currently, when a (legacy) DEC structure contained other DEC structure
declarations, the related component names were not added to the
containing DerivedTypeDetails component_names. This lead to bugs in
later phase when visiting the components (like in when lowering the
type to FIR/MLIR).

When an EntityDecl is visited and the scope is a DEC structure, add
the entity to the component names of this DEC structure.

Differential Revision: https://reviews.llvm.org/D154216
2023-06-30 20:25:04 +02:00
Slava Zakharin
7b4aa95d7c [flang][hlfir] Set/propagate 'unordered' attribute for elementals.
This patch adds 'unordered' attribute handling the HLFIR elementals'
builders and fixes the attribute handling in lowering and transformations.

Depends on D154031, D154032

Reviewed By: jeanPerier, tblah

Differential Revision: https://reviews.llvm.org/D154035
2023-06-29 11:16:38 -07:00
Slava Zakharin
3a4e9f7ae5 [flang][hlfir] Do not dereference unallocated entities in structure constructor.
Component-by-component assignment must be able to handle unallocated
allocatable values in structure constructor. F2018 7.5.10 p. 7 states
that the component must have unallocated status as a result of such
construction. The structure constructor temporary is initialized
such that all the allocatable components are unallocated, so we just
need to make sure not to do the component assignment if RHS is deallocated.

Depends on D152482  (the same LIT test is affected)

Reviewed By: jeanPerier, tblah

Differential Revision: https://reviews.llvm.org/D152493
2023-06-27 14:08:35 -07:00
Slava Zakharin
ebd0b8a047 [flang][hlfir] Special handling for temporary LHS in AssignOp.
When `AssignOp` is used with LHS that is a compiler generated temporary
special care must be taken to initialize the temporary and avoid
finalizations of its components. This change-set adds optional
`temporary_lhs` attribute for `AssignOp` to convey this information
to HLFIR-to-FIR conversion pass. Currently, this results in
calling `AssignTemporary` runtime for doing the assignment.

Reviewed By: jeanPerier, tblah

Differential Revision: https://reviews.llvm.org/D152482
2023-06-26 18:28:10 -07:00
Slava Zakharin
1ca458f78e [flang][hlfir] Lower structure constructor via AssignOp.
I tried this patch, first. Some tests failed because of the extra
finalizations for the temporary LHSs: when LHS component is a derived
type with final subprograms, the finalizations might be detected
by counting/printing in the final subprograms and treated as errors
in the tests, because they are not expected.
So I also tried to reuse the StructureConstructor code lowering to FIR
followed by AsExprOp to produce the HLFIR "value". Unfortunately,
this did not resolve the finalization issues, because AsExprOp may
end up being bufferized into AssignOp as well.
So the extra finalizations are inherent problem for AssignOp,
and it has to be resolved separately. Thus, I decided to proceed
with a "cleaner" direct lowering to HLFIR (the initial patch).

I am thinking about adding an extra flag for AssignOp that would
indicate that the LHS is a compiler generated temporary, so we could
use something like AssignTemporary() in HLFIR-to-FIR converter.

Reviewed By: tblah

Differential Revision: https://reviews.llvm.org/D151752
2023-05-31 11:30:55 -07:00
Slava Zakharin
ca2ec4b720 [flang][hlfir][NFC] Make BOZ lowering a TODO.
This change just turns the unhandled BOZ fatal error into TODO
like in non-HLFIR path.
2023-05-24 16:34:56 -07:00
Slava Zakharin
f809bf2b32 [flang][hlfir] Use complete form of DesignateOp for im/re array designators.
With this change, the lowering provides full slice triples for
designators like ...%array_comp%im/re, so that the codegen
does not have to figure it out for the array_comp.
Basically, ...%array_comp%im/re is lowered the same way
as ...%array_comp(:,:,...)%im/re.

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D150842
2023-05-19 09:02:03 -07:00
Slava Zakharin
280a3e44a3 [flang][hlfir] Added a TODO note for parameterized array component shapes.
Without the TODO, MLIR verifier fails because of invalid hlfir.declare
or fir.alloca that lowering produces.

Reviewed By: clementval

Differential Revision: https://reviews.llvm.org/D150911
2023-05-19 08:21:07 -07:00
Kiran Chandramohan
c3a0df1903 [Flang] Change complex divide lowering
Currently complex division is lowered to a fir.divc operation and the
fir.divc is later converted to a sequence of llvm operations to perform
complex division, however this causes issues for extreme values when
the calculations overflow.

This patch changes the lowering of complex division to use the Intrinsic
Call functionality to lower into library calls (for single, double,
extended and quad precisions) or an MLIR complex dialect division operation
(for half and bfloat precisions).

 A new wrapper function `genLibSplitComplexArgsCall` is written to handle
 the case of the arguments of the Complex Library calls being split to
its real and imaginary real components.

Note 1: If the Complex To Standard conversion of division operation
matures then we can use it for all precisions. Currently it has the
same issues as the conversion of fir.divc.
Note 2: A previous patch (D145808) did the same but during conversion of
the fir.divc operation. But using function calls at that stage leads to
ABI issues since the conversion to LLVM is not aware of the complex target
rewrite.
Note 3: If the patch is accepted, fir.divc can be removed from FIR. We
can use the complex.div operation where any transformation is required.

Reviewed By: vzakhari, PeteSteinfeld, DavidTruby, jeanPerier

Differential Revision: https://reviews.llvm.org/D149546
2023-05-11 11:52:35 +00:00
Slava Zakharin
9a7b363eeb [flang] Added missing type cast for the implied-do index.
The implied-do index value has 'index' type, and it has to be
converted to the original ac-do-variable's data type.

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D150150
2023-05-09 13:26:32 -07:00
Jean Perier
c7ff45a529 [flang][hlfir] Lower left-hand side vector subscripts to HLFIR
This patch lowers assignments to vector subscripted designators into the
newly added hlfir.elemental_addr and hlfir.region_assign.

Note that the codegen of these operation to FIR is still TODO and will
still emit a TODO message when trying to compile programs end to end.

Differential Revision: https://reviews.llvm.org/D149962
2023-05-09 09:22:37 +02:00
Jean Perier
2a9126d40d [flang][hlfir] Add TODO for polymorphic vector subscripted entities
I removed the barriers a bit fast. Some mold is needed on
hlfir.elemental for polymorphic vector subscripted designator (and for
parenthesized polymorphic) so that a temporary can be later created.

The parenthesized array case may also just used asExpr and that
could later use AssignTemporary to deal with this. But the vector
subscripted designator case will need to use some new runtime
to get some mold allocation done for the temp.

Add TODOs in the meantime.

Differential Revision: https://reviews.llvm.org/D149970
2023-05-07 16:25:50 +02:00
Jean Perier
583d492c63 [flang][hlfir] Lower vector subscripted RHS designators
Lower vector subscripted designators as values when they appear outside
of the assignment left-hand side and input IO contexts.

This matches Fortran semantics where vector subscripted designators cannot
be written to outside of the two contexts mentioned above: they are
passed/taken by value where they appear.

This patch uses the added hlfir.element_addr to lower vector designators
in lowering. But when reaching the end of the designator lowering, the
hlfir.element_addr is turned into an hlfir.elemental when lowering is
not asking for the hlfir.elemental_addr.

This approach allows lowering vector subscripted in the same way in
while visiting the designator, and only adapt to the context at the
edge.

The part where lowering uses the hlfir.elemental_addr will be
done in further patch as it requires lowering assignments in the
new hlfir.region_assign op, and there is not codegen yet for these
new operations.

Differential Revision: https://reviews.llvm.org/D149480
2023-05-03 09:22:25 +02:00
Ethan Luis McDonough
ba45f63782
[flang] Lower complex part
Implements HLFIR lowering for %im and %re.

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D145005
2023-03-07 11:40:27 -06:00
Jean Perier
88be49599f [flang][hlfir] Lower parent component references
Skip the parent components when they are not at the end of
designators.
Generate an hlfir.parent_comp for parent component at the end
of designators.

Differential Revision: https://reviews.llvm.org/D144948
2023-02-28 14:10:52 +01:00
Jean Perier
ffde9f1730 [flang][hlfir] Array constructor lowering [part 1/4]
This is the first and biggest chunk that introduces support for
array constructor to HLFIR.

This patch:
- adds a new ConvertArrayConstructor.cpp that centralizes the
  code dealing with array constructor lowering.
- introduces a framework to lower array constructor according to
  different strategies: A common analysis of the array constructor is
  done, and based on that, a lowering startegy is selected and driven
  through the ac-values of the array constructor. See
  ConvertArrayConstructor.cpp comments for more details.
- implements the first strategy that creates a temporary inlined and
  updates it with inlined code. This strategy can only be used if the
  temporary can be pre-allocated (i.e: the extents and length parameters
  can be pre-computed without evaluating any ac-values), and if all the
  ac-value expressions are scalars.

For the sake of simplicity, characters and derived type will be enabled
once all the strategies are added.

Reviewed By: clementval, PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D144102
2023-02-16 15:18:55 +01:00
Jean Perier
cedfd2721e [flang][hlfir] Lower procedure designators to HLFIR
- Add a convertProcedureDesignatorToHLFIR that converts the
  fir::ExtendedValue from the current lowering to a
  fir.boxproc/tuple<fir.boxproc, len> mlir::Value.

- Allow fir.boxproc/tuple<fir.boxproc, len> as hlfir::Entity values
  (a function is an address, but from a Fortran entity point of view,
  procedure that are not procedure pointers cannot be assigned to, so
  it makes a lot more sense to consider those as values).

- Modify symbol association to not generate an hlfir.declare for dummy
  procedures. They are not needed and allowing hlfir.declare to declare
  function values would make its verifier and handling overly complex
  for little benefits (maybe an hlfir.declare_proc could be added if it
  turnout out useful later for debug info and attributes storing
  purposes).

- Allow translation from hlfir::Entity to fir::ExtendedValue.
  convertToBox return type had to be relaxed because some intrinsics
  handles both object and procedure arguments and need to lower their
  object arguments "asBox". fir::BoxValue is not intended to carry
  dummy procedures (all its member functions would make little sense
  and its verifier does not accept such type).
  Note that AsAddr, AsValue and AsBox will always return the same MLIR
  value for procedure designators because they are always handled the
  same way in FIR.

Differential Revision: https://reviews.llvm.org/D143585
2023-02-09 09:02:52 +01:00
Tom Eccles
61c5c59720 [flang][NFC] add convertToX functions to HLFIRTools
These will be useful for sharing code with intrinsic argument processing
when lowering hlfir transformational intrinsic operations to FIR in
the BufferizeHLFIR pass.

Differential Revision: https://reviews.llvm.org/D143503
2023-02-08 10:01:08 +00:00
Jean Perier
92e5234f69 [flang][hlfir] Lower evaluate::DescriptorInquiry
Lower extents and lower bounds inquiries with a compile time
constant DIM that cannot be folded by the front-end.

Differential Revision: https://reviews.llvm.org/D143476
2023-02-07 15:28:24 +01:00
Jean Perier
ff2912a049 [flang][hlfir] place scalar in memory in convertToBox/convertToAddress
Implement the TODO. Be careful to use and propagate the expression
type to create the temporary since the mlir value may have been computed
with a different value type (e.g., i1 for logical) that should not be
used for in memory values that must have Fortran types.

Co-authored-by: Tom Eccles <tom.eccles@arm.com>

Differential Revision: https://reviews.llvm.org/D143421
2023-02-07 09:26:01 +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
Jean Perier
87cd6f9346 [flang][hlfir] Lower post f77 user calls
In lowering to HLFIR, deal with user calls involving a mix of:
 - dummy with VALUE
 - Polymorphism
 - contiguous dummy
 - assumed shape dummy
 - OPTIONAL arguments
 - NULL() passed to OPTIONAL arguments.
 - elemental calls

Does not deal with assumed ranked dummy arguments.

This patch unifies the preparation of all arguments that must be passed
in memory and are not passed as allocatable/pointers.

For optionals, the same argument preparation is done, except the utility
that generates the IR for the argument preparation is called inside a
fir.if.

The addressing of array arguments in elemental calls is delayed so that
it can also happen during this argument preparation, and be placed in
the fir.if when the array may be absent.

Structure helpers are added to convey a prepared dummy argument and the
data that may be needed to do the clean-up after the call (temporary
storage deallocation or copy-out). And a utility is added to wrap
the preparation code inside a fir.if and convey these values through
the fir.if.

Certain aspects of this patch brings the HLFIR lowering support beyond
what the current lowering to FIR supports (e.g. handling of NULL(), handling
of optional in elemental calls, handling of copy-in/copy-out involving
polymorphic entities).

Differential Revision: https://reviews.llvm.org/D142695
2023-02-01 11:43:29 +01:00
Jean Perier
7531c87183 [flang][hlfir] Enable allocate, deallocate, pointer assignment lowering
The previous patches allowed lowering allocatable/and pointer designator
expressions with HLFIR.
This patch updates the bridge genExprMutableBox to use HLFIR lowering
when HLFIR flag is set. For allocate and deallocate lowering that use
genExprMutableBox, no other change is needed.

For pointer assignments, the code doing the pointer assignments in the
bridge can be reused and is simply moved so that it can be shared, and
the "explicit context" special cases of the previous lowering are
by-passed.

The code doing pointer assignment revealed that convertExprToAddress
did not match the previous genExprAddr behavior (that actually
does not create temps for "x" where x is not contiguous).
Instead of trying to copy the old behavior that is a bit weird (was
dictated by the implementation rather than design). Update
convertExprToAddress to do something sensible and that works with
the current genExprAddr usages (if anything, it should saves bogus
array section temps).

Differential Revision: https://reviews.llvm.org/D142197
2023-01-20 14:06:30 +01:00
Jean Perier
b3bb4dd348 [flang][hlfir] Lower pointer and allocatable sub-part references
The previous patches dealt with allocatable and pointer symbol
and component whole references.
This one deals with the remaining sub-part case where a dereference
must be created before applying the sub-part reference on the target.

With this patch the support to designate allocatable and pointer in
HLFIR is complete, but some use points will need to be updated to
use HLFIR designator lowering (at least allocate/deallocate statement
and whole allocatable assignment).

The partInfo.base had to be turned into an std::optional<hlfir::Entity>
because loads of allocatable/pointers do create a
fir::FortranVariableOpInterface (there is no need to). The optional part
comes from the fact that the partInfo.base is not set when creating the
partInfo, but later when visiting the designator parts.

They are three cases when dereferences must be inserted:
- The pointer/allocatable is a symbol followed by a sub-part that is not
a component ref. This is done in visit(Symbol).
- The pointer/allocatable is a component followed by a sub-part that is
not another component ref. This is done in visit(Component).
- The pointer/allocatable is followed by a component ref. This case is
special since it does not call the above "visit" but instead calls "gen"
to break the visit and generate an hlfir.designate for the component
base (since one hlfir.designate can only represent one Fortran part-ref,
and must be chained to implement a Fortran designator with several part
refs). This is done in visitComponentImpl().

Differential Revision: https://reviews.llvm.org/D142124
2023-01-20 11:31:11 +01:00
Jean Perier
3508f69174 [flang][hlfir] Lower whole allocatable or pointer component ref
Compare to other component ref lowering, the hlfir.designate result type
computation is different, and the allocatable/pointer/contiguous must
be set on the hlfir.designate so that the component attributes are
kept in the IR.

Differential Revision: https://reviews.llvm.org/D142111
2023-01-19 16:57:21 +01:00
Jean Perier
c0b45fef15 [flang] Lower elemental and transformational clean-up in HLFIR
In lowering to hlfir, no clean-up was added yet for
the created hlfir.elemental. Add  the needed hlfir.destroy.

Regarding transformational lowering, clean-ups were created because
they are lowered in memory, but this is inconvenient because this
prevented lowering to hlfir from "moving" the created variable to
an expression. Add a new entry point in IntrinsicCall.h that keeps
track of whether or not the returned storage needs to be deallocated,
but does not insert the deallocation in the StatementContext.
This allows using the newly added hlfir.as_expr "move" aspect to be
used and save creating a copy.

Depends on D141839

Reviewed By: clementval

Differential Revision: https://reviews.llvm.org/D141841
2023-01-17 11:44:23 +01:00
Jean Perier
199e49746d [flang] Lower elemental intrinsics to hlfir.elemental
- Move the core code generating hlfir.elemental for user calls from
  genUserElementalCall into a new ElementalCallBuilder class and use
  C++ CRTP (curiously recursive template pattern) to implement the
  parts specific to user and intrinsic call into ElementalUserCallBuilder
  and ElementalIntrinsicCallBuilder. This allows sharing the core logic
  to lower elemental procedures for both user defined and intrinsics
  procedures.

- To allow using ElementalCallBuilder, split the intrinsic lowering code
  into two parts: first lower the arguments to hlfir::Entity regardless
  of the interface of the intrinsics, and then, in a different function
  (genIntrinsicProcRefCore), prepare the hlfir::Entity according to the
  interface. This allows using the same core logic to prepare "normal"
  arguments for non-elemental intrinsics, and to prepare the elements of
  array arguments inside elemental call (ElementalIntrinsicCallBuilder
  calls genIntrinsicProcRefCore once it has computed the scalar actual
  arguments).
  To allow this split, genExprBox/genExprAddr/genExprValue logic had to
  be split in ConvertExprToHlfir.[cpp/h].

- Add missing statement context pushScope/finalizeAndPop around the
  code generation inside the hlfir.elemental so that any temps created
  while lowering the call at the element level is correctly cleaned-up.

- One piece of code in hlfir::Entity::hasNonDefaultLowerBounds() was wrong for assumed shape arrays (returned true when an assumed shaped array had no explicit lower bounds). This caused the added test to hit a bogus TODO, so fix it.

Elemental intrinsics returning are still TODO (e.g., adjustl). I will implement this in a next patch, this one is big enough.

Differential Revision: https://reviews.llvm.org/D141612
2023-01-13 09:16:12 +01:00
Jean Perier
ffc3051d0f [flang] Lower component-ref to hlfir.designate
Implement the visit of component refs in DesignatorBuilder.
The ArrayRef code has to be updated a bit to cope with the
case where the base is an array and the component is also an
array.

Improve the result type of array sections designators (only return
a fir.box if the array section is not contiguous/has dynamic extent).
This required exposing IsContiguous entry point for different
front-end designator nodes (the implementation already existed,
but was internal to check-expression.cpp).

Differential Revision: https://reviews.llvm.org/D141470
2023-01-12 10:12:54 +01:00
Jean Perier
4e78f88561 [flang] Lower addresses inside global initializers in HLFIR
Move the code to lower an expression to address or a box in HLFIR from
Bridge.cpp to ConvertExpr.cpp so that it can be used inside
ConvertVariable.cpp (that needs to use a different symbol map that the
one held in the bridge).

Lower NULL to hlfir.null.

This allows lowering derived type constant structure constructors with
pointer components into fir.global.

Differential Revision: https://reviews.llvm.org/D141276
2023-01-10 09:32:55 +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