summaryrefslogtreecommitdiff
path: root/flang/lib/Optimizer/Transforms/LoopVersioning.cpp
AgeCommit message (Collapse)Author
2025-07-21[mlir][NFC] update `flang/Optimizer/Transforms` create APIs (11/n) (#149915)Maksim Levental
See https://github.com/llvm/llvm-project/pull/147168 for more info.
2025-07-14[flang] Optimize redundant array repacking. (#147881)Slava Zakharin
This patch allows optimizing redundant array repacking, when the source array is statically known to be contiguous. This is part of the implementation plan for the array repacking feature, though, it does not affect any real life use case as long as FIR inlining is not a thing. I experimented with simple cases of FIR inling using `-inline-all`, and I recorded these cases in optimize-array-repacking.fir tests.
2025-05-13[Flang] Add missing dependent dialects to MLIR passes (#139260)Sergio Afonso
This patch updates several passes to include the DLTI dialect, since their use of the `fir::support::getOrSetMLIRDataLayout()` utility function could, in some cases, require this dialect to be loaded in advance. Also, the `CUFComputeSharedMemoryOffsetsAndSize` pass has been updated with a dependency to the GPU dialect, as its invocation to `cuf::getOrCreateGPUModule()` would result in the same kind of error if no other operations or attributes from that dialect were present in the input MLIR module.
2025-05-12[flang] Propagate contiguous attribute through HLFIR. (#138797)Slava Zakharin
This change allows marking more designators producing an opaque box with 'contiguous' attribute, e.g. like in test1 case in flang/test/HLFIR/propagate-contiguous-attribute.fir. This would make isSimplyContiguous() return true for such designators allowing merging hlfir.eval_in_mem with hlfir.assign where the LHS is a contiguous array section. Depends on #139003
2025-03-31[flang] Recognize fir.pack_array in LoopVersioning. (#133191)Slava Zakharin
This change enables LoopVersioning when `fir.pack_array` is met in the def-use chain. It fixes a couple of huge performance regressions caused by enabling `-frepack-arrays`.
2025-02-06[Flang] Move non-common headers to FortranSupport (#124416)Michael Kruse
Move non-common files from FortranCommon to FortranSupport (analogous to LLVMSupport) such that * declarations and definitions that are only used by the Flang compiler, but not by the runtime, are moved to FortranSupport * declarations and definitions that are used by both ("common"), the compiler and the runtime, remain in FortranCommon * generic STL-like/ADT/utility classes and algorithms remain in FortranCommon This allows a for cleaner separation between compiler and runtime components, which are compiled differently. For instance, runtime sources must not use STL's `<optional>` which causes problems with CUDA support. Instead, the surrogate header `flang/Common/optional.h` must be used. This PR fixes this for `fast-int-sel.h`. Declarations in include/Runtime are also used by both, but are header-only. `ISO_Fortran_binding_wrapper.h`, a header used by compiler and runtime, is also moved into FortranCommon.
2025-01-30[Flang][MLIR] Extend DataLayout utilities to have basic GPU Module support ↵agozillon
(#123149) As there is now certain areas where we now have the possibility of having either a ModuleOp or GPUModuleOp and both of these modules can have DataLayout's and we may require utilising the DataLayout utilities in these areas I've taken the liberty of trying to extend them for use with both. Those with more knowledge of how they wish the GPUModuleOp's to interact with their parent ModuleOp's DataLayout may have further alterations they wish to make in the future, but for the moment, it'll simply utilise the basic data layout construction which I believe combines parent and child datalayouts from the ModuleOp and GPUModuleOp. If there is no GPUModuleOp DataLayout it should default to the parent ModuleOp. It's worth noting there is some weirdness if you have two module operations defining builtin dialect DataLayout Entries, it appears the combinatorial functionality for DataLayouts doesn't support the merging of these. This behaviour is useful for areas like: https://github.com/llvm/llvm-project/pull/119585/files#diff-19fc4bcb38829d085e25d601d344bbd85bf7ef749ca359e348f4a7c750eae89dR1412 where we have a crossroads between the two different module operations.
2024-12-23[flang] Enable loop-versioning for slices. (#120344)Slava Zakharin
Loops resulting from array expressions like array(:,i) may be versioned for the unit stride of the innermost dimension, when the initial array is an assumed-shape array (which are contiguous in many Fortran programs). This speeds up facerec for about 12% due to further vectorization of the innermost loop produced for the total SUM reduction.
2024-10-03[flang] replace fir.complex usages with mlir complex (#110850)jeanPerier
Core patch of https://discourse.llvm.org/t/rfc-flang-replace-usages-of-fir-complex-by-mlir-complex-type/82292. After that, the last step is to remove fir.complex from FIR types.
2024-08-27[flang][debug] Support derived types. (#99476)Abid Qadeer
This PR adds initial debug support for derived type. It handles `RecordType` and generates appropriate `DICompositeTypeAttr`. The `TypeInfoOp` is used to get information about the parent and location of the derived type. We use `getTypeSizeAndAlignment` to get the size and alignment of the components of the derived types. This function needed a few changes to be suitable to be used here: 1. The `getTypeSizeAndAlignment` errored out on unsupported type which would not work with incremental way we are building debug support. A new variant of this function has been that returns an std::optional. The original function has been renamed to `getTypeSizeAndAlignmentOrCrash` as it will call `TODO()` for unsupported types. 2. The Character type was returning size of just element and not the whole string which has been fixed. The testcase checks for offsets of the components which had to be hardcoded in the test. So the testcase is currently enabled on x86_64. With this PR in place, this is how the debugging of derived types look like: ``` type :: t_date integer :: year, month, day end type type :: t_address integer :: house_number end type type, extends(t_address) :: t_person character(len=20) name end type type, extends(t_person) :: t_employee type(t_date) :: hired_date real :: monthly_salary end type type(t_employee) :: employee (gdb) p employee $1 = ( t_person = ( t_address = ( house_number = 1 ), name = 'John', ' ' <repeats 16 times> ), hired_date = ( year = 2020, month = 1, day = 20 ), monthly_salary = 3.1400001 ) ```
2024-04-28Reapply "[mlir] Mark `isa/dyn_cast/cast/...` member functions depreca… ↵Christian Sigg
(#90406) …ted. (#89998)" (#90250) This partially reverts commit 7aedd7dc754c74a49fe84ed2640e269c25414087. This change removes calls to the deprecated member functions. It does not mark the functions deprecated yet and does not disable the deprecation warning in TypeSwitch. This seems to cause problems with MSVC.
2024-04-26Revert "[mlir] Mark `isa/dyn_cast/cast/...` member functions deprecated. ↵dyung
(#89998)" (#90250) This reverts commit 950b7ce0b88318f9099e9a7c9817d224ebdc6337. This change is causing build failures on a bot https://lab.llvm.org/buildbot/#/builders/216/builds/38157
2024-04-26[mlir] Mark `isa/dyn_cast/cast/...` member functions deprecated. (#89998)Christian Sigg
See https://mlir.llvm.org/deprecation and https://discourse.llvm.org/t/preferred-casting-style-going-forward.
2024-04-26[flang][NFC] Use tablegen to create LoopVersioning constructor (#90037)Tom Eccles
The pass is currently defined as only considering function arguments as candidates for the optimization. I would prefer to generalise the pass for other top level operations only when there is a concrete use case before making too many assumptions about the current set of top level operations. Therefore I have not adapted this pass to run on all top level operations.
2024-01-29[flang] Use DataLayout for computing type size in LoopVersioning. (#79778)Slava Zakharin
The existing type size computation in LoopVersioning does not work for REAL*10, because the compute element size is 10 bytes, which violates the power-of-two assertion. We'd better use the DataLayout for computing the storage size of each element of an array of the given type.
2024-01-20[Flang] Fix for replacing loop uses in LoopVersioning pass (#77899)David Green
The added test case has a loop that is versioned, which has a use of the loop in an if block after the loop. The current code replaces all uses of the loop with the new version If, but only if the parent blocks match. As far as I can see it should be safe to replace all the uses, then construct the result for the If with op.op.
2024-01-15[Flang] Clean up LoopVersioning LLVM_DEBUG blocks. NFC (#77818)David Green
Just a little trick to put LLVM_DEBUG blocks into separate { } scopes, so they clang-format better.
2023-11-17[flang][NFC] Fix typoValentin Clement
2023-10-12[flang]Check for dominance in loop versioning (#68797)Mats Petersson
This avoids trying to version loops that can't be versioned, and thus avoids hitting an assert. Co-authored with Slava Zakharin (who provided the test-code).
2023-09-08[flang] Fixed LoopVersioning for array slices. (#65703)Slava Zakharin
The first test case added in the LIT test demonstrates the problem. Even though we did not consider the inner loop as a candidate for the transformation due to the array_coor with a slice, we decided to version the outer loop for the same function argument. During the cloning of the outer loop we dropped the slicing completely producing invalid code. I restructured the code so that we record all arg uses that cannot be transformed (regardless of the reason), and then fixup the usage information across the loop nests. I also noticed that we may generate redundant contiguity checks for the inner loops, so I fixed it since it was easy with the new way of keeping the usage data.
2023-09-04[flang][LoopVersioning] support fir.array_coorTom Eccles
This is the last piece required for the loop versioning patch to work on code lowered via HLFIR. With this patch, HLFIR performance on spec2017 roms is now similar to the FIR lowering. Adding support for fir.array_coor means that many more loops will be versioned, even in the FIR lowering. So far as I have seen, these do not seem to have an impact on performance for the benchmarks I tried, but I expect it would speed up some programs, if the loop being versioned happened to be the hot code. The main difference between fir.array_coor and fir.coordinate_of is that fir.coordinate_of uses zero-based indices, whereas fir.array_coor uses the indices as specified in the Fortran program (starting from 1 by default, but also supporting non default lower bounds). I opted to transform fir.array_coor operations into fir.coordinate_of operations because this allows both to share the same offset calculation logic. The tricky bit of this patch is getting the correct lower bounds for the array operand to subtract from the fir.array_coor indices to get a zero-based indices. So far as I can tell, the FIR lowering will always provide lower bounds (shift) information in the shape operand to the fir.array_coor when non-default lower bounds are used. If none is given, I originally tried falling back to reading lower bounds from the box, but this led to misscompilation in SPEC2017 cam4. Therefore the pass instead assumes that if it can't already find an SSA value for the shift information, the default lower bound (1) should be used. A suspect the incorrect lower bounds in the box for the FIR lowering was already a known issue (see https://reviews.llvm.org/D158119). Differential Revision: https://reviews.llvm.org/D158597
2023-08-25[flang] Skip OPTIONAL arguments in LoopVersioning.Slava Zakharin
This patch fixes multiple tests failing with segfault due to accessing absent argument box before the loop versioning check. The absent arguments might be treated as contiguous for the purpose of loop versioning, but this is not done in this patch. Reviewed By: PeteSteinfeld Differential Revision: https://reviews.llvm.org/D158800
2023-08-23[flang][LoopVersioning] support reboxed operandsTom Eccles
Since https://reviews.llvm.org/D158119, many boxes lowered via HLFIR are reboxed with better lower bounds information after they are declared. For the loop versioning pass to support FIR lowered via HLFIR, it needs to dereference fir.rebox operations to figure out that the variable was a function argument. I decided to modify the existing dereferencing of fir.declare so that the declared/reboxed value is used in the versioned loop instead of the function argument. This makes it easier for the improved lower bounds information to be accessed. In doing this, I changed ArgInfo to store ArgInfo::arg by value instead of by pointer because mlir::Value has value-type semantics. Differential Revision: https://reviews.llvm.org/D158408
2023-08-22[flang] Make ISO_Fortran_binding.h a standalone header again.Slava Zakharin
This implements the proposal from https://discourse.llvm.org/t/adding-flang-specific-header-files-to-clang/72442/6 Since ISO_Fortran_binding.h is supposed to be included from users' C/C++ codes, it would better have no dependencies on other header files. Reviewed By: PeteSteinfeld Differential Revision: https://reviews.llvm.org/D158549
2023-08-18[flang][LoopVersioning] support fir.declareTom Eccles
When FIR comes from HLFIR, there will be a fir.declare operation between the source and the usage of each source variable (and some temporary allocations). This pass needs to be able to follow these so that it can still transform loops when HLFIR is used, otherwise it mistakenly assumes these values are not function arguments. More work is needed after this patch to fully support HLFIR, because the generated code tends to use fir.array_coor instead of fir.coordinate_of. Differential Revision: https://reviews.llvm.org/D157964
2023-06-05[flang] Store KindMapping by value in FirOpBuilderTom Eccles
Previously only a constant reference was stored in the FirOpBuilder. However, a lot of code was merged using FirOpBuilder builder{rewriter, getKindMapping(mod)}; This is incorrect because the KindMapping returned will go out of scope as soon as FirOpBuilder's constructor had run. This led to an infinite loop running some tests using HLFIR (because the stack space containing the kind mapping was re-used and corrupted). One solution would have just been to fix the incorrect call sites, however, as a large number of these had already made it past review, I decided to instead change FirOpBuilder to store its own copy of the KindMapping. This is not costly because nearly every time we construct a KindMapping is exclusively to construct a FirOpBuilder. To make this common pattern simpler, I added a new constructor to FirOpBuilder which calls getKindMapping(). Differential Revision: https://reviews.llvm.org/D151881
2023-06-01[FLANG] Change loop versioning to use shift instead of divideMats Petersson
Despite me being convinced that the use of divide didn't produce any divide instructions, it does in fact add more instructions than using a plain shift operation. This patch simply changes the divide to a shift right, with an assert to check that the "divisor" is a power of two. Reviewed By: kiranchandramohan, tblah Differential Revision: https://reviews.llvm.org/D151880
2023-05-30[FLANG] Support all arrays for LoopVersioningMats Petersson
This patch makes more than 2D arrays work, with a fix for the way that loop index is calculated. Removing the restriction of number of dimensions. This also changes the way that the actual index is calculated, such that the stride is used rather than the extent of the previous dimension. Some tests failed without fixing this - this was likely a latent bug in the 2D version too, but found in a test using 3D arrays, so wouldn't have been found with 2D only. This introduces a division on the index calculation - however it should be a nice and constant value allowing a shift to be used to actually divide - or otherwise removed by using other methods to calculate the result. In analysing code generated with optimisation at -O3, there are no divides produced. Some minor refactoring to avoid repeatedly asking for the "rank" of the array being worked on. This improves some of the SPEC-2017 ROMS code, in the same way as the limited 2D array improvements - less overhead spent calculating array indices in the inner-most loop and better use of vector-instructions. Reviewed By: kiranchandramohan Differential Revision: https://reviews.llvm.org/D151140
2023-04-18Add loop-versioning pass to improve unit-strideMats Petersson
Introduce conditional code to identify stride of "one element", and simplify the array accesses for that case. This allows better loop performance in various benchmarks. Reviewed By: tblah, kiranchandramohan Differential Revision: https://reviews.llvm.org/D141306