mlir/Presburger: strip dependency on MLIRSupport (#96517)
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.
This commit is contained in:
committed by
GitHub
parent
56277948d5
commit
d0fee98e0c
@@ -29,7 +29,6 @@
|
||||
#include "mlir/Analysis/Presburger/Matrix.h"
|
||||
#include "mlir/Analysis/Presburger/PresburgerRelation.h"
|
||||
#include "mlir/Analysis/Presburger/QuasiPolynomial.h"
|
||||
#include <bitset>
|
||||
#include <optional>
|
||||
|
||||
namespace mlir {
|
||||
|
||||
@@ -19,14 +19,15 @@
|
||||
#include "mlir/Analysis/Presburger/Matrix.h"
|
||||
#include "mlir/Analysis/Presburger/PresburgerSpace.h"
|
||||
#include "mlir/Analysis/Presburger/Utils.h"
|
||||
#include "mlir/Support/LogicalResult.h"
|
||||
#include "llvm/ADT/DynamicAPInt.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <optional>
|
||||
|
||||
namespace mlir {
|
||||
namespace presburger {
|
||||
using llvm::DynamicAPInt;
|
||||
using llvm::int64fromDynamicAPInt;
|
||||
using llvm::SmallVectorImpl;
|
||||
|
||||
class IntegerRelation;
|
||||
class IntegerPolyhedron;
|
||||
@@ -477,7 +478,7 @@ public:
|
||||
/// equality detection; if successful, the constant is substituted for the
|
||||
/// variable everywhere in the constraint system and then removed from the
|
||||
/// system.
|
||||
LogicalResult constantFoldVar(unsigned pos);
|
||||
bool constantFoldVar(unsigned pos);
|
||||
|
||||
/// This method calls `constantFoldVar` for the specified range of variables,
|
||||
/// `num` variables starting at position `pos`.
|
||||
@@ -500,7 +501,7 @@ public:
|
||||
/// 3) this = {0 <= d0 <= 5, 1 <= d1 <= 9}
|
||||
/// other = {2 <= d0 <= 6, 5 <= d1 <= 15},
|
||||
/// output = {0 <= d0 <= 6, 1 <= d1 <= 15}
|
||||
LogicalResult unionBoundingBox(const IntegerRelation &other);
|
||||
bool unionBoundingBox(const IntegerRelation &other);
|
||||
|
||||
/// Returns the smallest known constant bound for the extent of the specified
|
||||
/// variable (pos^th), i.e., the smallest known constant that is greater
|
||||
@@ -773,8 +774,8 @@ protected:
|
||||
/// Eliminates a single variable at `position` from equality and inequality
|
||||
/// constraints. Returns `success` if the variable was eliminated, and
|
||||
/// `failure` otherwise.
|
||||
inline LogicalResult gaussianEliminateVar(unsigned position) {
|
||||
return success(gaussianEliminateVars(position, position + 1) == 1);
|
||||
inline bool gaussianEliminateVar(unsigned position) {
|
||||
return gaussianEliminateVars(position, position + 1) == 1;
|
||||
}
|
||||
|
||||
/// Removes local variables using equalities. Each equality is checked if it
|
||||
|
||||
@@ -16,15 +16,16 @@
|
||||
#define MLIR_ANALYSIS_PRESBURGER_MATRIX_H
|
||||
|
||||
#include "mlir/Analysis/Presburger/Fraction.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <cassert>
|
||||
|
||||
namespace mlir {
|
||||
namespace presburger {
|
||||
using llvm::ArrayRef;
|
||||
using llvm::MutableArrayRef;
|
||||
using llvm::raw_ostream;
|
||||
using llvm::SmallVector;
|
||||
|
||||
/// This is a class to represent a resizable matrix.
|
||||
///
|
||||
|
||||
@@ -14,14 +14,16 @@
|
||||
#ifndef MLIR_ANALYSIS_PRESBURGER_PRESBURGERSPACE_H
|
||||
#define MLIR_ANALYSIS_PRESBURGER_PRESBURGERSPACE_H
|
||||
|
||||
#include "mlir/Support/TypeID.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/PointerLikeTypeTraits.h"
|
||||
#include "llvm/Support/TypeName.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace mlir {
|
||||
namespace presburger {
|
||||
using llvm::ArrayRef;
|
||||
using llvm::SmallVector;
|
||||
|
||||
/// Kind of variable. Implementation wise SetDims are treated as Range
|
||||
/// vars, and spaces with no distinction between dimension vars are treated
|
||||
@@ -74,7 +76,7 @@ public:
|
||||
explicit Identifier(T value)
|
||||
: value(llvm::PointerLikeTypeTraits<T>::getAsVoidPointer(value)) {
|
||||
#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
|
||||
idType = TypeID::get<T>();
|
||||
idType = llvm::getTypeName<T>();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -83,7 +85,7 @@ public:
|
||||
template <typename T>
|
||||
T getValue() const {
|
||||
#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
|
||||
assert(TypeID::get<T>() == idType &&
|
||||
assert(llvm::getTypeName<T>() == idType &&
|
||||
"Identifier was initialized with a different type than the one used "
|
||||
"to retrieve it.");
|
||||
#endif
|
||||
@@ -108,7 +110,7 @@ private:
|
||||
|
||||
#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
|
||||
/// TypeID of the identifiers in space. This should be used in asserts only.
|
||||
TypeID idType = TypeID::get<void>();
|
||||
llvm::StringRef idType;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -20,12 +20,7 @@
|
||||
#include "mlir/Analysis/Presburger/Matrix.h"
|
||||
#include "mlir/Analysis/Presburger/PWMAFunction.h"
|
||||
#include "mlir/Analysis/Presburger/Utils.h"
|
||||
#include "mlir/Support/LogicalResult.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallBitVector.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/StringSaver.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <optional>
|
||||
|
||||
namespace mlir {
|
||||
@@ -450,7 +445,7 @@ protected:
|
||||
/// lexicopositivity of the basis transform. The row must have a non-positive
|
||||
/// sample value. If this is not possible, return failure. This occurs when
|
||||
/// the constraints have no solution or the sample value is zero.
|
||||
LogicalResult moveRowUnknownToColumn(unsigned row);
|
||||
bool moveRowUnknownToColumn(unsigned row);
|
||||
|
||||
/// Given a row that has a non-integer sample value, add an inequality to cut
|
||||
/// away this fractional sample value from the polytope without removing any
|
||||
@@ -464,7 +459,7 @@ protected:
|
||||
///
|
||||
/// Return failure if the tableau became empty, and success if it didn't.
|
||||
/// Failure status indicates that the polytope was integer empty.
|
||||
LogicalResult addCut(unsigned row);
|
||||
bool addCut(unsigned row);
|
||||
|
||||
/// Undo the addition of the last constraint. This is only called while
|
||||
/// rolling back.
|
||||
@@ -516,7 +511,7 @@ private:
|
||||
MaybeOptimum<SmallVector<Fraction, 8>> getRationalSample() const;
|
||||
|
||||
/// Make the tableau configuration consistent.
|
||||
LogicalResult restoreRationalConsistency();
|
||||
bool restoreRationalConsistency();
|
||||
|
||||
/// Return whether the specified row is violated;
|
||||
bool rowIsViolated(unsigned row) const;
|
||||
@@ -631,7 +626,7 @@ private:
|
||||
/// Return failure if the tableau became empty, indicating that the polytope
|
||||
/// is always integer empty in the current symbol domain.
|
||||
/// Return success otherwise.
|
||||
LogicalResult doNonBranchingPivots();
|
||||
bool doNonBranchingPivots();
|
||||
|
||||
/// Get a row that is always violated in the current domain, if one exists.
|
||||
std::optional<unsigned> maybeGetAlwaysViolatedRow();
|
||||
@@ -652,7 +647,7 @@ private:
|
||||
/// at the time of the call. (This function may modify the symbol domain, but
|
||||
/// failure statu indicates that the polytope was empty for all symbol values
|
||||
/// in the initial domain.)
|
||||
LogicalResult addSymbolicCut(unsigned row);
|
||||
bool addSymbolicCut(unsigned row);
|
||||
|
||||
/// Get the numerator of the symbolic sample of the specific row.
|
||||
/// This is an affine expression in the symbols with integer coefficients.
|
||||
@@ -825,7 +820,7 @@ private:
|
||||
///
|
||||
/// Returns success if the unknown was successfully restored to a non-negative
|
||||
/// sample value, failure otherwise.
|
||||
LogicalResult restoreRow(Unknown &u);
|
||||
bool restoreRow(Unknown &u);
|
||||
|
||||
/// Find a pivot to change the sample value of row in the specified
|
||||
/// direction while preserving tableau consistency, except that if the
|
||||
|
||||
@@ -13,12 +13,10 @@
|
||||
#ifndef MLIR_ANALYSIS_PRESBURGER_UTILS_H
|
||||
#define MLIR_ANALYSIS_PRESBURGER_UTILS_H
|
||||
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "mlir/Analysis/Presburger/Matrix.h"
|
||||
#include "llvm/ADT/DynamicAPInt.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallBitVector.h"
|
||||
|
||||
#include "mlir/Analysis/Presburger/Matrix.h"
|
||||
#include <optional>
|
||||
|
||||
namespace mlir {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "mlir/IR/Builders.h"
|
||||
#include "mlir/IR/IntegerSet.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "mlir/Support/LogicalResult.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
@@ -1247,10 +1248,10 @@ LogicalResult FlatLinearValueConstraints::unionBoundingBox(
|
||||
if (!areVarsAligned(*this, otherCst)) {
|
||||
FlatLinearValueConstraints otherCopy(otherCst);
|
||||
mergeAndAlignVars(/*offset=*/getNumDimVars(), this, &otherCopy);
|
||||
return IntegerPolyhedron::unionBoundingBox(otherCopy);
|
||||
return success(IntegerPolyhedron::unionBoundingBox(otherCopy));
|
||||
}
|
||||
|
||||
return IntegerPolyhedron::unionBoundingBox(otherCst);
|
||||
return success(IntegerPolyhedron::unionBoundingBox(otherCst));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "mlir/Analysis/Presburger/Utils.h"
|
||||
#include "llvm/ADT/Sequence.h"
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
|
||||
using namespace mlir;
|
||||
using namespace presburger;
|
||||
|
||||
@@ -8,8 +8,4 @@ add_mlir_library(MLIRPresburger
|
||||
PWMAFunction.cpp
|
||||
QuasiPolynomial.cpp
|
||||
Simplex.cpp
|
||||
Utils.cpp
|
||||
|
||||
LINK_LIBS PUBLIC
|
||||
MLIRSupport
|
||||
)
|
||||
Utils.cpp)
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#include "mlir/Analysis/Presburger/PresburgerSpace.h"
|
||||
#include "mlir/Analysis/Presburger/Simplex.h"
|
||||
#include "mlir/Analysis/Presburger/Utils.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "mlir/Support/LogicalResult.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
@@ -1554,22 +1552,22 @@ static int findEqualityToConstant(const IntegerRelation &cst, unsigned pos,
|
||||
return -1;
|
||||
}
|
||||
|
||||
LogicalResult IntegerRelation::constantFoldVar(unsigned pos) {
|
||||
bool IntegerRelation::constantFoldVar(unsigned pos) {
|
||||
assert(pos < getNumVars() && "invalid position");
|
||||
int rowIdx;
|
||||
if ((rowIdx = findEqualityToConstant(*this, pos)) == -1)
|
||||
return failure();
|
||||
return false;
|
||||
|
||||
// atEq(rowIdx, pos) is either -1 or 1.
|
||||
assert(atEq(rowIdx, pos) * atEq(rowIdx, pos) == 1);
|
||||
DynamicAPInt constVal = -atEq(rowIdx, getNumCols() - 1) / atEq(rowIdx, pos);
|
||||
setAndEliminate(pos, constVal);
|
||||
return success();
|
||||
return true;
|
||||
}
|
||||
|
||||
void IntegerRelation::constantFoldVarRange(unsigned pos, unsigned num) {
|
||||
for (unsigned s = pos, t = pos, e = pos + num; s < e; s++) {
|
||||
if (failed(constantFoldVar(t)))
|
||||
if (!constantFoldVar(t))
|
||||
t++;
|
||||
}
|
||||
}
|
||||
@@ -1946,9 +1944,9 @@ void IntegerRelation::fourierMotzkinEliminate(unsigned pos, bool darkShadow,
|
||||
for (unsigned r = 0, e = getNumEqualities(); r < e; r++) {
|
||||
if (atEq(r, pos) != 0) {
|
||||
// Use Gaussian elimination here (since we have an equality).
|
||||
LogicalResult ret = gaussianEliminateVar(pos);
|
||||
bool ret = gaussianEliminateVar(pos);
|
||||
(void)ret;
|
||||
assert(succeeded(ret) && "Gaussian elimination guaranteed to succeed");
|
||||
assert(ret && "Gaussian elimination guaranteed to succeed");
|
||||
LLVM_DEBUG(llvm::dbgs() << "FM output (through Gaussian elimination):\n");
|
||||
LLVM_DEBUG(dump());
|
||||
return;
|
||||
@@ -2175,8 +2173,7 @@ static void getCommonConstraints(const IntegerRelation &a,
|
||||
|
||||
// Computes the bounding box with respect to 'other' by finding the min of the
|
||||
// lower bounds and the max of the upper bounds along each of the dimensions.
|
||||
LogicalResult
|
||||
IntegerRelation::unionBoundingBox(const IntegerRelation &otherCst) {
|
||||
bool IntegerRelation::unionBoundingBox(const IntegerRelation &otherCst) {
|
||||
assert(space.isEqual(otherCst.getSpace()) && "Spaces should match.");
|
||||
assert(getNumLocalVars() == 0 && "local ids not supported yet here");
|
||||
|
||||
@@ -2204,13 +2201,13 @@ IntegerRelation::unionBoundingBox(const IntegerRelation &otherCst) {
|
||||
if (!extent.has_value())
|
||||
// TODO: symbolic extents when necessary.
|
||||
// TODO: handle union if a dimension is unbounded.
|
||||
return failure();
|
||||
return false;
|
||||
|
||||
auto otherExtent = otherCst.getConstantBoundOnDimSize(
|
||||
d, &otherLb, &otherLbFloorDivisor, &otherUb);
|
||||
if (!otherExtent.has_value() || lbFloorDivisor != otherLbFloorDivisor)
|
||||
// TODO: symbolic extents when necessary.
|
||||
return failure();
|
||||
return false;
|
||||
|
||||
assert(lbFloorDivisor > 0 && "divisor always expected to be positive");
|
||||
|
||||
@@ -2230,7 +2227,7 @@ IntegerRelation::unionBoundingBox(const IntegerRelation &otherCst) {
|
||||
auto constLb = getConstantBound(BoundType::LB, d);
|
||||
auto constOtherLb = otherCst.getConstantBound(BoundType::LB, d);
|
||||
if (!constLb.has_value() || !constOtherLb.has_value())
|
||||
return failure();
|
||||
return false;
|
||||
std::fill(minLb.begin(), minLb.end(), 0);
|
||||
minLb.back() = std::min(*constLb, *constOtherLb);
|
||||
}
|
||||
@@ -2246,7 +2243,7 @@ IntegerRelation::unionBoundingBox(const IntegerRelation &otherCst) {
|
||||
auto constUb = getConstantBound(BoundType::UB, d);
|
||||
auto constOtherUb = otherCst.getConstantBound(BoundType::UB, d);
|
||||
if (!constUb.has_value() || !constOtherUb.has_value())
|
||||
return failure();
|
||||
return false;
|
||||
std::fill(maxUb.begin(), maxUb.end(), 0);
|
||||
maxUb.back() = std::max(*constUb, *constOtherUb);
|
||||
}
|
||||
@@ -2284,7 +2281,7 @@ IntegerRelation::unionBoundingBox(const IntegerRelation &otherCst) {
|
||||
// union (since the above are just the union along dimensions); we shouldn't
|
||||
// be discarding any other constraints on the symbols.
|
||||
|
||||
return success();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IntegerRelation::isColZero(unsigned pos) const {
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "mlir/Analysis/Presburger/LinearTransform.h"
|
||||
#include "mlir/Analysis/Presburger/IntegerRelation.h"
|
||||
#include "mlir/Analysis/Presburger/Matrix.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include <utility>
|
||||
|
||||
using namespace mlir;
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "mlir/Analysis/Presburger/Matrix.h"
|
||||
#include "mlir/Analysis/Presburger/Fraction.h"
|
||||
#include "mlir/Analysis/Presburger/Utils.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "mlir/Analysis/Presburger/PresburgerRelation.h"
|
||||
#include "mlir/Analysis/Presburger/PresburgerSpace.h"
|
||||
#include "mlir/Analysis/Presburger/Utils.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/STLFunctionalExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#include "mlir/Analysis/Presburger/PresburgerSpace.h"
|
||||
#include "mlir/Analysis/Presburger/Simplex.h"
|
||||
#include "mlir/Analysis/Presburger/Utils.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "mlir/Support/LogicalResult.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallBitVector.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
@@ -755,18 +753,18 @@ private:
|
||||
/// \___\|/ \_____/
|
||||
///
|
||||
///
|
||||
LogicalResult coalescePairCutCase(unsigned i, unsigned j);
|
||||
bool coalescePairCutCase(unsigned i, unsigned j);
|
||||
|
||||
/// Types the inequality `ineq` according to its `IneqType` for `simp` into
|
||||
/// `redundantIneqsB` and `cuttingIneqsB`. Returns success, if no separate
|
||||
/// inequalities were encountered. Otherwise, returns failure.
|
||||
LogicalResult typeInequality(ArrayRef<DynamicAPInt> ineq, Simplex &simp);
|
||||
bool typeInequality(ArrayRef<DynamicAPInt> ineq, Simplex &simp);
|
||||
|
||||
/// Types the equality `eq`, i.e. for `eq` == 0, types both `eq` >= 0 and
|
||||
/// -`eq` >= 0 according to their `IneqType` for `simp` into
|
||||
/// `redundantIneqsB` and `cuttingIneqsB`. Returns success, if no separate
|
||||
/// inequalities were encountered. Otherwise, returns failure.
|
||||
LogicalResult typeEquality(ArrayRef<DynamicAPInt> eq, Simplex &simp);
|
||||
bool typeEquality(ArrayRef<DynamicAPInt> eq, Simplex &simp);
|
||||
|
||||
/// Replaces the element at position `i` with the last element and erases
|
||||
/// the last element for both `disjuncts` and `simplices`.
|
||||
@@ -777,7 +775,7 @@ private:
|
||||
/// successfully coalesced. The simplices in `simplices` need to be the ones
|
||||
/// constructed from `disjuncts`. At this point, there are no empty
|
||||
/// disjuncts in `disjuncts` left.
|
||||
LogicalResult coalescePair(unsigned i, unsigned j);
|
||||
bool coalescePair(unsigned i, unsigned j);
|
||||
};
|
||||
|
||||
/// Constructs a `SetCoalescer` from a `PresburgerRelation`. Only adds non-empty
|
||||
@@ -820,7 +818,7 @@ PresburgerRelation SetCoalescer::coalesce() {
|
||||
cuttingIneqsB.clear();
|
||||
if (i == j)
|
||||
continue;
|
||||
if (coalescePair(i, j).succeeded()) {
|
||||
if (coalescePair(i, j)) {
|
||||
broken = true;
|
||||
break;
|
||||
}
|
||||
@@ -904,7 +902,7 @@ void SetCoalescer::addCoalescedDisjunct(unsigned i, unsigned j,
|
||||
/// \___\|/ \_____/
|
||||
///
|
||||
///
|
||||
LogicalResult SetCoalescer::coalescePairCutCase(unsigned i, unsigned j) {
|
||||
bool SetCoalescer::coalescePairCutCase(unsigned i, unsigned j) {
|
||||
/// All inequalities of `b` need to be redundant. We already know that the
|
||||
/// redundant ones are, so only the cutting ones remain to be checked.
|
||||
Simplex &simp = simplices[i];
|
||||
@@ -912,7 +910,7 @@ LogicalResult SetCoalescer::coalescePairCutCase(unsigned i, unsigned j) {
|
||||
if (llvm::any_of(cuttingIneqsA, [this, &simp](ArrayRef<DynamicAPInt> curr) {
|
||||
return !isFacetContained(curr, simp);
|
||||
}))
|
||||
return failure();
|
||||
return false;
|
||||
IntegerRelation newSet(disjunct.getSpace());
|
||||
|
||||
for (ArrayRef<DynamicAPInt> curr : redundantIneqsA)
|
||||
@@ -922,30 +920,26 @@ LogicalResult SetCoalescer::coalescePairCutCase(unsigned i, unsigned j) {
|
||||
newSet.addInequality(curr);
|
||||
|
||||
addCoalescedDisjunct(i, j, newSet);
|
||||
return success();
|
||||
return true;
|
||||
}
|
||||
|
||||
LogicalResult SetCoalescer::typeInequality(ArrayRef<DynamicAPInt> ineq,
|
||||
Simplex &simp) {
|
||||
bool SetCoalescer::typeInequality(ArrayRef<DynamicAPInt> ineq, Simplex &simp) {
|
||||
Simplex::IneqType type = simp.findIneqType(ineq);
|
||||
if (type == Simplex::IneqType::Redundant)
|
||||
redundantIneqsB.push_back(ineq);
|
||||
else if (type == Simplex::IneqType::Cut)
|
||||
cuttingIneqsB.push_back(ineq);
|
||||
else
|
||||
return failure();
|
||||
return success();
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
LogicalResult SetCoalescer::typeEquality(ArrayRef<DynamicAPInt> eq,
|
||||
Simplex &simp) {
|
||||
if (typeInequality(eq, simp).failed())
|
||||
return failure();
|
||||
bool SetCoalescer::typeEquality(ArrayRef<DynamicAPInt> eq, Simplex &simp) {
|
||||
if (!typeInequality(eq, simp))
|
||||
return false;
|
||||
negEqs.push_back(getNegatedCoeffs(eq));
|
||||
ArrayRef<DynamicAPInt> inv(negEqs.back());
|
||||
if (typeInequality(inv, simp).failed())
|
||||
return failure();
|
||||
return success();
|
||||
return typeInequality(inv, simp);
|
||||
}
|
||||
|
||||
void SetCoalescer::eraseDisjunct(unsigned i) {
|
||||
@@ -957,7 +951,7 @@ void SetCoalescer::eraseDisjunct(unsigned i) {
|
||||
simplices.pop_back();
|
||||
}
|
||||
|
||||
LogicalResult SetCoalescer::coalescePair(unsigned i, unsigned j) {
|
||||
bool SetCoalescer::coalescePair(unsigned i, unsigned j) {
|
||||
|
||||
IntegerRelation &a = disjuncts[i];
|
||||
IntegerRelation &b = disjuncts[j];
|
||||
@@ -965,7 +959,7 @@ LogicalResult SetCoalescer::coalescePair(unsigned i, unsigned j) {
|
||||
/// skipped.
|
||||
/// TODO: implement local id support.
|
||||
if (a.getNumLocalVars() != 0 || b.getNumLocalVars() != 0)
|
||||
return failure();
|
||||
return false;
|
||||
Simplex &simpA = simplices[i];
|
||||
Simplex &simpB = simplices[j];
|
||||
|
||||
@@ -975,34 +969,34 @@ LogicalResult SetCoalescer::coalescePair(unsigned i, unsigned j) {
|
||||
// inequality is encountered during typing, the two IntegerRelations
|
||||
// cannot be coalesced.
|
||||
for (int k = 0, e = a.getNumInequalities(); k < e; ++k)
|
||||
if (typeInequality(a.getInequality(k), simpB).failed())
|
||||
return failure();
|
||||
if (!typeInequality(a.getInequality(k), simpB))
|
||||
return false;
|
||||
|
||||
for (int k = 0, e = a.getNumEqualities(); k < e; ++k)
|
||||
if (typeEquality(a.getEquality(k), simpB).failed())
|
||||
return failure();
|
||||
if (!typeEquality(a.getEquality(k), simpB))
|
||||
return false;
|
||||
|
||||
std::swap(redundantIneqsA, redundantIneqsB);
|
||||
std::swap(cuttingIneqsA, cuttingIneqsB);
|
||||
|
||||
for (int k = 0, e = b.getNumInequalities(); k < e; ++k)
|
||||
if (typeInequality(b.getInequality(k), simpA).failed())
|
||||
return failure();
|
||||
if (!typeInequality(b.getInequality(k), simpA))
|
||||
return false;
|
||||
|
||||
for (int k = 0, e = b.getNumEqualities(); k < e; ++k)
|
||||
if (typeEquality(b.getEquality(k), simpA).failed())
|
||||
return failure();
|
||||
if (!typeEquality(b.getEquality(k), simpA))
|
||||
return false;
|
||||
|
||||
// If there are no cutting inequalities of `a`, `b` is contained
|
||||
// within `a`.
|
||||
if (cuttingIneqsA.empty()) {
|
||||
eraseDisjunct(j);
|
||||
return success();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to apply the cut case
|
||||
if (coalescePairCutCase(i, j).succeeded())
|
||||
return success();
|
||||
if (coalescePairCutCase(i, j))
|
||||
return true;
|
||||
|
||||
// Swap the vectors to compare the pair (j,i) instead of (i,j).
|
||||
std::swap(redundantIneqsA, redundantIneqsB);
|
||||
@@ -1012,14 +1006,11 @@ LogicalResult SetCoalescer::coalescePair(unsigned i, unsigned j) {
|
||||
// within `a`.
|
||||
if (cuttingIneqsA.empty()) {
|
||||
eraseDisjunct(i);
|
||||
return success();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to apply the cut case
|
||||
if (coalescePairCutCase(j, i).succeeded())
|
||||
return success();
|
||||
|
||||
return failure();
|
||||
return coalescePairCutCase(j, i);
|
||||
}
|
||||
|
||||
PresburgerRelation PresburgerRelation::coalesce() const {
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "mlir/Analysis/Presburger/QuasiPolynomial.h"
|
||||
#include "mlir/Analysis/Presburger/Fraction.h"
|
||||
#include "mlir/Analysis/Presburger/PresburgerSpace.h"
|
||||
#include "mlir/Analysis/Presburger/Utils.h"
|
||||
|
||||
using namespace mlir;
|
||||
using namespace presburger;
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#include "mlir/Analysis/Presburger/Matrix.h"
|
||||
#include "mlir/Analysis/Presburger/PresburgerSpace.h"
|
||||
#include "mlir/Analysis/Presburger/Utils.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "mlir/Support/LogicalResult.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallBitVector.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
@@ -231,7 +229,7 @@ Direction flippedDirection(Direction direction) {
|
||||
/// add these to the set of ignored columns and continue to the next row. If we
|
||||
/// run out of rows, then A*y is zero and we are done.
|
||||
MaybeOptimum<SmallVector<Fraction, 8>> LexSimplex::findRationalLexMin() {
|
||||
if (restoreRationalConsistency().failed()) {
|
||||
if (!restoreRationalConsistency()) {
|
||||
markEmpty();
|
||||
return OptimumKind::Empty;
|
||||
}
|
||||
@@ -276,7 +274,7 @@ MaybeOptimum<SmallVector<Fraction, 8>> LexSimplex::findRationalLexMin() {
|
||||
///
|
||||
/// The constraint is violated when added (it would be useless otherwise)
|
||||
/// so we immediately try to move it to a column.
|
||||
LogicalResult LexSimplexBase::addCut(unsigned row) {
|
||||
bool LexSimplexBase::addCut(unsigned row) {
|
||||
DynamicAPInt d = tableau(row, 0);
|
||||
unsigned cutRow = addZeroRow(/*makeRestricted=*/true);
|
||||
tableau(cutRow, 0) = d;
|
||||
@@ -303,7 +301,7 @@ std::optional<unsigned> LexSimplex::maybeGetNonIntegralVarRow() const {
|
||||
|
||||
MaybeOptimum<SmallVector<DynamicAPInt, 8>> LexSimplex::findIntegerLexMin() {
|
||||
// We first try to make the tableau consistent.
|
||||
if (restoreRationalConsistency().failed())
|
||||
if (!restoreRationalConsistency())
|
||||
return OptimumKind::Empty;
|
||||
|
||||
// Then, if the sample value is integral, we are done.
|
||||
@@ -318,9 +316,9 @@ MaybeOptimum<SmallVector<DynamicAPInt, 8>> LexSimplex::findIntegerLexMin() {
|
||||
//
|
||||
// Failure indicates that the tableau became empty, which occurs when the
|
||||
// polytope is integer empty.
|
||||
if (addCut(*maybeRow).failed())
|
||||
if (!addCut(*maybeRow))
|
||||
return OptimumKind::Empty;
|
||||
if (restoreRationalConsistency().failed())
|
||||
if (!restoreRationalConsistency())
|
||||
return OptimumKind::Empty;
|
||||
}
|
||||
|
||||
@@ -413,7 +411,7 @@ bool SymbolicLexSimplex::isSymbolicSampleIntegral(unsigned row) const {
|
||||
/// (sum_i (b_i%d)y_i - (-c%d) - sum_i (-a_i%d)s_i + q*d)/d >= 0
|
||||
/// This constraint is violated when added so we immediately try to move it to a
|
||||
/// column.
|
||||
LogicalResult SymbolicLexSimplex::addSymbolicCut(unsigned row) {
|
||||
bool SymbolicLexSimplex::addSymbolicCut(unsigned row) {
|
||||
DynamicAPInt d = tableau(row, 0);
|
||||
if (isRangeDivisibleBy(tableau.getRow(row).slice(3, nSymbol), d)) {
|
||||
// The coefficients of symbols in the symbol numerator are divisible
|
||||
@@ -525,11 +523,11 @@ std::optional<unsigned> SymbolicLexSimplex::maybeGetNonIntegralVarRow() {
|
||||
|
||||
/// The non-branching pivots are just the ones moving the rows
|
||||
/// that are always violated in the symbol domain.
|
||||
LogicalResult SymbolicLexSimplex::doNonBranchingPivots() {
|
||||
bool SymbolicLexSimplex::doNonBranchingPivots() {
|
||||
while (std::optional<unsigned> row = maybeGetAlwaysViolatedRow())
|
||||
if (moveRowUnknownToColumn(*row).failed())
|
||||
return failure();
|
||||
return success();
|
||||
if (!moveRowUnknownToColumn(*row))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
SymbolicLexOpt SymbolicLexSimplex::computeSymbolicIntegerLexMin() {
|
||||
@@ -569,7 +567,7 @@ SymbolicLexOpt SymbolicLexSimplex::computeSymbolicIntegerLexMin() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (doNonBranchingPivots().failed()) {
|
||||
if (!doNonBranchingPivots()) {
|
||||
// Could not find pivots for violated constraints; return.
|
||||
--level;
|
||||
continue;
|
||||
@@ -629,7 +627,7 @@ SymbolicLexOpt SymbolicLexSimplex::computeSymbolicIntegerLexMin() {
|
||||
// The tableau is rationally consistent for the current domain.
|
||||
// Now we look for non-integral sample values and add cuts for them.
|
||||
if (std::optional<unsigned> row = maybeGetNonIntegralVarRow()) {
|
||||
if (addSymbolicCut(*row).failed()) {
|
||||
if (!addSymbolicCut(*row)) {
|
||||
// No integral points; return.
|
||||
--level;
|
||||
continue;
|
||||
@@ -663,7 +661,7 @@ SymbolicLexOpt SymbolicLexSimplex::computeSymbolicIntegerLexMin() {
|
||||
SmallVector<DynamicAPInt, 8> splitIneq =
|
||||
getComplementIneq(getSymbolicSampleIneq(u.pos));
|
||||
normalizeRange(splitIneq);
|
||||
if (moveRowUnknownToColumn(u.pos).failed()) {
|
||||
if (!moveRowUnknownToColumn(u.pos)) {
|
||||
// The unknown can't be made non-negative; return.
|
||||
--level;
|
||||
continue;
|
||||
@@ -701,13 +699,13 @@ std::optional<unsigned> LexSimplex::maybeGetViolatedRow() const {
|
||||
/// We simply look for violated rows and keep trying to move them to column
|
||||
/// orientation, which always succeeds unless the constraints have no solution
|
||||
/// in which case we just give up and return.
|
||||
LogicalResult LexSimplex::restoreRationalConsistency() {
|
||||
bool LexSimplex::restoreRationalConsistency() {
|
||||
if (empty)
|
||||
return failure();
|
||||
return false;
|
||||
while (std::optional<unsigned> maybeViolatedRow = maybeGetViolatedRow())
|
||||
if (moveRowUnknownToColumn(*maybeViolatedRow).failed())
|
||||
return failure();
|
||||
return success();
|
||||
if (!moveRowUnknownToColumn(*maybeViolatedRow))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Move the row unknown to column orientation while preserving lexicopositivity
|
||||
@@ -772,7 +770,7 @@ LogicalResult LexSimplex::restoreRationalConsistency() {
|
||||
// which is in contradiction to the fact that B.col(j) / B(i,j) must be
|
||||
// lexicographically smaller than B.col(k) / B(i,k), since it lexicographically
|
||||
// minimizes the change in sample value.
|
||||
LogicalResult LexSimplexBase::moveRowUnknownToColumn(unsigned row) {
|
||||
bool LexSimplexBase::moveRowUnknownToColumn(unsigned row) {
|
||||
std::optional<unsigned> maybeColumn;
|
||||
for (unsigned col = 3 + nSymbol, e = getNumColumns(); col < e; ++col) {
|
||||
if (tableau(row, col) <= 0)
|
||||
@@ -782,10 +780,10 @@ LogicalResult LexSimplexBase::moveRowUnknownToColumn(unsigned row) {
|
||||
}
|
||||
|
||||
if (!maybeColumn)
|
||||
return failure();
|
||||
return false;
|
||||
|
||||
pivot(row, *maybeColumn);
|
||||
return success();
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned LexSimplexBase::getLexMinPivotColumn(unsigned row, unsigned colA,
|
||||
@@ -988,7 +986,7 @@ void SimplexBase::pivot(unsigned pivotRow, unsigned pivotCol) {
|
||||
/// Perform pivots until the unknown has a non-negative sample value or until
|
||||
/// no more upward pivots can be performed. Return success if we were able to
|
||||
/// bring the row to a non-negative sample value, and failure otherwise.
|
||||
LogicalResult Simplex::restoreRow(Unknown &u) {
|
||||
bool Simplex::restoreRow(Unknown &u) {
|
||||
assert(u.orientation == Orientation::Row &&
|
||||
"unknown should be in row position");
|
||||
|
||||
@@ -999,9 +997,9 @@ LogicalResult Simplex::restoreRow(Unknown &u) {
|
||||
|
||||
pivot(*maybePivot);
|
||||
if (u.orientation == Orientation::Column)
|
||||
return success(); // the unknown is unbounded above.
|
||||
return true; // the unknown is unbounded above.
|
||||
}
|
||||
return success(tableau(u.pos, 1) >= 0);
|
||||
return tableau(u.pos, 1) >= 0;
|
||||
}
|
||||
|
||||
/// Find a row that can be used to pivot the column in the specified direction.
|
||||
@@ -1107,8 +1105,8 @@ void SimplexBase::markEmpty() {
|
||||
/// empty and we mark it as such.
|
||||
void Simplex::addInequality(ArrayRef<DynamicAPInt> coeffs) {
|
||||
unsigned conIndex = addRow(coeffs, /*makeRestricted=*/true);
|
||||
LogicalResult result = restoreRow(con[conIndex]);
|
||||
if (failed(result))
|
||||
bool result = restoreRow(con[conIndex]);
|
||||
if (!result)
|
||||
markEmpty();
|
||||
}
|
||||
|
||||
@@ -1386,7 +1384,7 @@ MaybeOptimum<Fraction> Simplex::computeOptimum(Direction direction,
|
||||
MaybeOptimum<Fraction> optimum = computeRowOptimum(direction, row);
|
||||
if (u.restricted && direction == Direction::Down &&
|
||||
(optimum.isUnbounded() || *optimum < Fraction(0, 1))) {
|
||||
if (failed(restoreRow(u)))
|
||||
if (!restoreRow(u))
|
||||
llvm_unreachable("Could not restore row!");
|
||||
}
|
||||
return optimum;
|
||||
@@ -1455,7 +1453,7 @@ void Simplex::detectRedundant(unsigned offset, unsigned count) {
|
||||
if (minimum.isUnbounded() || *minimum < Fraction(0, 1)) {
|
||||
// Constraint is unbounded below or can attain negative sample values and
|
||||
// hence is not redundant.
|
||||
if (failed(restoreRow(u)))
|
||||
if (!restoreRow(u))
|
||||
llvm_unreachable("Could not restore non-redundant row!");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -13,18 +13,11 @@
|
||||
#include "mlir/Analysis/Presburger/Utils.h"
|
||||
#include "mlir/Analysis/Presburger/IntegerRelation.h"
|
||||
#include "mlir/Analysis/Presburger/PresburgerSpace.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "mlir/Support/LogicalResult.h"
|
||||
#include "llvm/ADT/STLFunctionalExtras.h"
|
||||
#include "llvm/ADT/SmallBitVector.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <numeric>
|
||||
|
||||
#include <numeric>
|
||||
#include <optional>
|
||||
|
||||
@@ -102,10 +95,10 @@ static void normalizeDivisionByGCD(MutableArrayRef<DynamicAPInt> dividend,
|
||||
/// If successful, `expr` is set to dividend of the division and `divisor` is
|
||||
/// set to the denominator of the division, which will be positive.
|
||||
/// The final division expression is normalized by GCD.
|
||||
static LogicalResult getDivRepr(const IntegerRelation &cst, unsigned pos,
|
||||
unsigned ubIneq, unsigned lbIneq,
|
||||
MutableArrayRef<DynamicAPInt> expr,
|
||||
DynamicAPInt &divisor) {
|
||||
static bool getDivRepr(const IntegerRelation &cst, unsigned pos,
|
||||
unsigned ubIneq, unsigned lbIneq,
|
||||
MutableArrayRef<DynamicAPInt> expr,
|
||||
DynamicAPInt &divisor) {
|
||||
|
||||
assert(pos <= cst.getNumVars() && "Invalid variable position");
|
||||
assert(ubIneq <= cst.getNumInequalities() &&
|
||||
@@ -127,7 +120,7 @@ static LogicalResult getDivRepr(const IntegerRelation &cst, unsigned pos,
|
||||
break;
|
||||
|
||||
if (i < e)
|
||||
return failure();
|
||||
return false;
|
||||
|
||||
// Then, check if the constant term is of the proper form.
|
||||
// Due to the form of the upper/lower bound inequalities, the sum of their
|
||||
@@ -139,7 +132,7 @@ static LogicalResult getDivRepr(const IntegerRelation &cst, unsigned pos,
|
||||
// Check if `c` satisfies the condition `0 <= c <= divisor - 1`.
|
||||
// This also implictly checks that `divisor` is positive.
|
||||
if (!(0 <= c && c <= divisor - 1)) // NOLINT
|
||||
return failure();
|
||||
return false;
|
||||
|
||||
// The inequality pair can be used to extract the division.
|
||||
// Set `expr` to the dividend of the division except the constant term, which
|
||||
@@ -154,7 +147,7 @@ static LogicalResult getDivRepr(const IntegerRelation &cst, unsigned pos,
|
||||
expr.back() = cst.atIneq(ubIneq, cst.getNumCols() - 1) + c;
|
||||
normalizeDivisionByGCD(expr, divisor);
|
||||
|
||||
return success();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Check if the pos^th variable can be represented as a division using
|
||||
@@ -168,10 +161,9 @@ static LogicalResult getDivRepr(const IntegerRelation &cst, unsigned pos,
|
||||
/// If successful, `expr` is set to dividend of the division and `divisor` is
|
||||
/// set to the denominator of the division. The final division expression is
|
||||
/// normalized by GCD.
|
||||
static LogicalResult getDivRepr(const IntegerRelation &cst, unsigned pos,
|
||||
unsigned eqInd,
|
||||
MutableArrayRef<DynamicAPInt> expr,
|
||||
DynamicAPInt &divisor) {
|
||||
static bool getDivRepr(const IntegerRelation &cst, unsigned pos, unsigned eqInd,
|
||||
MutableArrayRef<DynamicAPInt> expr,
|
||||
DynamicAPInt &divisor) {
|
||||
|
||||
assert(pos <= cst.getNumVars() && "Invalid variable position");
|
||||
assert(eqInd <= cst.getNumEqualities() && "Invalid equality position");
|
||||
@@ -182,7 +174,7 @@ static LogicalResult getDivRepr(const IntegerRelation &cst, unsigned pos,
|
||||
// Equality must involve the pos-th variable and hence `tempDiv` != 0.
|
||||
DynamicAPInt tempDiv = cst.atEq(eqInd, pos);
|
||||
if (tempDiv == 0)
|
||||
return failure();
|
||||
return false;
|
||||
int signDiv = tempDiv < 0 ? -1 : 1;
|
||||
|
||||
// The divisor is always a positive integer.
|
||||
@@ -195,7 +187,7 @@ static LogicalResult getDivRepr(const IntegerRelation &cst, unsigned pos,
|
||||
expr.back() = -signDiv * cst.atEq(eqInd, cst.getNumCols() - 1);
|
||||
normalizeDivisionByGCD(expr, divisor);
|
||||
|
||||
return success();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns `false` if the constraints depends on a variable for which an
|
||||
@@ -246,7 +238,7 @@ MaybeLocalRepr presburger::computeSingleVarRepr(
|
||||
for (unsigned ubPos : ubIndices) {
|
||||
for (unsigned lbPos : lbIndices) {
|
||||
// Attempt to get divison representation from ubPos, lbPos.
|
||||
if (failed(getDivRepr(cst, pos, ubPos, lbPos, dividend, divisor)))
|
||||
if (!getDivRepr(cst, pos, ubPos, lbPos, dividend, divisor))
|
||||
continue;
|
||||
|
||||
if (!checkExplicitRepresentation(cst, foundRepr, dividend, pos))
|
||||
@@ -259,7 +251,7 @@ MaybeLocalRepr presburger::computeSingleVarRepr(
|
||||
}
|
||||
for (unsigned eqPos : eqIndices) {
|
||||
// Attempt to get divison representation from eqPos.
|
||||
if (failed(getDivRepr(cst, pos, eqPos, dividend, divisor)))
|
||||
if (!getDivRepr(cst, pos, eqPos, dividend, divisor))
|
||||
continue;
|
||||
|
||||
if (!checkExplicitRepresentation(cst, foundRepr, dividend, pos))
|
||||
|
||||
@@ -16,12 +16,7 @@
|
||||
#include "mlir/Analysis/Presburger/GeneratingFunction.h"
|
||||
#include "mlir/Analysis/Presburger/IntegerRelation.h"
|
||||
#include "mlir/Analysis/Presburger/Matrix.h"
|
||||
#include "mlir/Analysis/Presburger/PWMAFunction.h"
|
||||
#include "mlir/Analysis/Presburger/PresburgerRelation.h"
|
||||
#include "mlir/Analysis/Presburger/QuasiPolynomial.h"
|
||||
#include "mlir/Analysis/Presburger/Simplex.h"
|
||||
#include "mlir/IR/MLIRContext.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <optional>
|
||||
|
||||
Reference in New Issue
Block a user