16 Commits

Author SHA1 Message Date
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
1119c15ef5 [flang][hlfir] Enable lowering and passing of allocatables and pointers.
Adds support for:
- referencing a whole allocatable/pointer symbol
- passing allocatable/pointer in a call

This required update in HLFIRTools.cpp helpers so that the
raw address, extents, lower bounds, and type parameters of a
fir.box/fir.class can be extracted.
This is required because in hlfir lowering, dereferencing a
pointer/alloc is only doing the fir.load fir.box part, and the
helpers have to be able to reason about that fir.box without the
help of a "fir::FortranVariableOpInterface".

Missing:
- referencing part of allocatable/pointer (will need to update
  Designator lowering to dereference the pointer/alloc). Same
  for whole allocatable and pointer components.
- allocate/deallocate/pointer assignment statements.
- Whole allocatable assignment.
- Lower inquires.

Differential Revision: https://reviews.llvm.org/D142043
2023-01-19 14:18:22 +01:00
Jean Perier
da78ae46f4 [flang][hlfir] Lower some character elemental references
Lower character elemental user procedures with constant length, and
bot dynamic and constant length ADJUSTL, ADJUSTR, and MERGE references
(which leaves out MIN/MAX).

Character elemental user procedures with dynamic length are a bit more
involving and since it is an edge-case that is not currently supported,
I will take this on later.

Differential Revision: https://reviews.llvm.org/D141847
2023-01-17 13:41:07 +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
3909b60a3c [flang][NFC] Remove CallBuilder class
The methods of CallBuilder do need to belong to a class.
This was made to avoid having to propagate generic lowering context
(converter, symbol mappings, location and StatementContext).

Packaging them together will actually make it harder to share the code
for user and intrinsic elemental lowering (I plan to use C++ CRTP),
and it is also misleading: one could think there is something going
with the class state while lowering the function while there is not
(and there should not be).

Removes the class and turns the methods into static functions.
Add a new CallContext class to solve the argument threading
inconvenience.

This contains no functional changes at all.

Differential Revision: https://reviews.llvm.org/D141510
2023-01-12 10:16:09 +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
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
Jean Perier
8febe67851 [flang] Lower statement function references in HLFIR
Enable lowering of statement function references in HLFIR.  This follows
the same principle as statement function lowering with the current
lowering:
- Actual arguments are lowered and mapped to the statement function
  dummy symbols.
- "HostAssociated" symbols are mapped to their host values (these are
  the symbols referred to inside the statement function expressions that
  are not statement function dummies. e.g: `x` in `stmt_func(i) =
  x(i)`).
- The statement function expression is evaluated.

evaluate::SetLength has to be lowered to deal with statement functions
returning characters since the front-end is generating one to ensure the
statement function expression value is trimmed/padded to match the statement
function declared type.

Differential Revision: https://reviews.llvm.org/D140220
2022-12-19 11:11:37 +01: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
4203b062fb [flang] Lower procedure ref to user defined elemental procedures (part 1)
Lower procedure ref to user defined elemental procedure when:
- there are no arguments that may be dynamically optional
- for functions, the result has no length parameters
- the reference can be unordered
- there are not character by value arguments

This uses the recently added hlfir.elemental operation and tools.
The "core" of the argument preparation is shared between elemental
and non elemental calls (genUserCalls is code moved without any
functional changes)

Differential Revision: https://reviews.llvm.org/D140118
2022-12-16 13:04:04 +01:00
Jean Perier
b013ebe059 [flang] Lower intrinsics to HLFIR part 1
This patch adds support for lowering intrinsics that have no dynamic
optionality aspects to handle and that requires argument to be lowered
to value, addr, or box.

It uses the current intrinsic lowering framework that can be re-used in
HLFIR to start with. HLFIR operations for charater/transformational
intrinsics will be added as needed from an optimization point of view.
The current approach will still create temporary variables for their
value directly in lowering.

Later patch will still need to add:
- support for dynamically optional arguments
- inquires
- "moving" the in memory computation of character and transformational
intrinsics to hlfir.expr. This is not needed from a semantic point of
view, but will help optimizing and will probably be required inside
hlfir.elemental returning characters so that the returned element
type is an hlfir.expr and match the result type of later hlfir.apply.

Differential Revision: https://reviews.llvm.org/D139613
2022-12-09 10:11:37 +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
Jean Perier
e78e4a1761 [flang] lower F77 calls in HLFIR
Use recently added hlfir.associate/hlfir.end_associate to deal
with the cases where the actual argument is an expression.

Differential Revision: https://reviews.llvm.org/D139009
2022-12-01 11:22:38 +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