summaryrefslogtreecommitdiff
path: root/mlir/lib/Interfaces/ControlFlowInterfaces.cpp
AgeCommit message (Collapse)Author
2025-11-05[mlir] [NFC] Remove stray debug statement (#166696)Jeremy Kun
Co-authored-by: Jeremy Kun <j2kun@users.noreply.github.com>
2025-10-28 [MLIR] Revamp RegionBranchOpInterface (#165429)Mehdi Amini
This is still somehow a WIP, we have some issues with this interface that are not trivial to solve. This patch tries to make the concepts of RegionBranchPoint and RegionSuccessor more robust and aligned with their definition: - A `RegionBranchPoint` is either the parent (`RegionBranchOpInterface`) op or a `RegionBranchTerminatorOpInterface` operation in a nested region. - A `RegionSuccessor` is either one of the nested region or the parent `RegionBranchOpInterface` Some new methods with reasonnable default implementation are added to help resolving the flow of values across the RegionBranchOpInterface. It is still not trivial in the current state to walk the def-use chain backward with this interface. For example when you have the 3rd block argument in the entry block of a for-loop, finding the matching operands requires to know about the hidden loop iterator block argument and where the iterargs start. The API is designed around forward-tracking of the chain unfortunately. Try to reland #161575 ; I suspect a buildbot incremental build issue.
2025-10-28Revert " [MLIR] Revamp RegionBranchOpInterface " (#165356)Mehdi Amini
Reverts llvm/llvm-project#161575 Broke Windows on ARM buildbot build, needs investigations.
2025-10-28 [MLIR] Revamp RegionBranchOpInterface (#161575)Mehdi Amini
This is still somehow a WIP, we have some issues with this interface that are not trivial to solve. This patch tries to make the concepts of RegionBranchPoint and RegionSuccessor more robust and aligned with their definition: - A `RegionBranchPoint` is either the parent (`RegionBranchOpInterface`) op or a `RegionBranchTerminatorOpInterface` operation in a nested region. - A `RegionSuccessor` is either one of the nested region or the parent `RegionBranchOpInterface` Some new methods with reasonnable default implementation are added to help resolving the flow of values across the RegionBranchOpInterface. It is still not trivial in the current state to walk the def-use chain backward with this interface. For example when you have the 3rd block argument in the entry block of a for-loop, finding the matching operands requires to know about the hidden loop iterator block argument and where the iterargs start. The API is designed around forward-tracking of the chain unfortunately.
2025-07-15[mlir] Remove unused includes (NFC) (#148872)Kazu Hirata
These are identified by misc-include-cleaner. I've filtered out those that break builds. Also, I'm staying away from llvm-config.h, config.h, and Compiler.h, which likely cause platform- or compiler-specific build failures.
2025-07-14[MLIR][Interfaces] Remove negative branch weight verifier (#148234)Christian Ulmann
This commit removes the verifier that checked if branch weights are negative. This check was too strict because weights are interpreted as unsigned integers. This showed up when running the verifier on LLVM dialect modules that were imported from LLVM IR.
2025-06-17[mlir][flang] Added Weighted[Region]BranchOpInterface's. (#142079)Slava Zakharin
The new interfaces provide getters and setters for the weight information about the branches of BranchOpInterface and RegionBranchOpInterface operations. These interfaces are done the same way as LLVM dialect's BranchWeightOpInterface. The plan is to produce this information in Flang, e.g. mark most probably "cold" code as such and allow LLVM to order basic blocks accordingly. An example of such a code is copy loops generated for arrays repacking - we can mark it as "cold" assuming that the copy will not happen dynamically. If the copy actually happens the overhead of the copy is probably high enough so that we may not care about the little overhead of jumping to the "cold" code and fetching it.
2025-04-22[mlir] Avoid doublespace in error (NFC). (#136560)Jacques Pienaar
This was resulting in 2 spaces in the error message.
2024-01-07[mlir][Interfaces][NFC] Move region loop detection to ↵Matthias Springer
`RegionBranchOpInterface` (#77090) `BufferPlacementTransformationBase::isLoop` checks if there a loop in the region branching graph of an operation. This algorithm is similar to `isRegionReachable` in the `RegionBranchOpInterface`. To avoid duplicate code, `isRegionReachable` is generalized, so that it can be used to detect region loops. A helper function `RegionBranchOpInterface::hasLoop` is added. This change also turns a recursive implementation into an iterative one, which is the preferred implementation strategy in LLVM. Also move the `isLoop` to `BufferOptimizations.cpp`, so that we can gradually retire `BufferPlacementTransformationBase`. (This is so that proper error handling can be added to `BufferViewFlowAnalysis`.)
2024-01-04[mlir][RegionBranchOpInterface] explicitly check for existance of block ↵Maksim Levental
terminator (#76831)
2023-09-21[mlir][Interfaces][NFC] Better documentation for `RegionBranchOpInterface` ↵Matthias Springer
(#66920) Update outdated documentation and add an example.
2023-08-30Reland "[mlir] Use a type for representing branch points in ↵Markus Böck
`RegionBranchOpInterface`" This reverts commit b26bb30b467b996c9786e3bd426c07684d84d406.
2023-08-29Revert "[mlir] Use a type for representing branch points in ↵Markus Böck
`RegionBranchOpInterface`" This reverts commit 024f562da67180b7be1663048c960b26c2cc16f8. Forgot to update flang
2023-08-29[mlir] Use a type for representing branch points in `RegionBranchOpInterface`Markus Böck
The current implementation is not very ergonomic or descriptive: It uses `std::optional<unsigned>` where `std::nullopt` represents the parent op and `unsigned` is the region number. This doesn't give us any useful methods specific to region control flow and makes the code fragile to changes due to now taking the region number into account. This patch introduces a new type called `RegionBranchPoint`, replacing all uses of `std::optional<unsigned>` in the interface. It can be implicitly constructed from a region or a `RegionSuccessor`, can be compared with a region to check whether the branch point is branching from the parent, adds `isParent` to check whether we are coming from a parent op and adds `RegionSuccessor::parent` as a descriptive way to indicate branching from the parent. Differential Revision: https://reviews.llvm.org/D159116
2023-08-10[mlir] Fix verifier of `RegionBranchOpInterface`Markus Böck
The verifier incorrectly passed the region number of the predecessor region instead of the successor region to `getSuccessorOperands`. This went unnoticed since all upstream `RegionBranchTerminatorOpInterface` implementations did not make use of the `index` parameter. Adding an assert to e.g. `scf.condition` to make sure the index is valid or adding a region terminator that passes different operands to different successors immediately causes the verifier to fail as it suddenly gets incorrect types. This patch fixes the implementation to correctly pass the successor region index. Differential Revision: https://reviews.llvm.org/D157507
2023-08-10[mlir] Revamp `RegionBranchOpInterface` successor mechanismMarkus Böck
The `RegionBranchOpInterface` had a few fundamental issues caused by the API design of `getSuccessorRegions`. It always required passing values for the `operands` parameter. This is problematic as the operands parameter actually changes meaning depending on which predecessor `index` is referring to. If coming from a region, you'd have to find a `RegionBranchTerminatorOpInterface` in that region, get its operand count, and then create a `SmallVector` of that size. This is not only inconvenient, but also error-prone, which has lead to a bug in the implementation of a previously existing `getSuccessorRegions` overload. Additionally, this made the method dual-use, trying to serve two different use-cases: 1) Trying to determine possible control flow edges between regions and 2) Trying to determine the region being branched to based on constant operands. This patch fixes these issues by changing the interface methods and adding new ones: * The `operands` argument of `getSuccessorRegions` has been removed. The method is now only responsible for returning possible control flow edges between regions. * An optional `getEntrySuccessorRegions` method has been added. This is used to determine which regions are branched to from the parent op based on constant operands of the parent op. By default, it calls `getSuccessorRegions`. This is analogous to `getSuccessorForOperands` from `BranchOpInterface`. * Add `getSuccessorRegions` to `RegionBranchTerminatorOpInterface`. This is used to get the possible successors of the terminator based on constant operands. By default, it calls the containing `RegionBranchOpInterface`s `getSuccessorRegions` method. * `getSuccessorEntryOperands` was renamed to `getEntrySuccessorOperands` for consistency. Differential Revision: https://reviews.llvm.org/D157506
2023-08-08[mlir][NFC] Make `ReturnLike` trait imply `RegionBranchTerminatorOpInterface`Markus Böck
This implication was already done de-facto and there were plenty of users and wrapper functions specifically used to handle the "return-like or RegionBranchTerminatorOpInterface" case. These simply existed due to up until recently missing features in ODS. With the new capabilities of traits, we can make `ReturnLike` imply `RegionBranchTerminatorOpInterface` and auto generate proper definitions for its methods. Various occurrences and wrapper methods used for `isa<RegionBranchTerminatorOpInterface>() || hasTrait<ReturnLike>()` have all been removed. Differential Revision: https://reviews.llvm.org/D157402
2022-12-29[mlir] NFC: work around gcc-aarch64 v8.3 compilation issue in ↵Christian Sigg
getRegionBranchSuccessorOperands implementation. https://reviews.llvm.org/rG25671db3d343 didn't quite do it because the underlying issue was that the specific compiler chokes on the second standard conversion sequence after the user-defined `MutableOperandRange::operator OperandRange() const` conversion (see https://en.cppreference.com/w/cpp/language/implicit_conversion).
2022-12-28[mlir] NFC: work around gcc-aarch64 v8.3 compilation issue in ↵Christian Sigg
getRegionBranchSuccessorOperands implementation.
2022-12-17mlir/tblgen: use std::optional in generationRamkumar Ramachandra
This is part of an effort to migrate from llvm::Optional to std::optional. This patch changes the way mlir-tblgen generates .inc files, and modifies tests and documentation appropriately. It is a "no compromises" patch, and doesn't leave the user with an unpleasant mix of llvm::Optional and std::optional. A non-trivial change has been made to ControlFlowInterfaces to split one constructor into two, relating to a build failure on Windows. See also: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716 Signed-off-by: Ramkumar Ramachandra <r@artagnon.com> Differential Revision: https://reviews.llvm.org/D138934
2022-12-04[mlir] Use std::nullopt instead of None in comments (NFC)Kazu Hirata
This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-03[mlir] Use std::nullopt instead of None (NFC)Kazu Hirata
This patch mechanically replaces None with std::nullopt where the compiler would warn if None were deprecated. The intent is to reduce the amount of manual work required in migrating from Optional to std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-10-17[mlir] Remove assert from RegionBranchOpInterface verifierJeff Niu
This assert is erroneous because an op implementing `RegionBranchOpInterface` can have variadic regions and in some cases have zero regions, in which case the only possible control flow is branching from the parent op to itself. Reviewed By: rriddle, jpienaar Differential Revision: https://reviews.llvm.org/D136052
2022-07-14[mlir] Use value instead of getValue (NFC)Kazu Hirata
2022-07-13[mlir] Use has_value instead of hasValue (NFC)Kazu Hirata
2022-06-25Revert "Don't use Optional::hasValue (NFC)"Kazu Hirata
This reverts commit aa8feeefd3ac6c78ee8f67bf033976fc7d68bc6d.
2022-06-25Don't use Optional::hasValue (NFC)Kazu Hirata
2022-06-13[mlir] Support getSuccessorInputs from parent opMogball
Ops that implement `RegionBranchOpInterface` are allowed to indicate that they can branch back to themselves in `getSuccessorRegions`, but there is no API that allows them to specify the forwarded operands. This patch enables that by changing `getSuccessorEntryOperands` to accept `None`. Fixes #54928 Reviewed By: rriddle Differential Revision: https://reviews.llvm.org/D127239
2022-06-08[mlir] Fix handling of some region branch terminator successorsMogball
When `RegionBranchOpInterface::getSuccessorRegions` is called for anything other than the parent op, it expects the operands of the terminator of the source region to be passed, not the operands of the parent op. This was not always respected. This fixes a bug in integer range inference and ForwardDataFlowSolver and changes `scf.while` to allow narrowing of successors using constant inputs. Fixes #55873 Reviewed By: mehdi_amini, krzysz00 Differential Revision: https://reviews.llvm.org/D127261
2022-04-19Apply clang-tidy fixes for performance-unnecessary-value-param in ↵Mehdi Amini
ControlFlowInterfaces.cpp (NFC)
2022-04-19[mlir][interfaces] Fix infinite loop in insideMutuallyExclusiveRegionsMatthias Springer
This function was missing a termination condition.
2022-04-19[mlir][interfaces] Add helpers for detecting recursive regionsMatthias Springer
Add helper functions to check if an op may be executed multiple times based on RegionBranchOpInterface. Differential Revision: https://reviews.llvm.org/D123789
2022-04-08[mlir] Add support for operation-produced successor arguments in ↵Markus Böck
BranchOpInterface This patch revamps the BranchOpInterface a bit and allows a proper implementation of what was previously `getMutableSuccessorOperands` for operations, which internally produce arguments to some of the block arguments. A motivating example for this would be an invoke op with a error handling path: ``` invoke %function(%0) label ^success ^error(%1 : i32) ^error(%e: !error, %arg0 : i32): ... ``` The advantages of this are that any users of `BranchOpInterface` can still argue over remaining block argument operands (such as `%1` in the example above), as well as make use of the modifying capabilities to add more operands, erase an operand etc. The way this patch implements that functionality is via a new class called `SuccessorOperands`, which is now returned by `getSuccessorOperands`. It basically contains an `unsigned` denoting how many operator produced operands exist, as well as a `MutableOperandRange`, which are the usual forwarded operands we are used to. The produced operands are assumed to the first few block arguments, followed by the forwarded operands afterwards. The role of `SuccessorOperands` is to provide various utility functions to modify and query the successor arguments from a `BranchOpInterface`. Differential Revision: https://reviews.llvm.org/D123062
2022-03-04[mlir] Region/BranchOpInterface: Allow implicit type conversions along ↵Mogball
control-flow edges RegionBranchOpInterface and BranchOpInterface are allowed to make implicit type conversions along control-flow edges. In effect, this adds an interface method, `areTypesCompatible`, to both interfaces, which should return whether the types of corresponding successor operands and block arguments are compatible. Users of the interfaces, here on forth, must be aware that types may mismatch, although current users (in MLIR core), are not affected by this change. By default, type equality is used. `async.execute` already has unequal types along control-flow edges (`!async.value<f32>` vs. `f32`), but it opted out of calling `RegionBranchOpInterface::verifyTypes` in its verifier. That method has now been removed and `RegionBranchOpInterface` will verify types along control edges by default in its verifier. Reviewed By: rriddle Differential Revision: https://reviews.llvm.org/D120790
2022-01-14[mlir] Remove getNumberOfExecutions from RegionBranchOpInterfaceEugene Zhulenev
`getNumRegionInvocations` was originally added for the async reference counting, but turned out to be not useful, and currently is not used anywhere (couldn't find any uses in public github repos). Removing dead code. Reviewed By: Mogball, mehdi_amini Differential Revision: https://reviews.llvm.org/D117347
2022-01-02Apply clang-tidy fixes for performance-for-range-copy to MLIR (NFC)Mehdi Amini
2021-11-25[mlir][interfaces] Add insideMutuallyExclusiveRegions helperMatthias Springer
Add a helper function to ControlFlowInterfaces for checking if two ops are in mutually exclusive regions according to RegionBranchOpInterface. Utilize this new helper in Linalg ComprehensiveBufferize. This makes the analysis independent of the SCF dialect and generalizes it to other ops that implement RegionBranchOpInterface. Differential Revision: https://reviews.llvm.org/D114220
2021-07-26[mlir] Added new RegionBranchTerminatorOpInterface and adapted uses of ↵Marcel Koester
hasTrait<ReturnLike>. This CL adds a new RegionBranchTerminatorOpInterface to query information about operands that can be passed to successor regions. Similar to the BranchOpInterface, it allows to freely define the involved operands. However, in contrast to the BranchOpInterface, it expects an additional region number to distinguish between various use cases which might require different operands passed to different regions. Moreover, we added new utility functions (namely getMutableRegionBranchSuccessorOperands and getRegionBranchSuccessorOperands) to query (mutable) operand ranges for operations equiped with the ReturnLike trait and/or implementing the newly added interface. This simplifies reasoning about terminators in the scope of the nested regions. We also adjusted the SCF.ConditionOp to benefit from the newly added capabilities. Differential Revision: https://reviews.llvm.org/D105018
2020-12-03[mlir][Types][NFC] Move all of the builtin Type classes to BuiltinTypes.hRiver Riddle
This is part of a larger refactoring the better congregates the builtin structures under the BuiltinDialect. This also removes the problematic "standard" naming that clashes with the "standard" dialect, which is not defined within IR/. A temporary forward is placed in StandardTypes.h to allow time for downstream users to replaced references. Differential Revision: https://reviews.llvm.org/D92435
2020-11-11[mlir] Add NumberOfExecutions analysis + update RegionBranchOpInterface ↵Eugene Zhulenev
interface to query number of region invocations Implements RFC discussed in: https://llvm.discourse.group/t/rfc-operationinstancesinterface-or-any-better-name/2158/10 Reviewed By: silvas, ftynse, rriddle Differential Revision: https://reviews.llvm.org/D90922
2020-11-04[mlir] Add a generic while/do-while loop to the SCF dialectAlex Zinenko
The new construct represents a generic loop with two regions: one executed before the loop condition is verifier and another after that. This construct can be used to express both a "while" loop and a "do-while" loop, depending on where the main payload is located. It is intended as an intermediate abstraction for lowering, which will be added later. This form is relatively easy to target from higher-level abstractions and supports transformations such as loop rotation and LICM. Differential Revision: https://reviews.llvm.org/D90255
2020-10-29[mlir] NFC: fix trivial typosKazuaki Ishizaki
fix typos in comments and documents Reviewed By: jpienaar Differential Revision: https://reviews.llvm.org/D90089
2020-09-09Wordsmith RegionBranchOpInterface verification errorsSean Silva
I was having a lot of trouble parsing the messages. In particular, the messages like: ``` <stdin>:3:8: error: 'scf.if' op along control flow edge from Region #0 to scf.if source #1 type '!npcomprt.tensor' should match input #1 type 'tensor<?xindex>' ``` In particular, one thing that kept catching me was parsing the "to scf.if source #1 type" as one thing, but really it is "to parent results: source type #1". Differential Revision: https://reviews.llvm.org/D87334
2020-07-15[MLIR] Add type checking capability to RegionBranchOpInterfaceRahul Joshi
- Add function `verifyTypes` that Op's can call to do type checking verification along the control flow edges described the Op's RegionBranchOpInterface. - We cannot rely on the verify methods on the OpInterface because the interface functions assume valid Ops, so they may crash if invoked on unverified Ops. (For example, scf.for getSuccessorRegions() calls getRegionIterArgs(), which dereferences getBody() block. If the scf.for is invalid with no body, this can lead to a segfault). `verifyTypes` can be called post op-verification to avoid this. Differential Revision: https://reviews.llvm.org/D82829
2020-04-29[mlir] Simplify BranchOpInterface by using MutableOperandRangeRiver Riddle
This range allows for performing many different operations on successor operands, including erasing/adding/setting. This removes the need for the explicit canEraseSuccessorOperand and eraseSuccessorOperand methods. Differential Revision: https://reviews.llvm.org/D79077
2020-03-10[mlir][NFC] Move the operation interfaces out of Analysis/ and into a new ↵River Riddle
Interfaces/ directory. The interfaces themselves aren't really analyses, they may be used by analyses though. Having them in Analysis can also create cyclic dependencies if an analysis depends on a specific dialect, that also provides one of the interfaces. Differential Revision: https://reviews.llvm.org/D75867