Commit Graph

848 Commits

Author SHA1 Message Date
Kazu Hirata
192d9dd731 [mlir] Use std::nullopt instead of None in comments (NFC)
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-04 19:58:32 -08:00
Kazu Hirata
70c73d1b72 [mlir] Use std::nullopt instead of None in comments (NFC)
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-04 17:23:50 -08:00
Kazu Hirata
1a36588ec6 [mlir] Use std::nullopt instead of None (NFC)
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-12-03 18:50:27 -08:00
Mahesh Ravishankar
fc367dfa67 [mlir] Remove Transforms/SideEffectUtils.h and move the methods into Interface/SideEffectInterfaces.h.
The methods in `SideEffectUtils.h` (and their implementations in
`SideEffectUtils.cpp`) seem to have similar intent to methods already
existing in `SideEffectInterfaces.h`. Move the decleration (and
implementation) from `SideEffectUtils.h` (and `SideEffectUtils.cpp`)
into `SideEffectInterfaces.h` (and `SideEffectInterface.cpp`).

Also drop the `SideEffectInterface::hasNoEffect` method in favor of
`mlir::isMemoryEffectFree` which actually recurses into the operation
instead of just relying on the `hasRecursiveMemoryEffectTrait`
exclusively.

Differential Revision: https://reviews.llvm.org/D137857
2022-11-15 20:07:35 +00:00
Hanhan Wang
8c33639aa6 [mlir] Move the assertion to a valid place.
The defining Op may live in an unlinked block so its parent Op may be
null. Only assert it when the parent Op is not null.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D137306
2022-11-04 12:14:15 -07:00
Sanjoy Das
86771d0b65 Introduce a ConditionallySpeculatable op interface
This patch takes the first step towards a more principled modeling of undefined behavior in MLIR as discussed in the following discourse threads:

 1. https://discourse.llvm.org/t/semantics-modeling-undefined-behavior-and-side-effects/4812
 2. https://discourse.llvm.org/t/rfc-mark-tensor-dim-and-memref-dim-as-side-effecting/65729

This patch in particular does the following:

 1. Introduces a ConditionallySpeculatable OpInterface that dynamically determines whether an Operation can be speculated.
 2. Re-defines `NoSideEffect` to allow undefined behavior, making it necessary but not sufficient for speculation.  Also renames it to `NoMemoryEffect`.
 3. Makes LICM respect the above semantics.
 4. Changes all ops tagged with `NoSideEffect` today to additionally implement ConditionallySpeculatable and mark themselves as always speculatable.  This combined trait is named `Pure`.  This makes this change NFC.

For out of tree dialects:

 1. Replace `NoSideEffect` with `Pure` if the operation does not have any memory effects, undefined behavior or infinite loops.
 2. Replace `NoSideEffect` with `NoSideEffect` otherwise.

The next steps in this process are (I'm proposing to do these in upcoming patches):

 1. Update operations like `tensor.dim`, `memref.dim`, `scf.for`, `affine.for` to implement a correct hook for `ConditionallySpeculatable`.  I'm also happy to update ops in other dialects if the respective dialect owners would like to and can give me some pointers.
 2. Update other passes that speculate operations to consult `ConditionallySpeculatable` in addition to `NoMemoryEffect`.  I could not find any other than LICM on a quick skim, but I could have missed some.
 3. Add some documentation / FAQs detailing the differences between side effects, undefined behavior, speculatabilty.

Reviewed By: rriddle, mehdi_amini

Differential Revision: https://reviews.llvm.org/D135505
2022-10-12 10:56:12 -07:00
Mehdi Amini
9e2ace1c52 Apply clang-tidy fixes for performance-move-const-arg in IntegerRelation.cpp (NFC) 2022-10-07 00:48:16 +00:00
Jeff Niu
d67def8704 [mlir][analysis] Remove empty files (NFC) 2022-10-03 16:52:53 -07:00
Groverkss
b696e25a7a [MLIR][Presburger] Add hermite normal form computation to Matrix
This patch adds hermite normal form computation to Matrix. Part of this algorithm
lived in LinearTransform, being used for compuing column echelon form. This
patch moves the implementation to Matrix::hermiteNormalForm and generalises it
to compute the hermite normal form.

Reviewed By: arjunp

Differential Revision: https://reviews.llvm.org/D133510
2022-09-14 16:39:05 +01:00
Arjun P
6d6f6c4d3f [MLIR][Presburger] use arbitrary-precision arithmetic with MPInt instead of int64_t
Only the main Presburger library under the Presburger directory has been switched to use arbitrary precision. Users have been changed to just cast returned values back to int64_t or to use newly added convenience functions that perform the same cast internally.

The performance impact of this has been tested by checking test runtimes after copy-pasting 100 copies of each function. Affine/simplify-structures.mlir goes from 0.76s to 0.80s after this patch. Its performance sees no regression compared to its original performance at commit 18a06d4f3a before a series of patches that I landed to offset the performance overhead of switching to arbitrary precision.

Affine/canonicalize.mlir and SCF/canonicalize.mlir show no noticable difference, staying at 2.02s and about 2.35s respectively.

Also, for Affine and SCF tests as a whole (no copy-pasting), the runtime remains about 0.09s on average before and after.

Reviewed By: bondhugula

Differential Revision: https://reviews.llvm.org/D129510
2022-09-14 15:47:41 +01:00
Groverkss
bb2226ac53 [MLIR][Presburger] Refactor MultiAffineFunction to be defined over universe
This patch refactors MAF to be defined over the universe in a given space
instead of being defined over a restricted domain.

The reasoning for this refactor is to store division representation for local
variables explicitly for the function outputs. This change is required for
unionLexMax/Min to support local variables which will be upstreamed after this
patch. Another reason for this refactor is to have a flattened form of
AffineMap as MultiAffineFunction.

Reviewed By: arjunp

Differential Revision: https://reviews.llvm.org/D131864
2022-09-11 01:12:09 +01:00
Markus Böck
82f86b862b [mlir][CallGraph] Add special call graph node for representing unknown callees
The callgraph currently contains a special external node that is used both as the quasi caller for any externally callable as well as callees that could not be resolved.
This has one negative side effect however, which is the motivation for this patch: It leads to every externally callable which contains a call that could not be resolved (eg. an indirect call), to be put into one giant SCC when iterating over the SCCs of the call graph.

This patch fixes that issue by creating a second special callgraph node that acts as the callee for any unresolved callable. This breaks the cycles produced in the callgraph, yielding proper SCCs for all direct calls.

Differential Revision: https://reviews.llvm.org/D133585
2022-09-09 20:22:59 +02:00
Zhixun Tan
47bf3e3812 [mlir][dataflow] Remove Lattice::isUninitialized().
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-09-08 08:46:22 -07:00
Mehdi Amini
95201fcca0 Revert "[mlir][cmake] Don't add dependencies on mlir-(generic-)headers"
This reverts commit 7691b69d5b.

Bots are broken because we're missing CMake dependencies all around now.
2022-09-03 01:45:18 +00:00
Jeff Niu
7691b69d5b [mlir][cmake] Don't add dependencies on mlir-(generic-)headers
Every dialect was dependent on `mlir-headers`, which was causing the
build of any single MLIR dialect to pull in a bunch of extra
dependencies that aren't needed. Now, MLIR dialects will need to
explicitly depend on `MLIR*IncGen` targets to pull in any needed
headers.

This does not impact the actual `mlir-header` target.

Consider the "simple" Arithmetic dialect. Before:

```
% ninja MLIRArithmeticDialect
[151/812] Building CXX object lib/TableGen/CMakeFiles/LLVMTableGen.dir/JSONBackend.cpp.o
```

After:

```
% ninja MLIRArithmeticDialect
[207/374] Building CXX object tools/mlir/lib/TableGen/CMakeFiles/MLIRTableGen.dir/GenInfo.cpp.o
```

(Both clean builds)

Reviewed By: rriddle, jpienaar

Differential Revision: https://reviews.llvm.org/D133132
2022-09-02 12:13:49 -07:00
Johannes Reifferscheid
23dec4a352 Move BufferViewFlowAnalysis to the Bufferization dialect.
It's only used from there, and this lets us remove the dependency from Analysis
to the Arith dialect.

Reviewed By: springerm

Differential Revision: https://reviews.llvm.org/D132928
2022-08-30 14:25:49 +02:00
Zhixun Tan
de0ebc5263 [mlir][dataflow] Consolidate 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-29 09:00:55 -07:00
Kazu Hirata
4a2377afd6 Use std::gcd (NFC)
To avoid changing semantics inadvertently, this patch casts arguments
to uint64_t before calling std::gcd.
2022-08-28 10:41:53 -07:00
Kazu Hirata
267f21a21b Use std::gcd (NFC)
This patch replaces calls to greatestCommonDivisor with std::gcd where
two arguments are of the same type.  This means that
std::common_type_t of the argument type is the same as the argument
type.

We could drop calls to std::abs in some cases, but that's left for
another patch.
2022-08-28 10:41:51 -07:00
Kazu Hirata
099775c2d6 [mlir] Use std::lcm (NFC)
This patch replaces mlir::lcm with std::lcm, a C++17 feature.

Note that all the arguments to mlir::lcm are of int64_t with no
implicit type conversion as they are passed to mlir::lcm, which I've
verified by modifying mlir::lcm as:

  template <typename TA, typename TB>
  inline int64_t lcm(TA a, TB b) {
    static_assert(std::is_same_v<TA, int64_t>);
    static_assert(std::is_same_v<TB, int64_t>);
    :
2022-08-27 09:53:15 -07:00
Johannes Reifferscheid
27a1a85662 buffer-deallocation: consider aliases introduced by arith.select.
Currently, buffer deallocation considers arith.select to be
non-aliasing, which results in deallocs being inserted incorrectly. Since
arith.select doesn't implement any useful interfaces, this change just handles
it explicitly. Eventually this should probably be fixed properly, if this pass
is going to be used long term.

Reviewed By: springerm

Differential Revision: https://reviews.llvm.org/D132460
2022-08-23 14:37:02 +02:00
Kazu Hirata
258531b7ac Remove redundant initialization of Optional (NFC) 2022-08-20 21:18:28 -07:00
Kazu Hirata
9e296584ce Fix unused variable warnings
These warnings came up with gcc-11.3.0.
2022-08-20 00:12:35 -07:00
Jacques Pienaar
052669e71a [mlir] add missing pessimistic setting
This is updated on https://reviews.llvm.org/D127139, to mark op with region as pessimistic.

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D131480
2022-08-17 16:20:13 -07:00
Zhixun Tan
4835441d02 [mlir][dataflow] Remove Abstract{Sparse,Dense}Lattice::isAtFixpoint() and an 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-08-15 13:21:05 -04:00
Kazu Hirata
3a6da9ebcb [mlir] Remove redundant member initialization (NFC)
Identified with readability-redundant-member-init.
2022-08-14 12:51:59 -07:00
Benjamin Kramer
9fa59e7643 [mlir] Use C++17 structured bindings instead of std::tie where applicable. NFCI 2022-08-09 13:34:17 +02:00
Arjun P
1486a2eaf0 [MLIR][Presburger] SlowMPInt::gcd: fix crash when sizes differ
Reviewed By: Groverkss

Differential Revision: https://reviews.llvm.org/D131186
2022-08-04 19:15:50 +01:00
Arjun P
bad95b72ee [MLIR][Presburger] fourier-motzkin: check if all LCMs are 1 using a bool instead of by multiplying them
This can easily overflow and it is possible for these unsigned overflows to result in incorrect results.
For example, the two LCMs could be 641 and 6700417, which multiply to 2^32 + 1, which overflows to 1.
Unsigned overflows already occur in the existing tests.

Also, when switching to arbitrary-precision arithmetic, this results in a many
large integer multiplications resulting in a significant slowdown.

Reviewed By: Groverkss

Differential Revision: https://reviews.llvm.org/D131184
2022-08-04 19:14:39 +01:00
Jeff Niu
62fe67f9eb [mlir][DCA] Fix visiting call ops when run at function scopes
When dead-code analysis is run at the scope of a function, call ops to
other functions at the same level were being marked as unreachable,
since the analysis optimistically assumes the call op to have no known
predecessors and that all predecessors are known, but the callee would
never get visited.

This patch fixes the bug by checking if a referenced function is above
the top-level op of the analysis, and is thus considered an external
callable.

Fixes #56830

Reviewed By: zero9178

Differential Revision: https://reviews.llvm.org/D130829
2022-07-31 16:03:46 -04:00
Kazu Hirata
16eaeaded5 Use is_contained (NFC) 2022-07-30 10:35:54 -07:00
Jacques Pienaar
13bc82b587 [mlir] SCCP add missing pessimistic setting
When this was updated in D127139 the update in-place case was no longer
marked as pessimistic. Add back in.

Differential Revision: https://reviews.llvm.org/D130453
2022-07-25 17:41:17 -07:00
Dmitri Gribenko
aba43035bd Use llvm::sort instead of std::sort where possible
llvm::sort is beneficial even when we use the iterator-based overload,
since it can optionally shuffle the elements (to detect
non-determinism). However llvm::sort is not usable everywhere, for
example, in compiler-rt.

Reviewed By: nhaehnle

Differential Revision: https://reviews.llvm.org/D130406
2022-07-23 15:19:05 +02:00
Kazu Hirata
360c1111e3 Use llvm::is_contained (NFC) 2022-07-20 09:09:19 -07:00
Arjun P
ffb8b7b2a0 [MLIR][Presburger] Provide functions to convert between arrays of MPInt and int64_t
Reviewed By: Groverkss

Differential Revision: https://reviews.llvm.org/D129509
2022-07-18 17:34:50 +01:00
Arjun P
ca6a5afbb2 [MLIR][Presburger] SlowMPInt: fix bug in ceilDiv, floorDiv where widths weren't harmonized
This also adds tests for abs, ceilDiv, floorDiv, mod, gcd and lcm.

Reviewed By: Groverkss

Differential Revision: https://reviews.llvm.org/D129816
2022-07-18 17:34:01 +01:00
bzcheeseman
f382dfc06b [MLIR][Liveness] Add currentlyLiveValues, a way to get a set of values that are live as of a given operation.
This change allows the user of LivenessBlockInfo to specify an op within the block and get a set of all values that are live as of that op. Semantically it relies on having a dominance-based region that has ordered operations. For DFG regions, computing liveness statically this way doesn't really make sense, it likely needs to be done at runtime.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D129447
2022-07-15 22:10:53 -07:00
Arjun P
86d73c11cf [MLIR][Presburger] SlowMPInt: gcd: assert that operands are non-negative 2022-07-15 15:45:53 +01:00
Kazu Hirata
c27d815249 [mlir] Use value instead of getValue (NFC) 2022-07-14 00:19:59 -07:00
Kazu Hirata
491d27013d [mlir] Use has_value instead of hasValue (NFC) 2022-07-13 00:57:02 -07:00
Arjun P
cdbc5f1e10 [MLIR][Presburger] introduce MPInt to support fast arbitrary precision in Presburger
This uses an int64_t-based fastpath for the common case and falls back to
SlowMPInt to handle the rare cases where larger numbers occur.
It uses `__builtin_*` for performance through the support in LLVM MathExtras.

Using this in the Presburger library results in a minor performance
*improvement* over any commit hash before sequence of patches
starting at d5e31cf38a.

This was previously reverted in 1e10d35ea9 due
to a build failure; relanding now with an attempted fix.

Reviewed By: Groverkss, ftynse

Differential Revision: https://reviews.llvm.org/D128811
2022-07-11 15:46:44 +01:00
Arjun P
1e10d35ea9 Revert "[MLIR][Presburger] introduce MPInt to support fast arbitrary precision in Presburger"
This reverts commit c9035df2fa.
Reverting due to build failure on Windows: https://lab.llvm.org/buildbot/#/builders/172/builds/14767
2022-07-11 14:26:09 +01:00
Arjun P
c9035df2fa [MLIR][Presburger] introduce MPInt to support fast arbitrary precision in Presburger
This uses an int64_t-based fastpath for the common case and falls back to
SlowMPInt to handle the rare cases where larger numbers occur.
It uses `__builtin_*` for performance through the support in LLVM MathExtras.

Using this in the Presburger library results in a minor performance
*improvement* over any commit hash before sequence of patches
starting at d5e31cf38a.

Reviewed By: Groverkss, ftynse

Differential Revision: https://reviews.llvm.org/D128811
2022-07-11 11:41:29 +01:00
Mogball
c20a581a8d [mlir] Delete ForwardDataFlowAnalysis
With SCCP and integer range analysis ported to the new framework, this old framework is redundant. Delete it.

Depends on D128866

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D128867
2022-07-07 21:08:27 -07:00
Mogball
ab701975e7 [mlir] Swap integer range inference to the new framework
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 20:28:13 -07:00
Mogball
d80c271c8a [mlir] An implementation of dense data-flow analysis
This patch introduces an implementation of dense data-flow analysis. Dense
data-flow analysis attaches a lattice before and after the execution of every
operation. The lattice state is propagated across operations by a user-defined
transfer function. The state is joined across control-flow and callgraph edges.

Thge patch provides an example pass that uses both a dense and a sparse analysis
together.

Depends on D127139

Reviewed By: rriddle, phisiart

Differential Revision: https://reviews.llvm.org/D127173
2022-07-07 15:12:46 -07:00
Mogball
9432fbfe13 [mlir] An implementation of sparse data-flow analysis
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-07-07 10:17:04 -07:00
Groverkss
479c4f648a [MLIR][Presburger] Refactor division representation to DivisionRepr
This patch refactors existing implementations of division representation storage
into a new class, DivisionRepr. This refactoring is done so that the common
division utilities can be shared in an upcoming patch.

Reviewed By: arjunp

Differential Revision: https://reviews.llvm.org/D129146
2022-07-07 15:05:28 +01:00
Groverkss
a18f843f07 [MLIR][Presburger] Support lexicographic max/min union of two PWMAFunction
This patch implements a lexicographic max/min union of two PWMAFunctions.

The lexmax/lexmin union of two functions is defined as a function defined on
the union of the input domains of both functions, such that when only one of the
functions are defined, it outputs the same as that function, and if both are
defined, it outputs the lexmax/lexmin of the two outputs. On points where
neither function is defined, the union is not defined either.

Reviewed By: arjunp

Differential Revision: https://reviews.llvm.org/D128829
2022-07-06 16:08:20 +01:00
Groverkss
ed3b040b54 [MLIR][Presburger] Rename attachments to identifiers in PresburgerSpace
"attachment" was a temporary name chosen for the information attached to a
variable in a PresburgerSpace. After the disambiguation of "variables" and
"identifiers" in PresburgerSpace, we use the word "identifiers" for this
information, since this information is used to "identify" these variables.

Reviewed By: arjunp

Differential Revision: https://reviews.llvm.org/D128751
2022-07-05 16:23:44 +01:00