[Mlir-commits] [mlir] [MLIR][Presburger] Use Identifiers outside Presburger library (PR #77316)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Feb 27 07:09:35 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Bharathi Ramana Joshi (iambrj)
<details>
<summary>Changes</summary>
---
Patch is 44.47 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/77316.diff
10 Files Affected:
- (modified) mlir/include/mlir/Analysis/FlatLinearValueConstraints.h (+52-50)
- (modified) mlir/include/mlir/Analysis/Presburger/IntegerRelation.h (+5)
- (modified) mlir/include/mlir/Analysis/Presburger/PresburgerSpace.h (+2)
- (modified) mlir/include/mlir/Dialect/Affine/Analysis/AffineAnalysis.h (+2-1)
- (modified) mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h (+3-2)
- (modified) mlir/lib/Analysis/FlatLinearValueConstraints.cpp (+44-96)
- (modified) mlir/lib/Analysis/Presburger/IntegerRelation.cpp (+67-15)
- (modified) mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp (+38-25)
- (modified) mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp (+25-17)
- (modified) mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp (+136)
``````````diff
diff --git a/mlir/include/mlir/Analysis/FlatLinearValueConstraints.h b/mlir/include/mlir/Analysis/FlatLinearValueConstraints.h
index e4de5b0661571c..22eaba94aa950e 100644
--- a/mlir/include/mlir/Analysis/FlatLinearValueConstraints.h
+++ b/mlir/include/mlir/Analysis/FlatLinearValueConstraints.h
@@ -205,6 +205,8 @@ class FlatLinearConstraints : public presburger::IntegerPolyhedron {
/// where each non-local variable can have an SSA Value attached to it.
class FlatLinearValueConstraints : public FlatLinearConstraints {
public:
+ using Identifier = presburger::Identifier;
+
/// Constructs a constraint system reserving memory for the specified number
/// of constraints and variables. `valArgs` are the optional SSA values
/// associated with each dimension/symbol. These must either be empty or match
@@ -217,11 +219,11 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
: FlatLinearConstraints(numReservedInequalities, numReservedEqualities,
numReservedCols, numDims, numSymbols, numLocals) {
assert(valArgs.empty() || valArgs.size() == getNumDimAndSymbolVars());
- values.reserve(numReservedCols);
- if (valArgs.empty())
- values.resize(getNumDimAndSymbolVars(), std::nullopt);
- else
- values.append(valArgs.begin(), valArgs.end());
+ // Store Values in space's identifiers.
+ space.resetIds();
+ for (unsigned i = 0, e = valArgs.size(); i < e; ++i)
+ if (valArgs[i])
+ setValue(i, *valArgs[i]);
}
/// Constructs a constraint system reserving memory for the specified number
@@ -236,11 +238,11 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
: FlatLinearConstraints(numReservedInequalities, numReservedEqualities,
numReservedCols, numDims, numSymbols, numLocals) {
assert(valArgs.empty() || valArgs.size() == getNumDimAndSymbolVars());
- values.reserve(numReservedCols);
- if (valArgs.empty())
- values.resize(getNumDimAndSymbolVars(), std::nullopt);
- else
- values.append(valArgs.begin(), valArgs.end());
+ // Store Values in space's identifiers.
+ space.resetIds();
+ for (unsigned i = 0, e = valArgs.size(); i < e; ++i)
+ if (valArgs[i])
+ setValue(i, valArgs[i]);
}
/// Constructs a constraint system with the specified number of dimensions
@@ -272,11 +274,15 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
FlatLinearValueConstraints(const IntegerPolyhedron &fac,
ArrayRef<std::optional<Value>> valArgs = {})
: FlatLinearConstraints(fac) {
- assert(valArgs.empty() || valArgs.size() == getNumDimAndSymbolVars());
+ // Do not reset values assigned by FlatLinearConstraints' constructor.
if (valArgs.empty())
- values.resize(getNumDimAndSymbolVars(), std::nullopt);
- else
- values.append(valArgs.begin(), valArgs.end());
+ return;
+ assert(valArgs.size() == getNumDimAndSymbolVars());
+ // Store Values in space's identifiers.
+ space.resetIds();
+ for (unsigned i = 0, e = valArgs.size(); i < e; ++i)
+ if (valArgs[i])
+ setValue(i, *valArgs[i]);
}
/// Creates an affine constraint system from an IntegerSet.
@@ -290,9 +296,6 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
cst->getKind() <= Kind::FlatAffineRelation;
}
- /// Replaces the contents of this FlatLinearValueConstraints with `other`.
- void clearAndCopyFrom(const IntegerRelation &other) override;
-
/// Adds a constant bound for the variable associated with the given Value.
void addBound(presburger::BoundType type, Value val, int64_t value);
using FlatLinearConstraints::addBound;
@@ -302,7 +305,9 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
inline Value getValue(unsigned pos) const {
assert(pos < getNumDimAndSymbolVars() && "Invalid position");
assert(hasValue(pos) && "variable's Value not set");
- return *values[pos];
+ VarKind kind = getVarKindAt(pos);
+ unsigned relativePos = pos - getVarKindOffset(kind);
+ return space.getId(kind, relativePos).getValue<Value>();
}
/// Returns the Values associated with variables in range [start, end).
@@ -313,27 +318,47 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
assert(start <= end && "invalid start position");
values->clear();
values->reserve(end - start);
- for (unsigned i = start; i < end; i++)
+ for (unsigned i = start; i < end; ++i)
values->push_back(getValue(i));
}
- inline ArrayRef<std::optional<Value>> getMaybeValues() const {
- return {values.data(), values.size()};
+ inline SmallVector<std::optional<Value>> getMaybeValues() const {
+ SmallVector<std::optional<Value>> maybeValues;
+ maybeValues.reserve(getNumDimAndSymbolVars());
+ for (unsigned i = 0, e = getNumDimAndSymbolVars(); i < e; ++i)
+ if (hasValue(i))
+ maybeValues.push_back(getValue(i));
+ else
+ maybeValues.push_back(std::nullopt);
+ return maybeValues;
}
- inline ArrayRef<std::optional<Value>>
+ inline SmallVector<std::optional<Value>>
getMaybeValues(presburger::VarKind kind) const {
assert(kind != VarKind::Local &&
"Local variables do not have any value attached to them.");
- return {values.data() + getVarKindOffset(kind), getNumVarKind(kind)};
+ SmallVector<std::optional<Value>> maybeValues;
+ maybeValues.reserve(getNumVarKind(kind));
+ for (unsigned i = 0, e = getNumVarKind(kind); i < e; ++i) {
+ const Identifier id = space.getId(kind, i);
+ if (id.hasValue())
+ maybeValues.push_back(id.getValue<Value>());
+ else
+ maybeValues.push_back(std::nullopt);
+ }
+ return maybeValues;
}
/// Returns true if the pos^th variable has an associated Value.
inline bool hasValue(unsigned pos) const {
assert(pos < getNumDimAndSymbolVars() && "Invalid position");
- return values[pos].has_value();
+ VarKind kind = getVarKindAt(pos);
+ unsigned relativePos = pos - getVarKindOffset(kind);
+ return space.getId(kind, relativePos).hasValue();
}
+ void resetValues() { space.resetIds(); }
+
unsigned appendDimVar(ValueRange vals);
using FlatLinearConstraints::appendDimVar;
@@ -360,7 +385,9 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
/// Sets the Value associated with the pos^th variable.
inline void setValue(unsigned pos, Value val) {
assert(pos < getNumDimAndSymbolVars() && "invalid var position");
- values[pos] = val;
+ VarKind kind = getVarKindAt(pos);
+ unsigned relativePos = pos - getVarKindOffset(kind);
+ space.getId(kind, relativePos) = presburger::Identifier(val);
}
/// Sets the Values associated with the variables in the range [start, end).
@@ -387,9 +414,6 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
void projectOut(Value val);
using IntegerPolyhedron::projectOut;
- /// Swap the posA^th variable with the posB^th variable.
- void swapVar(unsigned posA, unsigned posB) override;
-
/// Prints the number of constraints, dimensions, symbols and locals in the
/// FlatAffineValueConstraints. Also, prints for each variable whether there
/// is an SSA Value attached to it.
@@ -444,28 +468,6 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
/// output = {0 <= d0 <= 6, 1 <= d1 <= 15}
LogicalResult unionBoundingBox(const FlatLinearValueConstraints &other);
using IntegerPolyhedron::unionBoundingBox;
-
-protected:
- /// Eliminates the variable at the specified position using Fourier-Motzkin
- /// variable elimination, but uses Gaussian elimination if there is an
- /// equality involving that variable. If the result of the elimination is
- /// integer exact, `*isResultIntegerExact` is set to true. If `darkShadow` is
- /// set to true, a potential under approximation (subset) of the rational
- /// shadow / exact integer shadow is computed.
- // See implementation comments for more details.
- void fourierMotzkinEliminate(unsigned pos, bool darkShadow = false,
- bool *isResultIntegerExact = nullptr) override;
-
- /// Returns false if the fields corresponding to various variable counts, or
- /// equality/inequality buffer sizes aren't consistent; true otherwise. This
- /// is meant to be used within an assert internally.
- bool hasConsistentState() const override;
-
- /// Values corresponding to the (column) non-local variables of this
- /// constraint system appearing in the order the variables correspond to
- /// columns. Variables that aren't associated with any Value are set to
- /// std::nullopt.
- SmallVector<std::optional<Value>, 8> values;
};
/// Flattens 'expr' into 'flattenedExpr', which contains the coefficients of the
diff --git a/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h b/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
index c476a022a48272..a63703e8ef38f0 100644
--- a/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
+++ b/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
@@ -674,6 +674,11 @@ class IntegerRelation {
/// this for uniformity with `applyDomain`.
void applyRange(const IntegerRelation &rel);
+ /// Given a relation `other: (A -> B)`, this operation merges the symbol and
+ /// local variables and then takes the composition of `other` on `this: (B ->
+ /// C)`. The resulting relation represents tuples of the form: `A -> C`.
+ void mergeAndCompose(const IntegerRelation &other);
+
/// Compute an equivalent representation of the same set, such that all local
/// vars in all disjuncts have division representations. This representation
/// may involve local vars that correspond to divisions, and may also be a
diff --git a/mlir/include/mlir/Analysis/Presburger/PresburgerSpace.h b/mlir/include/mlir/Analysis/Presburger/PresburgerSpace.h
index 91ed349f461c69..a2442ede7a2d7a 100644
--- a/mlir/include/mlir/Analysis/Presburger/PresburgerSpace.h
+++ b/mlir/include/mlir/Analysis/Presburger/PresburgerSpace.h
@@ -265,6 +265,8 @@ class PresburgerSpace {
return {identifiers.data() + getVarKindOffset(kind), getNumVarKind(kind)};
}
+ ArrayRef<Identifier> getIds() const { return identifiers; }
+
/// Returns if identifiers are being used.
bool isUsingIds() const { return usingIds; }
diff --git a/mlir/include/mlir/Dialect/Affine/Analysis/AffineAnalysis.h b/mlir/include/mlir/Dialect/Affine/Analysis/AffineAnalysis.h
index a27583877b603c..4134aef8174bc1 100644
--- a/mlir/include/mlir/Dialect/Affine/Analysis/AffineAnalysis.h
+++ b/mlir/include/mlir/Dialect/Affine/Analysis/AffineAnalysis.h
@@ -15,6 +15,7 @@
#ifndef MLIR_DIALECT_AFFINE_ANALYSIS_AFFINEANALYSIS_H
#define MLIR_DIALECT_AFFINE_ANALYSIS_AFFINEANALYSIS_H
+#include "mlir/Analysis/Presburger/IntegerRelation.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/IR/Value.h"
#include "llvm/ADT/SmallVector.h"
@@ -115,7 +116,7 @@ struct MemRefAccess {
///
/// Returns failure for yet unimplemented/unsupported cases (see docs of
/// mlir::getIndexSet and mlir::getRelationFromMap for these cases).
- LogicalResult getAccessRelation(FlatAffineRelation &accessRel) const;
+ LogicalResult getAccessRelation(presburger::IntegerRelation &accessRel) const;
/// Populates 'accessMap' with composition of AffineApplyOps reachable from
/// 'indices'.
diff --git a/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h b/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h
index 7c500f13895af1..c932792fbed756 100644
--- a/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h
+++ b/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h
@@ -251,9 +251,10 @@ class FlatAffineRelation : public FlatAffineValueConstraints {
/// For AffineValueMap, the domain and symbols have Value set corresponding to
/// the Value in `map`. Returns failure if the AffineMap could not be flattened
/// (i.e., semi-affine is not yet handled).
-LogicalResult getRelationFromMap(AffineMap &map, FlatAffineRelation &rel);
+LogicalResult getRelationFromMap(AffineMap &map,
+ presburger::IntegerRelation &rel);
LogicalResult getRelationFromMap(const AffineValueMap &map,
- FlatAffineRelation &rel);
+ presburger::IntegerRelation &rel);
} // namespace affine
} // namespace mlir
diff --git a/mlir/lib/Analysis/FlatLinearValueConstraints.cpp b/mlir/lib/Analysis/FlatLinearValueConstraints.cpp
index 69846a356e0cc4..8a09c741979ffb 100644
--- a/mlir/lib/Analysis/FlatLinearValueConstraints.cpp
+++ b/mlir/lib/Analysis/FlatLinearValueConstraints.cpp
@@ -9,6 +9,7 @@
#include "mlir/Analysis//FlatLinearValueConstraints.h"
#include "mlir/Analysis/Presburger/LinearTransform.h"
+#include "mlir/Analysis/Presburger/PresburgerSpace.h"
#include "mlir/Analysis/Presburger/Simplex.h"
#include "mlir/Analysis/Presburger/Utils.h"
#include "mlir/IR/AffineExprVisitor.h"
@@ -817,13 +818,13 @@ FlatLinearValueConstraints::FlatLinearValueConstraints(IntegerSet set,
set.getNumDims() + set.getNumSymbols() + 1,
set.getNumDims(), set.getNumSymbols(),
/*numLocals=*/0) {
- // Populate values.
- if (operands.empty()) {
- values.resize(getNumDimAndSymbolVars(), std::nullopt);
- } else {
- assert(set.getNumInputs() == operands.size() && "operand count mismatch");
- values.assign(operands.begin(), operands.end());
- }
+ assert(operands.empty() ||
+ set.getNumInputs() == operands.size() && "operand count mismatch");
+ // Use values in space for FlatLinearValueConstraints.
+ space.resetIds();
+ // Set the values for the non-local variables.
+ for (unsigned i = 0, e = operands.size(); i < e; ++i)
+ setValue(i, operands[i]);
// Flatten expressions and add them to the constraint system.
std::vector<SmallVector<int64_t, 8>> flatExprs;
@@ -873,11 +874,6 @@ unsigned FlatLinearValueConstraints::insertVar(VarKind kind, unsigned pos,
unsigned num) {
unsigned absolutePos = IntegerPolyhedron::insertVar(kind, pos, num);
- if (kind != VarKind::Local) {
- values.insert(values.begin() + absolutePos, num, std::nullopt);
- assert(values.size() == getNumDimAndSymbolVars());
- }
-
return absolutePos;
}
@@ -890,11 +886,10 @@ unsigned FlatLinearValueConstraints::insertVar(VarKind kind, unsigned pos,
unsigned absolutePos = IntegerPolyhedron::insertVar(kind, pos, num);
// If a Value is provided, insert it; otherwise use std::nullopt.
- for (unsigned i = 0; i < num; ++i)
- values.insert(values.begin() + absolutePos + i,
- vals[i] ? std::optional<Value>(vals[i]) : std::nullopt);
+ for (unsigned i = 0, e = vals.size(); i < e; ++i)
+ if (vals[i])
+ setValue(absolutePos + i, vals[i]);
- assert(values.size() == getNumDimAndSymbolVars());
return absolutePos;
}
@@ -902,10 +897,14 @@ unsigned FlatLinearValueConstraints::insertVar(VarKind kind, unsigned pos,
/// associated with the same set of variables, appearing in the same order.
static bool areVarsAligned(const FlatLinearValueConstraints &a,
const FlatLinearValueConstraints &b) {
- return a.getNumDimVars() == b.getNumDimVars() &&
- a.getNumSymbolVars() == b.getNumSymbolVars() &&
- a.getNumVars() == b.getNumVars() &&
- a.getMaybeValues().equals(b.getMaybeValues());
+ if (a.getNumDomainVars() != b.getNumDomainVars() ||
+ a.getNumRangeVars() != b.getNumRangeVars() ||
+ a.getNumSymbolVars() != b.getNumSymbolVars())
+ return false;
+ SmallVector<std::optional<Value>> aMaybeValues = a.getMaybeValues(),
+ bMaybeValues = b.getMaybeValues();
+ return std::equal(aMaybeValues.begin(), aMaybeValues.end(),
+ bMaybeValues.begin(), bMaybeValues.end());
}
/// Calls areVarsAligned to check if two constraint systems have the same set
@@ -928,12 +927,14 @@ static bool LLVM_ATTRIBUTE_UNUSED areVarsUnique(
return true;
SmallPtrSet<Value, 8> uniqueVars;
- ArrayRef<std::optional<Value>> maybeValues =
- cst.getMaybeValues().slice(start, end - start);
- for (std::optional<Value> val : maybeValues) {
+ SmallVector<std::optional<Value>, 8> maybeValuesAll = cst.getMaybeValues();
+ ArrayRef<std::optional<Value>> maybeValues = {maybeValuesAll.data() + start,
+ maybeValuesAll.data() + end};
+
+ for (std::optional<Value> val : maybeValues)
if (val && !uniqueVars.insert(*val).second)
return false;
- }
+
return true;
}
@@ -1058,20 +1059,9 @@ void FlatLinearValueConstraints::mergeSymbolVars(
"expected same number of symbols");
}
-bool FlatLinearValueConstraints::hasConsistentState() const {
- return IntegerPolyhedron::hasConsistentState() &&
- values.size() == getNumDimAndSymbolVars();
-}
-
void FlatLinearValueConstraints::removeVarRange(VarKind kind, unsigned varStart,
unsigned varLimit) {
IntegerPolyhedron::removeVarRange(kind, varStart, varLimit);
- unsigned offset = getVarKindOffset(kind);
-
- if (kind != VarKind::Local) {
- values.erase(values.begin() + varStart + offset,
- values.begin() + varLimit + offset);
- }
}
AffineMap
@@ -1089,14 +1079,14 @@ FlatLinearValueConstraints::computeAlignedMap(AffineMap map,
dims.reserve(getNumDimVars());
syms.reserve(getNumSymbolVars());
- for (unsigned i = getVarKindOffset(VarKind::SetDim),
- e = getVarKindEnd(VarKind::SetDim);
- i < e; ++i)
- dims.push_back(values[i] ? *values[i] : Value());
- for (unsigned i = getVarKindOffset(VarKind::Symbol),
- e = getVarKindEnd(VarKind::Symbol);
- i < e; ++i)
- syms.push_back(values[i] ? *values[i] : Value());
+ for (unsigned i = 0, e = getNumVarKind(VarKind::SetDim); i < e; ++i) {
+ Identifier id = space.getId(VarKind::SetDim, i);
+ dims.push_back(id.hasValue() ? Value(id.getValue<Value>()) : Value());
+ }
+ for (unsigned i = 0, e = getNumVarKind(VarKind::Symbol); i < e; ++i) {
+ Identifier id = space.getId(VarKind::Symbol, i);
+ syms.push_back(id.hasValue() ? Value(id.getValue<Value>()) : Value());
+ }
AffineMap alignedMap =
alignAffineMapWithValues(map, operands, dims, syms, newSymsPtr);
@@ -1109,38 +1099,18 @@ FlatLinearValueConstraints::computeAlignedMap(AffineMap map,
bool FlatLinearValueConstraints::findVar(Value val, unsigned *pos,
unsigned offset) const {
- unsigned i = offset;
- for (const auto &mayBeVar :
- ArrayRef<std::optional<Value>>(values).drop_front(offset)) {
- if (mayBeVar && *mayBeVar == val) {
+ SmallVector<std::optional<Value>> maybeValues = getMaybeValues();
+ for (unsigned i = offset, e = maybeValues.size(); i < e; ++i)
+ if (maybeValues[i] && maybeValues[i].value() == val) {
*pos = i;
return true;
}
- i++;
- }
return false;
}
bool FlatLinearValueConstraints::containsVar(Value val) const {
- return llvm::any_of(values, [&](const std::optional<Value> &mayBeVar) {
- return mayBeVar && *mayBeVar == val;
- });
-}
-
-void FlatLinearValueConstraints::swapVar(unsigned posA, unsigned posB) {
- IntegerPolyhedron::swapVar(posA, posB);
-
- if (getVarKindAt(posA) == VarKind::Local &&
- getVarKindAt(posB) == VarKind::Local)
- return;
-
- // Treat value of a local variable as std::nullopt.
- if (getVarKindAt(posA) == VarKind::Local)
- values[posB] = std::nullopt;
- else if (getVarKindAt(posB) == VarKind::Local)
- values[posA] = std::nullopt;
- else
- std::swap(values[posA], values[posB]);
+ unsigned pos;
+ return findVar(val, &pos, 0);
}
void FlatLinearValueConstraints::addBound(BoundType type, Value val,
@@ -1180,31 +1150,6 @@ void FlatLinearValueConstraints::printSpace(raw_ostream &os) const {
os << "const)\n";
}
-void FlatLinearValueConstraints::clearAndCopyFrom(
- const IntegerRelation &other) {
-
- if (auto *otherValueSet =
- dyn_cast<const FlatLinearValueConstraints>(&other)) {
- *this = *otherValueSet;
- ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/77316
More information about the Mlir-commits
mailing list