ApplyOp provides the type parameters in its argument, so we can
take it from there. For hlfir.expr block arguments (such as with
user-defined assignments) we use hlfir.get_length in lowering.
Depends on D154561
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D154562
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
This patch sets `unordered` `fir.do_loop` attribute during lowering
of elemental subroutine calls to HLFIR, when it is safe to do so.
Proper handling of `hlfir.elemental` will be done in a separate patch.
Reviewed By: jeanPerier, tblah
Differential Revision: https://reviews.llvm.org/D154031
This patch adds support for vector subscripted assignment left-hand
side. It does not yet add support for the cases where the LHS must be
saved because its evaluation could be impacted by the assignment.
The implementation adds an hlfir::ElementalOpInterface to share the
elemental inlining utility and some other tools between
hlfir::ElementalOp and hlfir::ElelemntalAddrOp.
It adds generateYieldedLHS() to allow retrieving the LHS value
in lowering, whether or not it is vector subscripted. If it is vector
subscripted, this utility creates a loop nest iterating over the
elements and returns the address of an element.
Differential Revision: https://reviews.llvm.org/D153759
Lower user defined assignment inside the hlfir.region_assign
"userDefinedAssignment" mlir region.
This is done by adding an entry point to ConvertCall.h in order
to call genUserCall with the region block arguments as arguments.
The codegen for hlfir.region_assign with user defined assignment
will be added in a later patch.
Differential Revision: https://reviews.llvm.org/D153404
Use hlfir::loadTrivialScalars to dereference pointer, allocatables, and
load numerical and logical scalars.
This has a small fallout on tests:
- load is done on the HLFIR entity (#0 of hlfir.declare) and not the FIR one (#1). This makes no difference at the FIR level (#1 and #0 only differs to account for assumed and explicit shape lower bounds).
- loadTrivialScalars get rids of allocatable fir.box for monomoprhic scalars
(it is not needed). This exposed a bug in lowering of MERGE with
a polymorphic and a monomorphic argument: when the monomorphic is not
a fir.box, the polymorphic fir.class should not be reboxed but its
address should be read.
Reviewed By: tblah
Differential Revision: https://reviews.llvm.org/D153252
It seems just replacing the operation was not replacing all of the uses
when the types of the expression before and after this pass differ (due
to differing shape information). Now the shape information is always
kept the same.
This fixes https://github.com/llvm/llvm-project/issues/63399
Differential Revision: https://reviews.llvm.org/D153333
The code is used, for example, when passing arguments to IO or intrinsic
calls as value. The allocatable/pointer boxes must be dereferenced,
and trivial values have to be loaded. Character and derived values
have to stay boxed.
I am not sure what to do for the array cases, and I have not seen
any test triggering it, so I leave it as a TODO.
Reviewed By: tblah, clementval
Differential Revision: https://reviews.llvm.org/D151925
First issue is that the clean-ups were generated after the yield_element
operation that must be the terminator. Second issue is that codegen for
elemenal operation was not working properly with nested elemental ops.
Differential Revision: https://reviews.llvm.org/D149921
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
We have to unbox the boxchar variables in order to get to
the raw address that can be used for emboxing.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D149473
We have to keep it as a box, since taking box_addr of the optional
box may be invalid.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D149505
Inlining as a hlfir.elemental will allow the transpose to be inlined
into subsequent operations in some cases. For example,
y = TRANSPOSE(x)
z = y * 2
Will operate in a single loop without creating a temporary for the
TRANSPOSE (unlike the runtime call, which always allocates).
This is in a new SimplifyHLFIRIntriniscs pass. The intention is that some
day that pass might replace the FIR SimplifyIntrinsics pass.
Depends On: D149060
Reviewed By: jeanPerier, vzakhari
Differential Revision: https://reviews.llvm.org/D149067
If we know the extent at compile time, it is better to generate an
arith.constant than hlfir.get_extent. This gives more information earlier
in compilation (before hflir.get_extent is lowered).
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D149060
The array component indices in the "path" of a fir.slice are zero based
because FIR does not know about the component lower bounds.
When lowering hlfir.designate to FIR for `array%x(i, j)`, convert `i` and
`j` to zero based indices before generating the fir.slice.
Differential Revision: https://reviews.llvm.org/D148627
If the extents were known, this should have been canonicalised into a
fir.shape operation. Therefore, the extents at this point are not known at
compile time. Use hlfir.get_extents to delay resolving the real extent
until after the expression is bufferized.
Depends On: D146831
Differential Revision: https://reviews.llvm.org/D146832
Add an HLFIR operation for the SUM transformational intrinsic, according
to the design set out in flang/doc/HighLevelFIR.md.
I decided to make hlfir.sum very lenient about the form of its
arguments. This allows the sum intrinsic to be lowered to only this HLFIR
operation, without needing several operations to convert and box
arguments. Having only one operation generated for the intrinsic
invocation should make optimisation passes on HLFIR simpler.
Differential Revision: https://reviews.llvm.org/D142897
- 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
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
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
There is little point not to dereference pointers LHS and RHS before
before emitting an hlfir.assign when lowering an assignment.
This pushes complexity and descriptor read side effects that are better
expressed in a load before the assignment.
Differential Revision: https://reviews.llvm.org/D143372
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
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
The patch adds operations to `BlockAndValueMapping` and renames it to `IRMapping`. When operations are cloned, old operations are mapped to the cloned operations. This allows mapping from an operation to a cloned operation. Example:
```
Operation *opWithRegion = ...
Operation *opInsideRegion = &opWithRegion->front().front();
IRMapping map
Operation *newOpWithRegion = opWithRegion->clone(map);
Operation *newOpInsideRegion = map.lookupOrNull(opInsideRegion);
```
Migration instructions:
All includes to `mlir/IR/BlockAndValueMapping.h` should be replaced with `mlir/IR/IRMapping.h`. All uses of `BlockAndValueMapping` need to be renamed to `IRMapping`.
Reviewed By: rriddle, mehdi_amini
Differential Revision: https://reviews.llvm.org/D139665
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
Hlfir.designate was made to support substrings but so far substrings
were not yet lowered to it. Implement support for them.
Differential Revision: https://reviews.llvm.org/D140310
This will implement evaluate::SetLength where the length of
a character entity is changed (with trimming and padding).
Differential Revision: https://reviews.llvm.org/D140219
The motivation is to have it accessible in HLFIROps.cpp to
use it in hlfir.set_length builder to build the result length
type as best as possible.
Differential Revision: https://reviews.llvm.org/D140214
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
The defining op of HLFIR variables is expected to be visible
in most cases, but HLFIR codegen won't rely on it from a correctness
point of view.
This patch allows building a fir.shape from an hlfir::Entity does not
have a visible FortranVariabeInterface defining op.
Differential Revision: https://reviews.llvm.org/D140099
Without any optimization or when it cannot be optimized before
bufferization, an hlfir.elemental lowers to an array temporary.
Its codegen consists in:
- allocating a temp given the type, shape, and length parameter arguments.
- generating a loop nest given the elemental shape
- inlining the body of the elemental inside the loops, and replacing the
yield_element by an assignment to an element of the temp.
Differential Revision: https://reviews.llvm.org/D140093
Lower binary and unary elemental operations with an array argument
using hlfir.elemental, hlfir.yield_element, and hlfir.apply.
Concat implementation, which is a binary operation, is moved to a
BinaryOp struct so that it can leverage this new code.
This patch implements the "not yet implemented: character array
expression temp with dynamic length" TODO of the current lowering
by splitting the result length computation from the result value
computation. That way, the result length computation can be done
before lowering the operation to an hlfir.elemental, and the length
of the hlfir.elemental is known and storage for it can later be
allocated.
It adds a DesignatorOp builder to make "dumb" indexing (without triplets,
component, substrings or derived type component ref) easier since indexing
needs to be generated for array variables in elemental expression (in
the added hlfir::genElementAt helper).
Differential Revision: https://reviews.llvm.org/D140040
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
Add the default unoptimized implementation implementation
of hlfir.assign. It relies on the runtime for array assignment
and always makes a temp of the right hand side for arrays.
Assignment optimization will be done when all HLFIR pieces are in place
and aliasing analysis is available.
Differential Revision: https://reviews.llvm.org/D139426
For now at least, the plan is to keep hlfir.expr usage limited as
sub-expression operand, assignment rhs, and a few other contexts (
e.g. Associate statements). The rest of lowering (statements lowering
in the bridge) will still expect to get and manipulate characters and
arrays in memory. That means that hlfir.expr must be converted to
variable in converter.genExprAddr/converter.genExprBox.
This is done using an hlfir.associate, and generating the related
hlfir.end_associate in the statement context.
hlfir::getFirBase of is updated to avoid bringing in the HLFIR
fir.boxchar/fir.box into FIR when the entity was created with
hlfir::AssociateOp.
Differential Revision: https://reviews.llvm.org/D139328
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
Also add support for fir.boxchar in HLFIRTools so that character
designator with none constant lengths can be processed/converted to
fir::ExtendedValue.
Differential Revision: https://reviews.llvm.org/D138190
Update lowering to generate hlfir.declare instead of fir.declare.
Introduce the hlfir::Entity class that will be used to work with
Fortran objects in HLFIR transformation.
Fix lower bounds that where swapped with extents in fir.declare
generation.
Update tests that expected fir.declare.
Differential Revision: https://reviews.llvm.org/D137951
This reflects the fact that Attributes will not always be visible when
looking at an HLFIR variable. The EntityWithAttributes class is used
to denote in the compiler code that the value at hand has visible
attributes. It is intended to be used in lowering so that the code
can query about operands attributes when generating code.
Differential Revision: https://reviews.llvm.org/D137792
Use the utility to lower Constant<T> that was split from current lowering
in https://reviews.llvm.org/D136955.
The difference in HLFIR is the addition of a fir.declare on constant
outlined in memory so that all the information about them is available.
Lowering to HLFIR is enabled in Brideg::genExprValue to allow testing
of scalar constant lowering.
Differential Revision: https://reviews.llvm.org/D137084
Add hlfir::FortranEntity class and a first helper to convert it to
fir::ExtendedValue.
The hlfir::FortranEntity will be the core class of the new expression
lowering. It is conceptually very similar to what fir::ExtendedValue
is today, except that it is wrapping single mlir::Value: it holds the
SSA value for a lowered Fortran variable or expression value.
Differential Revision: https://reviews.llvm.org/D136428