Emits MLIR op corresponding to `!$omp target update` directive. So far,
only motion types: `to` and `from` are supported. Motion modifiers:
`present`, `mapper`, and `iterator` are not supported yet.
This is a follow up to #75047 & #75159, only the last commit is relevant
to this PR.
Make sure we only load box and read its bounds when it is present.
- Add `AddrAndBoundInfo` struct to be able to carry around the `addr`
and `isPresent` values. This is likely to grow so we can make all the
access in a single `fir.if` operation.
The function `instantiateVariable` in Bridge.cpp has the following code:
```
if (var.getSymbol().test(
Fortran::semantics::Symbol::Flag::OmpThreadprivate))
Fortran::lower::genThreadprivateOp(*this, var);
if (var.getSymbol().test(
Fortran::semantics::Symbol::Flag::OmpDeclareTarget))
Fortran::lower::genDeclareTargetIntGlobal(*this, var);
```
Implement `handleOpenMPSymbolProperties` in OpenMP.cpp, move the above
code there, and have `instantiateVariable` call this function instead.
This would further separate OpenMP-related details into OpenMP.cpp.
The specific terminator operation depends on what operation it is inside
of. The function `genOpenMPTerminator` performs these checks and selects
the appropriate type of terminator.
Remove partial duplication of that code, and replace it with a function
call. This makes `genOpenMPTerminator` be the sole source of OpenMP
terminators.
Replace explicit calls to
```
op = builder.create<SectionOp>(...)
createBodyOfOp<SectionOp>(op, ...)
```
with a single call to
```
createOpWithBody<SectionOp>(...)
```
This is NFC, that's what the `createOpWithBody` function does.
The function `genCommonBlockMember` is not specific to OpenMP, and it
could very well be a common utility. Move it to ConvertVariable.cpp
where it logically belongs.
This got "lost" in the HLFIR transformation. This patch applies the old
attribute to the AssociateOp that needs it, and forwards it to the
AllocaOp that is generated when lowering to FIR.
This patch removes the val field from the `MapInfoOp`.
Previously when lowering `TargetOp`, the bounds information for the
`BoxValues` were also being mapped. Instead these ops are now cloned
inside the target region to prevent mapping of non reference typed
values.
Initialization of reduction variable for min-reduction is set to largest
negative value. As such, in presence of non-negative operands, min
reduction gives incorrect output. This patch initialises min-reduction
to use the maximum positive value instead, so that it can produce
correct output for the entire range of real valued operands.
Fixes https://github.com/llvm/llvm-project/issues/73101
This patch adds the following check from OpenMP 5.2.
```
If the directive has a clause, it must contain at least one enter clause
or at least one link clause.
```
Also added a warning for the deprication of `TO` clause on `DECLARE
TARGET` construct.
```
The clause-name to may be used as a synonym for the clause-name enter.
This use has been deprecated.
```
Based on the tests for to clause, the tests for enter clause are added.
This patch does not add tests where both to and enter clause are used together.
Currently Statement context used during processing of clauses is
finalized after the OpenMP operation creation. This causes the
finalization to go inside the OpenMP region and this can lead to
multiple finalizations in a parallel region. This fix proposes to
finalize them before the OpenMP op creation.
Fixes#71342
In cases like `copy(array(N))` it is still useful to represent
the data operand uniformly with `copy(array(N:N))`.
This change generates data bounds even if it is not an array
section with the triplets. The lower and the upper bounds
are the same and the extent is one in this case.
This patch adds the PFT lowering changes required for adding the IsolatedFromAbove trait to omp.target.
Key Changes:
- Add IsolatedFromAbove trait to target op in MLIR.
- Main reason for this change is to prevent CSE and other similar optimisations from crossing region boundaries for target operations. The link below has the discourse discussion surrounding this issue.
- Move implicit operand capturing to the PFT lowering stage.
- Implicit operands are first added as implicitly captured map_operands with their map_types set accordingly to indicate this. Later, all map_operands including implicit ones are added as block arguments.
- Remove `implicit` attribute from the `MapInfoOp`. This information is already captured by the `map_type`.
- The custom printer and parser for the map_types have been updated to show the `implicit` and `literal` map_types.
- Update related tests.
- This fixes#63555.
- This fixes#70488.
The location set on atomic operations in both OpenMP and OpenACC was
completly off. The real location needs to be created from the source
CharBlock of the parse tree node of the respective atomic statement.
This patch updates locations in lowering for atomic operations.
Iteration variables behave slightly different with LASTPRIVATE,
as they must be assigned the value that the copy would have after
sequential execution of the loop. This case is now handled.
This patch also fixes LASTPRIVATE for loops where the step is
different from 1.
Fixes https://github.com/llvm/llvm-project/issues/64055
Remove usage of getElementType in OpenMPTranslation to pave way for
switching to opaque pointers in MLIR and Flang. The approach chosen
stores the elementType in a new field in MapInfo called varType. A
similar approach was chosen for AtomicReadOp in
81767f52f4
This patch builds on top of a prior patch in review which adds a new map
and bounds operation by modifying the OpenMP PFT lowering to support
these operations and generate them from the PFT.
A significant amount of the support for the Bounds operation is borrowed
from OpenACC's own current implementation and lowering, just ported
over to OpenMP.
The patch also adds very preliminary/initial support for lowering to
a new Capture attribute, which is stored on the new Map Operation,
which helps the later lowering from OpenMP -> LLVM IR by indicating
how a map argument should be handled. This capture type will
influence how a map argument is accessed on device and passed by
the host (different load/store handling etc.). It is reflective of a
similar piece of information stored in the Clang AST which performs a
similar role.
As well as some minor adjustments to how the map type (map bitshift
which dictates to the runtime how it should handle an argument) is
generated to further support more use-cases for future patches that
build on this work.
Finally it adds the map entry operation creation and tying it to the relevant
target operations as well as the addition of some new tests and alteration
of previous tests to support the new changes.
Depends on D158732
reviewers: kiranchandramohan, TIFitis, clementval, razvanlupusoru
Differential Revision: https://reviews.llvm.org/D158734
This patch implements the lowering of the OpenMP 'requires' directive
from Flang parse tree to MLIR attributes attached to the top-level
module.
Target-related 'requires' clauses are gathered and combined for each top-level
unit during semantics. Lastly, a single module-level `omp.requires` attribute
is attached to the MLIR module with that information at the end of the process.
The `atomic_default_mem_order` clause is not addressed by this patch, but
rather it will come as a separate patch and follow a different approach.
Depends on D147214, D150328, D150329 and D157983.
Differential Revision: https://reviews.llvm.org/D147218
For unstructured construct, the blocks are created in advance inside the
function body. This causes issues when the unstructured construct is
inside an OpenACC region operations. This patch adds the same fix than
OpenMP lowering and re-create the blocks inside the op region.
Initial OpenMP fix: 29f167abcf
This patch is part of a larger initiative aimed at fixing floating-point `max` and `min` operations in MLIR: https://discourse.llvm.org/t/rfc-fix-floating-point-max-and-min-operations-in-mlir/72671.
This commit addresses Task 1.2 of the mentioned RFC. By renaming these operations, we align their names with LLVM intrinsics that have corresponding semantics.
Since the OpenACC atomics specification is a subset of OpenMP atomics,
the same lowering implementation can be used. This change extracts out
the necessary pieces from the OpenMP lowering and puts them in a shared
spot. The shared spot is a header file so that each implementation can
template specialize directly.
After putting the OpenMP implementation in a common spot, the following
changes were needed to make it work for OpenACC:
* Ensure parsing works correctly by avoiding hardcoded offsets.
* Templatize based on atomic type.
* The checking whether it is OpenMP or OpenACC is done by checking for
OmpAtomicClauseList (OpenACC does not implement this so we just
templatize with void). It was preferable to check this instead of atomic
type because in some cases, like atomic capture, the read/write/update
implementations are called - and we want compile time evaluation of
these conditional parts.
* The memory order and hint are used only for OpenMP.
* Generate acc dialect operations instead of omp dialect operations.
Atomic update operation is modelled in OpenMP dialect as
an operation that takes a reference to the operation being
updated. It also contains a region that will perform the
update. The block argument represents the loaded value from
the update location and the Yield operation is the value
that should be stored for the update.
OpenMP FIR lowering binds the value loaded from the update
address to the SymbolAddress. HLFIR lowering does not permit
SymbolAddresses to be a value. To work around this, the
lowering is now performed in two steps. First the body of
the atomic update is lowered into an SCF execute_region
operation. Then this is copied into the omp.atomic_update
as a second step that performs the following:
-> Create an omp.atomic_update with the block argument of
the correct type.
-> Copy the operations from the SCF execute_region. Convert
the scf.yield to an omp.yield.
-> Remove the loads of the update location and replace all
uses with the block argument.
Reviewed By: tblah, razvanlupusoru
Differential Revision: https://reviews.llvm.org/D158294
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
This patch explicitly marks supported clauses for OpenMP directives missing an
implementation, so that compilation fails if they are specified, rather than
silently ignoring them.
Differential Revision: https://reviews.llvm.org/D158076
This patch adds lowering support for threadprivate
variables encapsulated in a common block and
marked inside a copyin clause.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D157083
This patch adds support for translating `teams` OpenMP directives to MLIR, when
appearing as either loop or block constructs and as part of combined constructs
or on its own.
The current Fortran parser does not allow the specification of the optional
lower bound for the "num_teams" clause, so only the `num_teams_upper` MLIR
argument is set by this patch.
Depends on D156809
Differential Revision: https://reviews.llvm.org/D156884
This patch extracts MLIR codegen logic from various types of OpenMP constructs
and places it into operation-specific functions. This refactoring mainly
targets block constructs and unifying logic for directives that can appear on
their own as well as combined with others.
The processing of clauses that do not apply to the directive being processed is
avoided and code duplication for combined constructs is reduced.
Depends on D156455.
Differential Revision: https://reviews.llvm.org/D156809
This patch adds support for lowering target-related combined constructs from
PFT to MLIR. The lowering of OpenMP loop constructs is generalized in
preparation for later supporting different combinations of target, teams,
distribute, parallel and simd directives.
Currently enabled by this patch are the following combined constructs:
- do simd
- parallel do simd
- target parallel do simd
- target parallel do
- target simd
Depends on D155981 and D157090.
Differential Revision: https://reviews.llvm.org/D156455
HLFIR inserts hlfir.declare for threadprivate variables. Seek over
the hlfir.declare to find the threadprivate global symbol.
Reviewed By: tblah
Differential Revision: https://reviews.llvm.org/D157730