addLocalFloorDiv currently returns void and requires the caller to know
that the newly added local variable is in a particular index. This
commit returns the index of the newly added variable so that callers
need not tie themselves to this implementation detail.
I found one relevant callsite demonstrating this and updated it. I am
using this API out of tree and wanted to make our out-of-tree code a bit
more resilient to upstream changes.
Improve memref region utility (`getConstantBoundingSizeAndShape`) to get
its constant bounding size and shape using affine expressions/maps by
also considering local variables in the system. Leads to significantly
precise and tighter bounding size and shape in the presence of div/mod
expressions (as evident from the test cases). The approach is now more
robust, proper, and complete. For affine fusion, this leads to private
memrefs of accurate size in several cases. This also impacts other
affine analysis-based passes like data copy generation that use memref
regions.
With contributions from `Vinayaka Bandishti <vinayaka@polymagelabs.com>`
on `getConstantBoundingSizeAndShape` and getConstantBoundOnDimSize`.
Fixes: https://github.com/llvm/llvm-project/issues/46317
Co-authored-by: Vinayaka Bandishti <vinayaka@polymagelabs.com>
Fix/improve debug messages and API signatures for affine
analysis/fusion utils.
Move some warnings under LLVM_DEBUG. These weren't meant to be exposed
during compilation.
Add dump pretty methods for FlatLinearConstraints.
NFC.
I noticed that several assertions in MLIR codebase have issues with
operator precedence
The issue with operator precedence in these assertions is due to the way
logical operators are evaluated. The `&&` operator has higher precedence
than the `||` operator, which means the assertion is currently
evaluating incorrectly, like this:
```
assert((resType.getNumDynamicDims() == dynOutDims.size()) ||
(dynOutDims.empty() && "Either none or all output dynamic dims must be specified!"));
```
We should add parentheses around the entire expression involving
`dynOutDims.empty()` to ensure that the logical conditions are grouped
correctly. Here’s the corrected version:
```
assert(((resType.getNumDynamicDims() == dynOutDims.size()) || dynOutDims.empty()) &&
"Either none or all output dynamic dims must be specified!");
```
Follow up on a desire post-landing d0fee98 (mlir/Presburger: strip
dependency on MLIRSupport) to reinstate the use of LogicalResult in
Presburger. Since db791b2 (mlir/LogicalResult: move into llvm),
LogicalResult is in LLVM, and fulfilling this desire is possible while
still maintaining the goal of stripping the Presburger library of mlir
dependencies.
Strip the Presburger library's dependency on the MLIR Support library,
as well as the headers, in the interest of making it leaner.
This patch is part of a project to move the Presburger library into
LLVM.
Change: remove guards on debug-printing, to allow Release builds without
LLVM_ENABLE_DUMP to pass.
MPInt is an arbitrary-precision integer library that builds on top of
APInt, and has a fast-path when the number fits within 64 bits. It was
originally written for the Presburger library in MLIR, but seems useful
to the LLVM project in general, independently of the Presburger library
or MLIR. Hence, move it into LLVM/ADT under the name DynamicAPInt.
This patch is part of a project to move the Presburger library into
LLVM.
MPInt is an arbitrary-precision integer library that builds on top of
APInt, and has a fast-path when the number fits within 64 bits. It was
originally written for the Presburger library in MLIR, but seems useful
to the LLVM project in general, independently of the Presburger library
or MLIR. Hence, move it into LLVM/ADT under the name DynamicAPInt.
This patch is part of a project to move the Presburger library into
LLVM.
This patch adds support for computing bounds for semi-affine mod
expression to FlatLinearConstraints. This is then enabled within the
ScalableValueBoundsConstraintSet to allow computing the bounds of
scalable remainder loops.
E.g. computing the bound of something like:
```
// `1000 mod s0` is a semi-affine.
#remainder_start_index = affine_map<()[s0] -> (-(1000 mod s0) + 1000)>
#remaining_iterations = affine_map<(d0) -> (-d0 + 1000)>
%0 = affine.apply #remainder_start_index()[%c8_vscale]
scf.for %i = %0 to %c1000 step %c8_vscale {
%remaining_iterations = affine.apply #remaining_iterations(%i)
// The upper bound for the remainder loop iterations should be:
// %c8_vscale - 1 (expressed as an affine map,
// affine_map<()[s0] -> (s0 * 8 - 1)>, where s0 is vscale)
%bound = "test.reify_bound"(%remaining_iterations) <{scalable, ...}>
}
```
There are caveats to this implementation. To be able to add a bound for
a `mod` we need to assume the rhs is positive (> 0). This may not be
known when adding the bounds for the `mod` expression. So to handle this
a constraint is added for `rhs > 0`, this may later be found not to hold
(in which case the constraints set becomes empty/invalid).
This is not a problem for computing scalable bounds where it's safe to
assume `s0` is vscale (or some positive multiple of it). But this may
need to be considered when enabling this feature elsewhere (to ensure
correctness).
The pull request includes the following changes.
1. Refactors the interface to `PresburgerSpace::identifiers` to `setId` and a
const `getId`, instead of previous `getId` which returned a mutable
reference. `resetIds` does not need to be called to use identifiers, `setId`
calls `resetIds` if identifiers are not enabled.
2. Deprecates `FlatAffineRelation` by refactoring all usages of
`FlatAffineRelation` to `IntegerRelation`. To achieve this,
`FlatAffineRelation::compose` is refactored into
`IntegerRelation::mergeAndCompose`.
3. Deletes unneeded overrides of virtual functions `hasConsistentState`,
`clearAndCopyFrom` and `fourierMotzkinEliminate` from
`FlatLinearValueConstraints` as these were only used through
`FlatAffineRelation` and we now use `IntegerRelation`'s member functions
instead.
4. Fixes an existing bug in FlatLinearValueConstraints' constructor
which caused
identifiers set by superclass FlatLinearConstraints' constructor to be
erased.
5. Fixes `IntegerRelation::convertVarKind` not preserving identifiers.
When performing constant folding on the affineApplyOp, there is a
division of 0 in the affine map.
[related issue](https://github.com/llvm/llvm-project/issues/64622)
---------
Co-authored-by: Javier Setoain <jsetoain@users.noreply.github.com>
Generalize affine fusion to work at any inner depth; fusing loops inside
other
affine.for or even inside scf.for or scf.while nests. Apply in post
order on
all affine nests on the pass' top-level operation.
Fix MDG init for blocks inside other affine nests.
Relax unnecessary requirement for unique vars during merge and align of
FlatLinearValueConstraints. There are several cases where
FlatLinearValueConstraints need to have duplicate Values for the
dimensions:
for eg. in dependence relation systems with source and destination
accesses
could have common loop IVs. `mergeAndAlign` can be done even in the
presence
of Values reappearing by simply aligning from left to right in that
order.
While at this, drop outdated comments; improve some debug messages.
Matrix has been templated to Matrix (for MPInt and Fraction) with
explicit instantiation for both these types.
IntMatrix, inheriting from Matrix<MPInt>, has been created to allow for
integer-only methods.
makeMatrix has been duplicated to makeIntMatrix and makeFracMatrix.
This was already landed previously but was reverted in
98c994c8e22d7f38cc04f56ee5cdeb337734414d due to build failure. This
fixes the failure.
The method implementations remain in the .cpp file; explicit instantiations have been added for these two types.
makeMatrix has been duplicated to makeIntMatrix and makeFracMatrix.
Fix a bug in detecting unknown ids as mods of known ids that was
preventing certain fusions.
While at this, fix the function signature of `detectAsMod` function to
have output as the last argument.
Reviewed By: bondhugula
Differential Revision: https://reviews.llvm.org/D152055
`BoundType` is no longer a nested member of `IntegerRelation` but a top-level enum in the `presburger` namespace.
This allows `BoundType` to be predeclared in header files. Nested members cannot be predeclared.
Differential Revision: https://reviews.llvm.org/D146210
The new class hierarchy is as follows:
* `IntegerRelation` (no change)
* `IntegerPolyhedron` (no change)
* `FlatLinearConstraints`: provides an AffineExpr-based API
* `FlatLinearValueConstraints`: stores an additional mapping of non-local vars to SSA values
* `FlatAffineValueConstraints`: provides additional helper functions for Affine dialect ops
* `FlatAffineRelation` (no change)
`FlatConstraints` and `FlatValueConstraints` are moved from `MLIRAffineAnalysis` to `MLIRAnalysis` and can be used without depending on the Affine dialect.
This change is in preparation of D145681, which adds an MLIR interface that depends on `FlatConstraints` (and cannot depend on the Affine dialect or any other dialect).
Differential Revision: https://reviews.llvm.org/D146201