summaryrefslogtreecommitdiff
path: root/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
AgeCommit message (Collapse)Author
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-09-12[MLIR] Avoid resolving callable outside the analysis scope in ↵Mehdi Amini
DeadCodeAnalysis (#155088) We are using the symbol table machinery to lookup for a callable, but when the analysis scope if a function, such lookup will resolve outside of the scope. This can lead to race-condition issues since other passes may operate in parallel on the sibling functions. The callable would be discarded right after the lookup (we check the analysis scope), so avoiding the lookup is NFC. For the DataFlow solver, we're looking at the top-level operation, and if it isn't a SymbolTable we disable the interprocedural optimization in the solver config directly. This strategy isn't NFC but seems reasonnable and does not encounter any change in behavior in practice in tree. Fix #154948
2025-08-18[MLIR] Fix Liveness analysis handling of unreachable code (#153973)Mehdi Amini
This patch is forcing all values to be initialized by the LivenessAnalysis, even in dead blocks. The dataflow framework will skip visiting values when its already knows that a block is dynamically unreachable, so this requires specific handling. Downstream code could consider that the absence of liveness is the same a "dead". However as the code is mutated, new value can be introduced, and a transformation like "RemoveDeadValue" must conservatively consider that the absence of liveness information meant that we weren't sure if a value was dead (it could be a newly introduced value. Fixes #153906
2025-07-01[mlir] Remove unused includes (NFC) (#146467)Kazu Hirata
2025-06-04[mlir] NFC: Add data flow analysis extension points (#142549)Vadim Curcă
This commit introduces `visitCallOperation` and `visitCallableOperation` extension points in the sparse data flow analysis framework. This allows, for example, to make the analysis less conservative, without a lot of code duplication, propagating information even if not all the call or return sites are known.
2024-12-14[DataFlow] Migrate away from PointerUnion::{is,get} (NFC) (#119950)Kazu Hirata
Note that PointerUnion::{is,get} have been soft deprecated in PointerUnion.h: // FIXME: Replace the uses of is(), get() and dyn_cast() with // isa<T>, cast<T> and the llvm::dyn_cast<T> I'm not touching PointerUnion::dyn_cast for now because it's a bit complicated; we could blindly migrate it to dyn_cast_if_present, but we should probably use dyn_cast when the operand is known to be non-null.
2024-10-11[mlir] [dataflow] unify semantics of program point (#110344)donald chen
The concept of a 'program point' in the original data flow framework is ambiguous. It can refer to either an operation or a block itself. This representation has different interpretations in forward and backward data-flow analysis. In forward data-flow analysis, the program point of an operation represents the state after the operation, while in backward data flow analysis, it represents the state before the operation. When using forward or backward data-flow analysis, it is crucial to carefully handle this distinction to ensure correctness. This patch refactors the definition of program point, unifying the interpretation of program points in both forward and backward data-flow analysis. How to integrate this patch? For dense forward data-flow analysis and other analysis (except dense backward data-flow analysis), the program point corresponding to the original operation can be obtained by `getProgramPointAfter(op)`, and the program point corresponding to the original block can be obtained by `getProgramPointBefore(block)`. For dense backward data-flow analysis, the program point corresponding to the original operation can be obtained by `getProgramPointBefore(op)`, and the program point corresponding to the original block can be obtained by `getProgramPointAfter(block)`. NOTE: If you need to get the lattice of other data-flow analyses in dense backward data-flow analysis, you should still use the dense forward data-flow approach. For example, to get the Executable state of a block in dense backward data-flow analysis and add the dependency of the current operation, you should write: ``getOrCreateFor<Executable>(getProgramPointBefore(op), getProgramPointBefore(block))`` In case above, we use getProgramPointBefore(op) because the analysis we rely on is dense backward data-flow, and we use getProgramPointBefore(block) because the lattice we query is the result of a non-dense backward data flow computation. related dsscussion: https://discourse.llvm.org/t/rfc-unify-the-semantics-of-program-points/80671/8 corresponding PSA: https://discourse.llvm.org/t/psa-program-point-semantics-change/81479
2024-09-10Reland [MLIR] Make resolveCallable customizable in CallOpInterface (#107989)Henrich Lauko
Relands #100361 with fixed dependencies.
2024-09-10Revert "[MLIR] Make `resolveCallable` customizable in `CallOpInterface`" ↵Matthias Springer
(#107984) Reverts llvm/llvm-project#100361 This commit caused some linker errors. (Missing `MLIRCallInterfaces` dependency.)
2024-09-10[MLIR] Make `resolveCallable` customizable in `CallOpInterface` (#100361)Henrich Lauko
Allow customization of the `resolveCallable` method in the `CallOpInterface`. This change allows for operations implementing this interface to provide their own logic for resolving callables. - Introduce the `resolveCallable` method, which does not include the optional symbol table parameter. This method replaces the previously existing extra class declaration `resolveCallable`. - Introduce the `resolveCallableInTable` method, which incorporates the symbol table parameter. This method replaces the previous extra class declaration `resolveCallable` that used the optional symbol table parameter.
2024-08-25[mlir] [dataflow] Refactoring the definition of program points in data flow ↵donald chen
analysis (#105656) This patch distinguishes between program points and lattice anchors in data flow analysis, where lattice anchors represent locations where a lattice can be attached, while program points denote points in program execution. Related discussions: https://discourse.llvm.org/t/rfc-unify-the-semantics-of-program-points/80671/8
2024-08-22[mlir][dataflow] Propagate errors from `visitOperation` (#105448)Ivan Butygin
Base `DataFlowAnalysis::visit` returns `LogicalResult`, but wrappers's Sparse/Dense/Forward/Backward `visitOperation` doesn't. Sometimes it's needed to abort solver early if some unrecoverable condition detected inside analysis. Update `visitOperation` to return `LogicalResult` and propagate it to `solver.initializeAndRun()`. Only `visitOperation` is updated for now, it's possible to update other hooks like `visitNonControlFlowArguments`, bit it's not needed immediately and let's keep this PR small. Hijacked `UnderlyingValueAnalysis` test analysis to test it.
2024-07-02mlir/LogicalResult: move into llvm (#97309)Ramkumar Ramachandra
This patch is part of a project to move the Presburger library into LLVM.
2023-12-18[mlir] support non-interprocedural dataflow analyses (#75583)Oleksandr "Alex" Zinenko
The core implementation of the dataflow anlysis framework is interpocedural by design. While this offers better analysis precision, it also comes with additional cost as it takes longer for the analysis to reach the fixpoint state. Add a configuration mechanism to the dataflow solver to control whether it operates inteprocedurally or not to offer clients a choice. As a positive side effect, this change also adds hooks for explicitly processing external/opaque function calls in the dataflow analyses, e.g., based off of attributes present in the the function declaration or call operation such as alias scopes and modref available in the LLVM dialect. This change should not affect existing analyses and the default solver configuration remains interprocedural. Co-authored-by: Jacob Peng <jacobmpeng@gmail.com>
2023-10-28Apply clang-tidy fixes for misc-include-cleaner in SparseAnalysis.cpp (NFC)Mehdi Amini
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-11[MLIR][analysis] Fix call op handling in sparse backward dataflowSrishti Srivastava
Currently, data in `AbstractSparseBackwardDataFlowAnalysis` is considered to flow one-to-one, in order, from the operands of an op implementing `CallOpInterface` to the arguments of the function it is calling. This understanding of the data flow is inaccurate. The operands of such an op that forward to the function arguments are obtained using a method provided by `CallOpInterface` called `getArgOperands()`. This commit fixes this bug by using `getArgOperands()` instead of `getOperands()` to get the mapping from operands to function arguments because not all operands necessarily forward to the function arguments and even if they do, they don't necessarily have to be in the order in which they appear in the op. The operands that don't get forwarded are handled by the newly introduced `visitCallOperand()` function, which works analogous to the `visitBranchOperand()` function. This fix is also propagated to liveness analysis that earlier relied on this incorrect implementation of the sparse backward dataflow analysis framework and corrects some incorrect assumptions made in it. Extra cleanup: Improved a comment and removed an unnecessary code line. Signed-off-by: Srishti Srivastava <srishtisrivastava.ai@gmail.com> Reviewed By: matthiaskramm, jcai19 Differential Revision: https://reviews.llvm.org/D157261
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
2023-07-29[MLIR][analysis] Fix error in the sparse backward dataflow analysisSrishti Srivastava
Earlier, in the sparse backward dataflow analysis, data from the results of an op implementing `RegionBranchOpInterface` was considered to flow into the operands of every op that did not implement the `RegionBranchTerminatorOpInterface` but was return-like and present in a region of the former. It was thus also expected that the number of results of the former be equal to the number of operands in the latter. This understanding of dataflow is incorrect and thus this expectation is also not justified. This commit fixes this incorrect understanding. This commit ensures that these return-like ops are handled just like the ops implementing the `RegionBranchTerminatorOpInterface`, which means that, if this op has a region `A` whose successors are regions `B`, `C`, and `D`, then data flows from the arguments (successor inputs) of `B`, `C`, and `D` to the corresponding successor operands of this op. This fix is also propagated to liveness analysis that earlier relied on this incorrect implementation of the sparse backward dataflow analysis framework and corrects some incorrect assumptions made in it. Also cleaned up some unnecessary comments from the test file. Issue: https://github.com/llvm/llvm-project/issues/64139. Signed-off-by: Srishti Srivastava <srishtisrivastava.ai@gmail.com> Reviewed By: jcai19, matthiaskramm, Mogball Differential Revision: https://reviews.llvm.org/D156376
2023-07-27[mlir] NFC: rename XDataFlowAnalysis to XForwardDataFlowAnalysisAlex Zinenko
This makes naming consisnt with XBackwardDataFlowAnalysis. Reviewed By: Mogball, phisiart Differential Revision: https://reviews.llvm.org/D155930
2023-07-03[mlir][dataflow] Unify dependency management in AnalysisState.Zhixun Tan
In the MLIR dataflow analysis framework, when an `AnalysisState` is updated, it's dependents are enqueued to be visited. Currently, there are two ways dependents are managed: * `AnalysisState::dependents` stores a list of dependents. `DataFlowSolver::propagateIfChanged()` reads this list and enqueues them to the worklist. * `AnalysisState::onUpdate()` allows custom logic to enqueue more to the worklist. This is called by `DataFlowSolver::propagateIfChanged()`. This cleanup diff consolidates the two into `AnalysisState::onUpdate()`. This way, `DataFlowSolver` does not need to know the detail about `AnalysisState::dependents`, and the logic of dependency management is entirely handled by `AnalysisState`. Reviewed By: Mogball Differential Revision: https://reviews.llvm.org/D154170
2023-05-26[mlir] Move casting calls from methods to function callsTres Popp
The MLIR classes Type/Attribute/Operation/Op/Value support cast/dyn_cast/isa/dyn_cast_or_null functionality through llvm's doCast functionality in addition to defining methods with the same name. This change begins the migration of uses of the method to the corresponding function call as has been decided as more consistent. Note that there still exist classes that only define methods directly, such as AffineExpr, and this does not include work currently to support a functional cast/isa call. Context: - https://mlir.llvm.org/deprecation/ at "Use the free function variants for dyn_cast/cast/isa/…" - Original discussion at https://discourse.llvm.org/t/preferred-casting-style-going-forward/68443 Implementation: This patch updates all remaining uses of the deprecated functionality in mlir/. This was done with clang-tidy as described below and further modifications to GPUBase.td and OpenMPOpsInterfaces.td. Steps are described per line, as comments are removed by git: 0. Retrieve the change from the following to build clang-tidy with an additional check: main...tpopp:llvm-project:tidy-cast-check 1. Build clang-tidy 2. Run clang-tidy over your entire codebase while disabling all checks and enabling the one relevant one. Run on all header files also. 3. Delete .inc files that were also modified, so the next build rebuilds them to a pure state. ``` ninja -C $BUILD_DIR clang-tidy run-clang-tidy -clang-tidy-binary=$BUILD_DIR/bin/clang-tidy -checks='-*,misc-cast-functions'\ -header-filter=mlir/ mlir/* -fix rm -rf $BUILD_DIR/tools/mlir/**/*.inc ``` Differential Revision: https://reviews.llvm.org/D151542
2023-05-12[mlir] Move casting calls from methods to function callsTres Popp
The MLIR classes Type/Attribute/Operation/Op/Value support cast/dyn_cast/isa/dyn_cast_or_null functionality through llvm's doCast functionality in addition to defining methods with the same name. This change begins the migration of uses of the method to the corresponding function call as has been decided as more consistent. Note that there still exist classes that only define methods directly, such as AffineExpr, and this does not include work currently to support a functional cast/isa call. Caveats include: - This clang-tidy script probably has more problems. - This only touches C++ code, so nothing that is being generated. Context: - https://mlir.llvm.org/deprecation/ at "Use the free function variants for dyn_cast/cast/isa/…" - Original discussion at https://discourse.llvm.org/t/preferred-casting-style-going-forward/68443 Implementation: This first patch was created with the following steps. The intention is to only do automated changes at first, so I waste less time if it's reverted, and so the first mass change is more clear as an example to other teams that will need to follow similar steps. Steps are described per line, as comments are removed by git: 0. Retrieve the change from the following to build clang-tidy with an additional check: https://github.com/llvm/llvm-project/compare/main...tpopp:llvm-project:tidy-cast-check 1. Build clang-tidy 2. Run clang-tidy over your entire codebase while disabling all checks and enabling the one relevant one. Run on all header files also. 3. Delete .inc files that were also modified, so the next build rebuilds them to a pure state. 4. Some changes have been deleted for the following reasons: - Some files had a variable also named cast - Some files had not included a header file that defines the cast functions - Some files are definitions of the classes that have the casting methods, so the code still refers to the method instead of the function without adding a prefix or removing the method declaration at the same time. ``` ninja -C $BUILD_DIR clang-tidy run-clang-tidy -clang-tidy-binary=$BUILD_DIR/bin/clang-tidy -checks='-*,misc-cast-functions'\ -header-filter=mlir/ mlir/* -fix rm -rf $BUILD_DIR/tools/mlir/**/*.inc git restore mlir/lib/IR mlir/lib/Dialect/DLTI/DLTI.cpp\ mlir/lib/Dialect/Complex/IR/ComplexDialect.cpp\ mlir/lib/**/IR/\ mlir/lib/Dialect/SparseTensor/Transforms/SparseVectorization.cpp\ mlir/lib/Dialect/Vector/Transforms/LowerVectorMultiReduction.cpp\ mlir/test/lib/Dialect/Test/TestTypes.cpp\ mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.cpp\ mlir/test/lib/Dialect/Test/TestAttributes.cpp\ mlir/unittests/TableGen/EnumsGenTest.cpp\ mlir/test/python/lib/PythonTestCAPI.cpp\ mlir/include/mlir/IR/ ``` Differential Revision: https://reviews.llvm.org/D150123
2023-03-15[ADT][mlir][NFCI] Do not use non-const lvalue-refs with enumerateJakub Kuderski
Replace references to enumerate results with either result_pairs (reference wrapper type) or structured bindings. I did not use structured bindings everywhere as it wasn't clear to me it would improve readability. This is in preparation to the switch to zip semantics which won't support non-const lvalue reference to elements: https://reviews.llvm.org/D144503. I chose to use values instead of const lvalue-refs because MLIR is biased towards avoiding `const` local variables. This won't degrade performance because currently `result_pair` is cheap to copy (size_t + iterator), and in the future, the enumerator iterator dereference will return temporaries anyway. Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D146006
2023-01-25[mlir] fix crash when call a function declXiang Li
Check region before use it. Fixes #60215 https://github.com/llvm/llvm-project/issues/60215 Differential Revision: https://reviews.llvm.org/D142544
2022-12-22[mlir] Fix a warningKazu Hirata
This patch fixes: mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp:321:19: warning: unused variable ‘block’ [-Wunused-variable]
2022-12-19[mlir] Apply ClangTidy readability finding.Adrian Kuegel
Use empty() instead of checking for size 0.
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-13[mlir] Implement backward dataflow.Matthias Kramm
This enables interprocedural lifeness analysis, very busy expression analysis, etc. Reviewed By: Mogball Differential Revision: https://reviews.llvm.org/D138935
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-09-08[mlir][dataflow] Remove Lattice::isUninitialized().Zhixun Tan
Currently, for sparse analyses, we always store a `Optional<ValueT>` in each lattice element. When it's `None`, we consider the lattice element as `uninitialized`. However: * Not all lattices have an `uninitialized` state. For example, `Executable` and `PredecessorState` have default values so they are always initialized. * In dense analyses, we don't have the concept of an `uninitialized` state. Given these inconsistencies, this patch removes `Lattice::isUninitialized()`. Individual analysis states are now default-constructed. If the default state of an analysis can be considered as "uninitialized" then this analysis should implement the following logic: * Special join rule: `join(uninitialized, any) == any`. * Special bail out logic: if any of the input states is uninitialized, exit the transfer function early. Depends On D132086 Reviewed By: Mogball Differential Revision: https://reviews.llvm.org/D132800
2022-08-29[mlir][dataflow] Consolidate ↵Zhixun Tan
AbstractSparseLattice::markPessimisticFixpoint() and AbstractDenseLattice::reset() into Abstract{Sparse,Dense}DataFlowAnalysis::setToEntryState(). ### Rationale For a program point where we cannot reason about incoming dataflow (e.g. an argument of an entry block), the framework needs to initialize the state. Currently, `AbstractSparseDataFlowAnalysis` initializes such state to the "pessimistic fixpoint", and `AbstractDenseDataFlowAnalysis` calls the state's `reset()` function. However, entry states aren't necessarily the pessimistic fixpoint. Example: in reaching definition, the pessimistic fixpoint is `{all definitions}`, but the entry state is `{}`. This awkwardness might be why the dense analysis API currently uses `reset()` instead of `markPessimisticFixpoint()`. This patch consolidates entry point initialization into a single function `setToEntryState()`. ### API Location Note that `setToEntryState()` is defined in the analysis rather than the lattice, so that we allow different analyses to use the same lattice but different entry states. ### Removal of the concept of optimistic/known value The concept of optimistic/known value is too specific to SCCP. Furthermore, the known value is not really used: In the current SCCP implementation, the known value (pessimistic fixpoint) is always `Attribute{}` (non-constant). This means there's no point storing a `knownValue` in each state. If we do need to re-introduce optimistic/known value, we should put it in the SCCP analysis, not the sparse analysis API. ### Terminology Please let me know if "entry state" is a good terminology. I chose "entry" from Wikipedia (https://en.wikipedia.org/wiki/Data-flow_analysis#Basic_principles). Another term I can think of is "boundary" (https://suif.stanford.edu/~courses/cs243/lectures/L3-DFA2-revised.pdf) which might be better since it also makes sense for backward analysis. Reviewed By: Mogball Differential Revision: https://reviews.llvm.org/D132086
2022-08-20Fix unused variable warningsKazu Hirata
These warnings came up with gcc-11.3.0.
2022-08-15[mlir][dataflow] Remove Abstract{Sparse,Dense}Lattice::isAtFixpoint() and an ↵Zhixun Tan
ineffective optimization to simplify public API Currently, in the MLIR `{Sparse,Dense}DataFlowAnalysis` API, there is a small optimization: Before running a transfer function, if the "out state" is already at the pessimistic fixpoint (bottom lattice value), then we know that it cannot possibly be changed, therefore we can skip the transfer function. I benchmarked and found that this optimization is ineffective, so we can remove it and simplify `{Sparse,Dense}DataFlowAnalysis`. In a subsequent patch, I plan to change/remove the concept of the pessimistic fixpoint so that the API is further simplified. Benchmark: I ran the following tests 5 times (after 3 warmup runs), and timed the `initializeAndRun()` function. | Test | Before (us) | After (us) | | mlir-opt -test-dead-code-analysis mlir/test/Analysis/DataFlow/test-dead-code-analysis.mlir | 181.2536 | 187.7074 | | mlir-opt -- -test-dead-code-analysis mlir/test/Analysis/DataFlow/test-last-modified-callgraph.mlir | 109.5504 | 105.0654 | | mlir-opt -- -test-dead-code-analysis mlir/test/Analysis/DataFlow/test-last-modified.mlir | 333.3646 | 322.4224 | | mlir-opt -- -allow-unregistered-dialect -sccp mlir/test/Analysis/DataFlow/test-combined-sccp.mlir | 1027.1492 | 1081.818 | Note: `test-combined-sccp.mlir` is crafted by combining `mlir/test/Transforms/sccp.mlir`, `mlir/test/Transforms/sccp-structured.mlir` and `mlir/test/Transforms/sccp-callgraph.mlir`. Reviewed By: aartbik, Mogball Differential Revision: https://reviews.llvm.org/D131660
2022-07-07[mlir] Swap integer range inference to the new frameworkMogball
Integer range inference has been swapped to the new framework. The integer value range lattices automatically updates the corresponding constant value on update. Depends on D127173 Reviewed By: krzysz00, rriddle Differential Revision: https://reviews.llvm.org/D128866
2022-07-07[mlir] An implementation of sparse data-flow analysisMogball
This patch introduces a (forward) sparse data-flow analysis implemented with the data-flow analysis framework. The analysis interacts with liveness information that can be provided by dead-code analysis to be conditional. This patch re-implements SCCP using dead-code analysis and (conditional) constant propagation analyses. Depends on D127064 Reviewed By: rriddle, phisiart Differential Revision: https://reviews.llvm.org/D127139
2022-06-30[mlir] Add Dead Code AnalysisMogball
This patch implements the analysis state classes needed for sparse data-flow analysis and implements a dead-code analysis using those states to determine liveness of blocks, control-flow edges, region predecessors, and function callsites. Depends on D126751 Reviewed By: rriddle, phisiart Differential Revision: https://reviews.llvm.org/D127064