summaryrefslogtreecommitdiff
path: root/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
AgeCommit message (Collapse)Author
2025-11-14[OpenMP][Flang] Emit default declare mappers implicitly for derived types ↵Akash Banerjee
(#140562) This patch adds support to emit default declare mappers for implicit mapping of derived types when not supplied by user. This especially helps tackle mapping of allocatables of derived types.
2025-11-10[Flang][OpenMP] Move char box bounds generation for Maps to ↵agozillon
DirectiveCommons.h (#165918) Currently we generate these bounds in the MapInfoFinalization.cpp pass as it seems there's a missing case for character strings/arrays (length parameter) in the DirectiveCommons bounds generation functionality OpenMP uses for it's map operations. This PR tries to add this case to the DirectiveCommons function and remove the need for the bounds generation in the MapInfoFinalization pass, so that we are generating the bounds in the same place most other bounds are generated.
2025-11-07[Flang][OpenMP] Unify MapInfoFinalization's BoxChar handling with other Box ↵agozillon
types (#165954) Currently we handle BoxChars separately and a little differently to the other BoxType's, however realistically they can be handled the same and should be to simplify the pass as much as we can.
2025-10-22[flang][mlir] Migrate to free create functions. NFC. (#164657)Jakub Kuderski
See https://discourse.llvm.org/t/psa-opty-create-now-with-100-more-tab-complete/87339. I plan to mark these as deprecated in https://github.com/llvm/llvm-project/pull/164649.
2025-10-21[Flang][OpenMP][Dialect] Swap to using MLIR dialect enum to encode map flags ↵agozillon
(#164043) This PR shifts from using the LLVM OpenMP enumerator bit flags to an OpenMP dialect specific enumerator. This allows us to better represent map types that wouldn't be of interest to the LLVM backend and runtime in the dialect. Primarily things like ref_ptr/ref_ptee/ref_ptr_ptee/atach_none/attach_always/attach_auto which are of interest to the compiler for certrain transformations (primarily in the FIR transformation passes dealing with mapping), but the runtime has no need to know about them. It also means if another OpenMP implementation comes along they won't need to stick to the same bit flag system LLVM chose/do leg work to address it.
2025-10-15[Flang][OpenMP] Fix USM `close` semantics and `use_device_ptr` (#163258)Akash Banerjee
- Add CLOSE map flag when USM is required. - use_device_ptr: prevent implicitly expanding member operands. - Fixes test offload/test/offloading/fortran/usm_map_close.f90.
2025-10-09[Flang][OpenMP] Defer descriptor mapping for assumed dummy argument types ↵agozillon
(#154349) This PR adds deferral of descriptor maps until they are necessary for assumed dummy argument types. The intent is to avoid a problem where a user can inadvertently map a temporary local descriptor to device without their knowledge and proceed to never unmap it. This temporary local descriptor remains lodged in OpenMP device memory and the next time another variable or descriptor residing in the same stack address is mapped we incur a runtime OpenMP map error as we try to remap the same address. This fix was discussed with the OpenMP committee and applies to OpenMP 5.2 and below, future versions of OpenMP can avoid this issue via the attach semantics added to the specification.
2025-10-02[Flang][OpenMP] Implicitly map nested allocatable components in derived ↵Akash Banerjee
types (#160766) This PR adds support for nested derived types and their mappers to the MapInfoFinalization pass. - Generalize MapInfoFinalization to add child maps for arbitrarily nested allocatables when a derived object is mapped via declare mapper. - Traverse HLFIR designates rooted at the target block arg and build full coordinate_of chains; append members with correct membersIndex. This fixes #156461.
2025-09-25Revert "[Flang][OpenMP] Implicitly map nested allocatable components in ↵Akash Banerjee
derived types" (#160759) Reverts llvm/llvm-project#160116
2025-09-24[Flang][OpenMP] Implicitly map nested allocatable components in derived ↵Akash Banerjee
types (#160116) This PR adds support for nested derived types and their mappers to the MapInfoFinalization pass. - Generalize MapInfoFinalization to add child maps for arbitrarily nested allocatables when a derived object is mapped via declare mapper. - Traverse HLFIR designates rooted at the target block arg and build full coordinate_of chains; append members with correct membersIndex. This fixes #156461.
2025-07-25[Flang][OpenMP] Appropriately emit present/load/store in all cases in ↵agozillon
MapInfoFinalization (#150311) Currently, we return early whenever we've already generated an allocation for intermediate descriptor variables (required in certain cases when we can't directly access the base address of a passes in descriptor function argument due to HLFIR/FIR restrictions). This unfortunately, skips over the presence check and load/store required to set the intermediate descriptor allocations values/data. This is fine in most cases, but if a function happens to have a series of branches with seperate target regions capturing the same input argument, we'd emit the present/load/store into the first branch with the first target inside of it, the secondary (or any preceding) branches would not have the present/load/store, this would lead to the subsequent mapped values in that branch being empty and then leading to a memory access violation on device. The fix for the moment is to emit a present/load/store at the relevant location of every target utilising the input argument, this likely will also lead to fixing possible issues with the input argument being manipulated inbetween target regions (primarily resizing, the data should remain the same as we're just copying an address around, in theory at least). There's possible optimizations/simplifications to emit less load/stores such as by raising the load/store out of the branches when we can, but I'm inclined to leave this sort of optimization to lower level passes such as an LLVM pass (which very possibly already covers it).
2025-07-24[mlir][NFC] update `flang/lib` create APIs (12/n) (#149914)Maksim Levental
See https://github.com/llvm/llvm-project/pull/147168 for more info.
2025-06-10[Flang][OpenMP] - When mapping a `fir.boxchar`, map the underlying data ↵Pranav Bhandarkar
pointer as a member (#141715) This PR adds functionality to the `MapInfoFinalization` pass wherein the underlying data pointer of a `fir.boxchar` is mapped as a member of the parent boxchar.
2025-05-12[Flang][MLIR] - Handle the mapping of subroutine arguments when they are ↵Pranav Bhandarkar
subsequently used inside the region of an `omp.target` Op (#134967) This is a fix for https://github.com/llvm/llvm-project/issues/134912 which is a problem with mapping `fir.boxchar<k>` type values to the target i.e an `omp.target` op. There really are two problems. Fixing the first exposed the second. The first problem is that OpenMP lowering of maps in `omp.target` in Flang cannot handle the mapping of a value that doesnt have a defining operation. In other words, a value that is a block argument. This is handled by mapping the value using a `MapInfoOp`. The second problem this fixes is that it adds bounds to `omp.map.info` ops that map `fir.char<k, ?>` types by extracting the length from the corresponding `fir.boxchar`
2025-05-09[Flang][OpenMP] Generate correct present checks for implicit maps of ↵agozillon
optional allocatables (#138210) Currently, we do not generate the appropriate checks to check if an optional allocatable argument is present before accessing relevant components of it, in particular when creating bounds, we must generate a presence check and we must make sure we do not generate/keep an load external to the presence check by utilising the raw address rather than the regular address of the info data structure. Similarly in cases for optional allocatables we must treat them like non-allocatable arguments and generate an intermediate allocation that we can have as a location in memory that we can access later in the lowering without causing segfaults when we perform "mapping" on it, even if the end result is an empty allocatable (basically, we shouldn't explode if someone tries to map a non-present optional, similar to C++ when mapping null data).
2025-04-14[Flang][OpenMP][MLIR] Check for presence of Box type before emitting store ↵agozillon
in MapInfoFinalization pass (#135477) Currently we don't check for the presence of descriptor/BoxTypes before emitting stores which lower to memcpys, the issue with this is that users can have optional arguments, where they don't provide an input, making the argument effectively null. This can still be mapped and this causes issues at the moment as we'll emit a memcpy for function arguments to store to a local variable for certain edge cases, when we perform this memcpy on a null input, we cause a segfault at runtime. The fix to this is to simply create a branch around the store that checks if the data we're copying from is actually present. If it is, we proceed with the store, if it isn't we skip it.
2025-03-20[MLIR][OpenMP] Improve omp.map.info verification (#132066)Sergio Afonso
This patch makes the `map_type` and `map_capture_type` arguments of the `omp.map.info` operation required, which was already an invariant being verified by its users via `verifyMapClause()`. This makes it clearer, as getters no longer return misleading `std::optional` values. Checks for the `mapper_id` argument are moved to a verifier for the operation, rather than being checked by users. Functionally NFC, but not marked as such due to a reordering of arguments in the assembly format of `omp.map.info`.
2025-03-10[flang][OpenMP] Implement HAS_DEVICE_ADDR clause (#128568)Krzysztof Parzyszek
The HAS_DEVICE_ADDR indicates that the object(s) listed exists at an address that is a valid device address. Specifically, `has_device_addr(x)` means that (in C/C++ terms) `&x` is a device address. When entering a target region, `x` does not need to be allocated on the device, or have its contents copied over (in the absence of additional mapping clauses). Passing its address verbatim to the region for use is sufficient, and is the intended goal of the clause. Some Fortran objects use descriptors in their in-memory representation. If `x` had a descriptor, both the descriptor and the contents of `x` would be located in the device memory. However, the descriptors are managed by the compiler, and can be regenerated at various points as needed. The address of the effective descriptor may change, hence it's not safe to pass the address of the descriptor to the target region. Instead, the descriptor itself is always copied, but for objects like `x`, no further mapping takes place (as this keeps the storage pointer in the descriptor unchanged). --------- Co-authored-by: Sergio Afonso <safonsof@amd.com>
2025-03-07[Flang][OpenMP][MLIR] Implement close, present and ompx_hold modifiers for ↵agozillon
Flang maps (#129586) This PR adds an initial implementation for the map modifiers close, present and ompx_hold, primarily just required adding the appropriate map type flags to the map type bits. In the case of ompx_hold it required adding the map type to the OpenMP dialect. Close has a bit of a problem when utilised with the ALWAYS map type on descriptors, so it is likely we'll have to make sure close and always are not applied to the descriptor simultaneously in the future when we apply always to the descriptors to facilitate movement of descriptor information to device for consistency, however, we may find an alternative to this with further investigation. For the moment, it is a TODO/Note to keep track of it.
2025-02-28[flang] update fir.coordinate_of to carry the fields (#127231)jeanPerier
This patch updates fir.coordinate_op to carry the field index as attributes instead of relying on getting it from the fir.field_index operations defining its operands. The rational is that FIR currently has a few operations that require DAGs to be preserved in order to be able to do code generation. This is the case of fir.coordinate_op, which requires its fir.field operand producer to be visible. This makes IR transformation harder/brittle, so I want to update FIR to get rid if this. Codegen/printer/parser of fir.coordinate_of and many tests need to be updated after this change.
2025-02-18[MLIR][OpenMP] Add OMP Mapper field to MapInfoOp (#120994)Akash Banerjee
This patch adds the mapper field to the omp.map.info op. Depends on #117046.
2025-02-18[MLIR][OpenMP] Add Lowering support for OpenMP Declare Mapper directive ↵Akash Banerjee
(#117046) This patch adds HLFIR/FIR lowering support for OpenMP Declare Mapper directive. Depends on #117045.
2025-01-21[flang][OpenMP][OpenACC] remove libEvaluate dependency in passes (#123784)jeanPerier
Move OpenACC/OpenMP helpers from Lower/DirectivesCommon.h that are also used in OpenACC and OpenMP mlir passes into a new Optimizer/Builder/DirectivesCommon.h so that parser and evaluate headers are not included in Optimizer libraries (this both introduce compile-time and link-time pointless overheads). This should fix https://github.com/llvm/llvm-project/issues/123377
2025-01-11[flang] Teach omp-map-info-finalization to reuse descriptor allocas (#122507)macurtis-amd
Internal testing shows improvements in some SPEC HPC benchmarks with this change.
2025-01-03[Flang][OpenMP] Fix allocating arrays with size intrinisic (#119226)agozillon
Attempt to address the following example from causing an assert or ICE: ``` subroutine test(a) implicit none integer :: i real(kind=real64), dimension(:) :: a real(kind=real64), dimension(size(a, 1)) :: b !$omp target map(tofrom: b) do i = 1, 10 b(i) = i end do !$omp end target end subroutine ``` Where we utilise a Fortran intrinsic (size) to calculate the size of allocatable arrays and then map it to device.
2024-12-18Re-apply (#117867): [flang][OpenMP] Implicitly map allocatable record fields ↵Kareem Ergawy
(#120374) This re-applies #117867 with a small fix that hopefully prevents build bot failures. The fix is avoiding `dyn_cast` for the result of `getOperation()`. Instead we can assign the result to `mlir::ModuleOp` directly since the type of the operation is known statically (`OpT` in `OperationPass`).
2024-12-18Revert "[flang][OpenMP] Implicitly map allocatable record fields (#117867)" ↵Kareem Ergawy
(#120360)
2024-12-18[flang][OpenMP] Implicitly map allocatable record fields (#117867)Kareem Ergawy
This is a starting PR to implicitly map allocatable record fields. This PR contains the following changes: 1. Re-purposes some of the utils used in `Lower/OpenMP.cpp` so that these utils work on the `mlir::Value` level rather than the `semantics::Symbol` level. This takes one step towards to enabling MLIR passes to more easily do some lowering themselves (e.g. creating `omp.map.bounds` ops for implicitely caputured data like this PR does). 2. Adds support for implicitely capturing and mapping allocatable fields in record types. There is quite some distant to still cover to have full support for this. I added a number of todos to guide further development. Co-authored-by: Andrew Gozillon <andrew.gozillon@amd.com> Co-authored-by: Andrew Gozillon <andrew.gozillon@amd.com>
2024-11-16[Flang][OpenMP] Derived type explicit allocatable member mapping (#113557)agozillon
This PR is one of 3 in a PR stack, this is the primary change set which seeks to extend the current derived type explicit member mapping support to handle descriptor member mapping at arbitrary levels of nesting. The PR stack seems to do this reasonably (from testing so far) but as you can create quite complex mappings with derived types (in particular when adding allocatable derived types or arrays of allocatable derived types) I imagine there will be hiccups, which I am more than happy to address. There will also be further extensions to this work to handle the implicit auto-magical mapping of descriptor members in derived types and a few other changes planned for the future (with some ideas on optimizing things). The changes in this PR primarily occur in the OpenMP lowering and the OMPMapInfoFinalization pass. In the OpenMP lowering several utility functions were added or extended to support the generation of appropriate intermediate member mappings which are currently required when the parent (or multiple parents) of a mapped member are descriptor types. We need to map the entirety of these types or do a "deep copy" for lack of a better term, where we map both the base address and the descriptor as without the copying of both of these we lack the information in the case of the descriptor to access the member or attach the pointers data to the pointer and in the latter case we require the base address to map the chunk of data. Currently we do not segment descriptor based derived types as we do with regular non-descriptor derived types, we effectively map their entirety in all cases at the moment, I hope to address this at some point in the future as it adds a fair bit of a performance penalty to having nestings of allocatable derived types as an example. The process of mapping all intermediate descriptor members in a members path only occurs if a member has an allocatable or object parent in its symbol path or the member itself is a member or allocatable. This occurs in the createParentSymAndGenIntermediateMaps function, which will also generate the appropriate address for the allocatable member within the derived type to use as a the varPtr field of the map (for intermediate allocatable maps and final allocatable mappings). In this case it's necessary as we can't utilise the usual Fortran::lower functionality such as gatherDataOperandAddrAndBounds without causing issues later in the lowering due to extra allocas being spawned which seem to affect the pointer attachment (at least this is my current assumption, it results in memory access errors on the device due to incorrect map information generation). This is similar to why we do not use the MLIR value generated for this and utilise the original symbol provided when mapping descriptor types external to derived types. Hopefully this can be rectified in the future so this function can be simplified and more closely aligned to the other type mappings. We also make use of fir::CoordinateOp as opposed to the HLFIR version as the HLFIR version doesn't support the appropriate lowering to FIR necessary at the moment, we also cannot use a single CoordinateOp (similarly to a single GEP) as when we index through a descriptor operation (BoxType) we encounter issues later in the lowering, however in either case we need access to intermediate descriptors so individual CoordinateOp's aid this (although, being able to compress them into a smaller amount of CoordinateOp's may simplify the IR and perhaps result in a better end product, something to consider for the future). The other large change area was in the OMPMapInfoFinalization pass, where the pass had to be extended to support the expansion of box types (or multiple nestings of box types) within derived types, or box type derived types. This requires expanding each BoxType mapping from one into two maps and then modifying all of the existing member indices of the overarching parent mapping to account for the addition of these new members alongside adjusting the existing member indices to support the addition of these new maps which extend the original member indices (as a base address of a box type is currently considered a member of the box type at a position of 0 as when lowered to LLVM-IR it's a pointer contained at this position in the descriptor type, however, this means extending mapped children of this expanded descriptor type to additionally incorporate the new member index in the correct location in its own index list). I believe there is a reasonable amount of comments that should aid in understanding this better, alongside the test alterations for the pass. A subset of the changes were also aimed at making some of the utilities for packing and unpacking the DenseIntElementsAttr containing the member indices shareable across the lowering and OMPMapInfoFinalization, this required moving some functions to the Lower/Support/Utils.h header, and transforming the lowering structure containing the member index data into something more similar to the version used in OMPMapInfoFinalization. There we also some other attempts at tidying things up in relation to the member index data generation in the lowering, some of which required creating a logical operator for the OpenMP ID class so it can be utilised as a map key (it simply utilises the symbol address for the moment as ordering isn't particularly important). Otherwise I have added a set of new tests encompassing some of the mappings currently supported by this PR (unfortunately as you can have arbitrary nestings of all shapes and types it's not very feasible to cover them all).
2024-11-14[Flang][OpenMP] Update MapInfoFinalization to use BlockArgs Interface and ↵agozillon
modify use_device_ptr/addr to be order independent (#113919) This patch primarily updates the MapInfoFinalization pass to utilise the BlockArgument interface. It also shuffles newly added arguments the MapInfoFinalization passes to the end of the BlockArg/Relevant MapInfo lists, instead of one prior to the owning descriptor type. During this it was noted that the use_device_ptr/addr handling of target data was a little bit too order dependent so I've attempted to make it less so, as we cannot depend on argument ordering to be the same as Fortran for any future frontends.
2024-09-04[OpenMP]Update use_device_clause lowering (#101703)Akash Banerjee
This patch updates the use_device_ptr and use_device_addr clauses to use the mapInfoOps for lowering. This allows all the types that are handle by the map clauses such as derived types to also be supported by the use_device_clauses. This is patch 1/2 in a series of patches. Co-authored-by: Raghu Maddhipatla raghu.maddhipatla@amd.com
2024-08-23[Flang][OpenMP] Align map clause generation and fix issue with non-shared ↵agozillon
allocations for assumed shape/size descriptor types (#97855) This PR aims to unify the map argument generation behavior across both the implicit capture (captured in a target region) and the explicit capture (process map), currently the varPtr field of the MapInfo for the same variable will be different depending on how it's captured. This PR tries to align that across the generations of MapInfoOp in the OpenMP lowering. Currently, I have opted to utilise the rawInput (input memref to a HLFIR DeclareInfoOp) as opposed to the addr field which includes more information. The side affect of this is that we have to deal with BoxTypes less often, which will result in simpler maps in these cases. The negative side affect of this is that we don't have access to the bounds information through the resulting value, however, I believe the bounds information we require in our case is still appropriately stored in the map bounds, and this seems to be the case from testing so far. The other fix is for cases where we end up with a BoxType argument into a function (certain assumed shape and sizes cases do this) that has no fir.ref wrapping it. As we need the Box to be a reference type to actually utilise the operation to access the base address stored inside and create the correct mappings we currently generate an intermediate allocation in these cases, and then store into it, and utilise this as the map argument, as opposed to the original. However, as we were not sharing the same intermediate allocation across all of the maps for a variable, this resulted in errors in certain cases when detatching/attatching the data e.g. via enter and exit. This PR adjusts this for cases Currently we only maintain tracking of all intermediate allocations for the current function scope, as opposed to module. Primarily as the only case I am aware of that this is required is in cases where we pass certain types of arguments to functions (so I opted to minimize the overhead of the pass for now). It could likely be extended to module scope if required if we find other cases where it's applicable and causing issues.
2024-08-22[flang][NFC] Move OpenMP related passes into a separate directory (#104732)Ivan R. Ivanov
Reapplied with fixed library dependencies for shared lib build
2024-08-21Revert "[flang][NFC] Move OpenMP related passes into a separate directory ↵Ivan Radanov Ivanov
(#104732)" This reverts commit 87eeed1f0ebe57abffde560c25dd9829dc6038f3.
2024-08-21[flang][NFC] Move OpenMP related passes into a separate directory (#104732)Ivan R. Ivanov