This pass will mark functions called from TargetOp's
and declare target functions as implicitly declare
target by adding the MLIR declare target attribute
directly to the function.
This pass executes after the initial lowering of Fortran's PFT
to MLIR (FIR/OMP+Arith etc.) and is one of a series of passes
that aim to clean up the MLIR for offloading (seperate passes
in different patches, one for early outlining, another for declare
target function filtering).
Reviewers: jsjodin, skatrak, kiaranchandramohan
Differential Revision: https://reviews.llvm.org/D154247
This patch adds support for selecting which functions are lowered to LLVM IR
from MLIR depending on declare target information and whether host or device
code is being generated.
The approach proposed by this patch is to perform the filtering in two stages:
- An MLIR transformation pass, which is added to the Flang translation flow
after the `OMPEarlyOutliningPass`. The functions that are kept are those
that match the OpenMP processor (host or device) the compiler invocation
is targeting, according to the presence of the `-fopenmp-is-target-device`
compiler option and declare target information. All functions contaning an
`omp.target` are also kept, regardless of the declare target information of
the function, due to the need for keeping target regions visible for both
host and device compilation.
- A filtering step during translation to LLVM IR, which is peformed for those
functions that were kept because of the presence of a target region inside.
If the targeted OpenMP processor does not match the declare target
information of the function, then it is removed from the LLVM IR after its
contents have been processed and translated. Since they should only contain
an omp.target operation which, in turn, should have been outlined into
another LLVM IR function, the wrapper can be deleted at that point.
Depends on D150328 and D150329.
Differential Revision: https://reviews.llvm.org/D147641
This feature was introduced in `D123492`.
Doing equivalence on pointers to sort operands of commutative operations is incorrect when checking equivalence of ops in separate regions (where the lhs and rhs operands are marked as equivalent but are not the same value).
It was also discussed in `D123492` and `D129480` that the correct solution would be to stable sort the operands in canonicalization (based on some numbering in the region maybe), but until that lands, reverting this change will unblock us and other users.
An example of a pass that might not work properly because of this is `DuplicateFunctionEliminationPass`.
Reviewed By: mehdi_amini, jpienaar
Differential Revision: https://reviews.llvm.org/D154699
The extent information is available here so just add it to the acc.bounds
operation so it can be retrieved easily if needed.
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D155319
Use typed assignment in Atomic Write lowering to better handle
type conversions of allowed types.
Note: We should make similar changes for other constructs in
later patches.
Reviewed By: NimishMishra
Differential Revision: https://reviews.llvm.org/D154163
Add support to lower reduction with the multiply operator and
complex type.
Depends on D155007
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D155014
This is an attempt at mimicing the method in which
threadprivate handles the following type of variables:
program main
integer :: i
!$omp declare target to(i)
end
Which essentially generates a GlobalOp for the variable (which
would normally only be an alloca) when it's instantiated. The
main difference is there is no operation generated within the
function, instead the declare target attribute is appended
later within handleDeclareTarget.
Reviewers: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D152037
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
Check the combination of reduction operator and types. This is
currently not checking common block and composite types.
Depends on D155105
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D155106
There was a bug with the -funderscoring / -fno-underscoring options from (https://reviews.llvm.org/D140795) that prevented the driver option from controlling the underscoring behaviour and instead the behaviour could only be controlled by the pass option instead of the driver option. The driver test case did not catch the bug and also needed to be updated.
Reviewed By: awarzynski
Differential Revision: https://reviews.llvm.org/D155042
This patch implements an early outlining transform of omp.target operations in
flang. The pass is needed because optimizations may cross target op region
boundaries, but with the outlining the resulting functions only contain a
single omp.target op plus a func.return, so there should not be any opportunity
to optimize across region boundaries.
The patch also adds an interface to be able to store and retrieve the parent
function name of the original target operation. This is needed to be able to
create correct kernel function names when lowering to LLVM-IR.
Reviewed By: kiranchandramohan, domada
Differential Revision: https://reviews.llvm.org/D154879
Add lowering support for reduction with the add operator
on complex type.
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D155007
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
Add support for the `.neqv.` reduction operator for
Flang/OpenACC lowering.
Depends on D154900
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D154901
Add support for the `.eqv.` reduction operator for
Flang/OpenACC lowering.
Depends on D154898
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D154900
Add support for the `.or.` reduction operator for
Flang/OpenACC lowering.
Depends on D154896
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D154898
Add support for the `.and.` reduction operator
in Flang/OpenACC lowering.
Depends on D154888
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D154896
The return type of the recipe must match the array slice provided by
the user. This patch enhance the recipe creation to take into account
the constant slices.
Depends on D154657
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D154727
Similiar to D154259 for private recipe, this patch makes use of the same code
for the init region of the firstprivate recipe and populate the copy region for
trivial types and arrays.
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D154657
hlfir.get_length will not modify the buffer and so it is safe for a
hlfir.associate using the same expression buffer not to make its own
copy.
Differential Revision: https://reviews.llvm.org/D154942
Do not look for the global early in nullify codegen. The type descriptor
can be emitted later and it would raise an error as it could not be found.
Use `fir.type_desc` instead so it delays the type descriptor lookup until
evrything is emitted.
https://github.com/llvm/llvm-project/issues/63775
Reviewed By: vzakhari
Differential Revision: https://reviews.llvm.org/D154982
Currently the local builder used in IntrinsicCall doesn't have the
fastmath flags passed to it. This results in the fastmath attribute
not being added to certain runtime calls. This patch simply forwards
the fastmath flags from the parent builder.
Differential Revision: https://reviews.llvm.org/D154611
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
In the context of elemental operation a dynamically optional
intrinsic argument must be lowered such that the elemental
designator is generated under isPresent check.
Reviewed By: tblah
Differential Revision: https://reviews.llvm.org/D154897
Add support for `ieor` reduction operator in
OpenACC lowering.
Depends on D154887
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D154888
Add support for `ior` reduction operator in
OpenACC lowering.
Depends on D154886
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D154887
Make a copy of the expression and associate that so that this is the
only use.
So far as I know, we don't currently generate code for an associate with
more than one use. This is here just in case.
Depends on D154715
Differential Revision: https://reviews.llvm.org/D154721
The associate operation checks if it is the only use of the hlfir.expr,
and if so it can take ownership of the hlfir.expr instead of copying it
(move semantics).
If this check is done by accessing the associate operation's arguments
directly (not through the AssociateOpAdaptor), the expression uses will
contain some operations which have been deleted. These can include prior
copies of the same associate operation, if that operation was cloned
(e.g. to lower a hlfir.elemental into a fir.do_loop). Accessing the
bufferized expression instead of the old hlfir.expr through the adaptor
avoids this false positive.
Differential Revision: https://reviews.llvm.org/D154715
The following error was triggered in the added test case.
This is a false positive.
COMMON block must be declared in the same scoping unit in which the OpenACC directive or clause appears
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D154742
This patch renames the `OpenMPIRBuilderConfig` flags to reduce confusion over
their meaning. `IsTargetCodegen` becomes `IsGPU`, whereas `IsEmbedded` becomes
`IsTargetDevice`. The `-fopenmp-is-device` compiler option is also renamed to
`-fopenmp-is-target-device` and the `omp.is_device` MLIR attribute is renamed
to `omp.is_target_device`. Getters and setters of all these renamed properties
are also updated accordingly. Many unit tests have been updated to use the new
names, but an alias for the `-fopenmp-is-device` option is created so that
external programs do not stop working after the name change.
`IsGPU` is set when the target triple is AMDGCN or NVIDIA PTX, and it is only
valid if `IsTargetDevice` is specified as well. `IsTargetDevice` is set by the
`-fopenmp-is-target-device` compiler frontend option, which is only added to
the OpenMP device invocation for offloading-enabled programs.
Differential Revision: https://reviews.llvm.org/D154591
This fixes the majority of cases where we hit the "hlfir.associate of
hlfir.expr with more than one use" TODO. In particular, this allows cam4
to be built.
hlfir.shape_of is just a way to delay reading shape information until
after intrinsics have been lowered to FIR runtime calls. It gets the
shape information from reading existing SSA values (e.g. fetching the
shape used when hlfir.declare'ing the variable).
Therefore hlfir.shape_of doesn't affect decisions about when to
deallocate the buffer.
Differential Revision: https://reviews.llvm.org/D154521
The return type of the recipe must match the array slice provided by
the user. This patch enhance the recipe creation to take into account
the constant slices.
Depends on D154259
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D154648
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
Lower hlfir.get_length into the char length inquiry of the bufferized
entity. In some cases the codegen will fail with
`hlfir.associate of hlfir.expr with more than one use` - this will be fixed
separately (after D154521).
Depends on D154560
Reviewed By: tblah, jeanPerier
Differential Revision: https://reviews.llvm.org/D154561
We will use hlfir.get_length to lower inquiries of char length
applied to hlfir.expr character values.
Reviewed By: tblah, jeanPerier
Differential Revision: https://reviews.llvm.org/D154560
This patch implements HLFIR lowering for associating an actual
TARGET argument to a dummy POINTER argument.
Reviewed By: tblah, jeanPerier
Differential Revision: https://reviews.llvm.org/D154311
Wrong error was reported mentioning that the common block was in
more than one data sharing clause.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D154393
The sourcerange was missing for a few directives when
they were the first directive to appear in a program
without a program statement.
Reviewed By: DavidTruby
Differential Revision: https://reviews.llvm.org/D153634
The need to save LHS addresses on a stack before doing an assignment
is very limited: it is only really needed for forall and vectore
subscripted LHS where the LHS cannot be computed as a descriptor.
The previous current WHERE codegen was creating address stacks for
LHS element addresses when the LHS evaluation conflicts with the
assignment (may depend on the LHS value). This is not needed
since the computed array designator for the LHS is already "saved"
before the assignment from an SSA point of view.
This patch prevents LHS temporary stack from being created outside
of forall and vector subscripted assignments.
Differential Revision: https://reviews.llvm.org/D154418
genElementalCall can return a null option when lowering elemental
subroutine calls (as there is no return value). Therefore
std::option::value should not be used as it will cause an
assertion failure.
This fixes uses of the mvbits intrinsic with array arguments, as used in
the gfortran test suite.
Differential Revision: https://reviews.llvm.org/D154340
This adds support for dynamically optional arguments for intrinsics
which do not have their own hlfir operations.
The functions for processing these arguments are mostly the same as the
equivalent functions in ConvertExpr.cpp. I chose not to share
implementations so that HLFIR helpers can be used here. Presumably
ConvertExpr.cpp will go away one day.
Depends on D154236
Differential Revision: https://reviews.llvm.org/D154237
This also adds support for allocatable non-optional arguments.
Of the transformational intrinsics which currently have their own hlfir
operations, all of the dynamically optional arguments are lowered as
boxes, so that is all that is implemented for now.
One alternative approach would have been to deal with the dynamically
optional arguments when lowering to FIR runtime calls. I decided not to
do this so that any passes working on the intrinsic operations would not
have to know about and handle the dynamically optional arguments.
Depends on D154235
Differential Revision: https://reviews.llvm.org/D154236