diff --git a/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h b/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h --- a/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h +++ b/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h @@ -33,7 +33,7 @@ struct MutableAffineMap; /// FlatAffineValueConstraints represents an extension of IntegerPolyhedron -/// where each identifier can have an SSA Value attached to it. +/// where each non-local identifier can have an SSA Value attached to it. class FlatAffineValueConstraints : public presburger::IntegerPolyhedron { public: /// Constructs a constraint system reserving memory for the specified number @@ -48,10 +48,10 @@ presburger::PresburgerSpace::getSetSpace( numDims, numSymbols, numLocals)) { assert(numReservedCols >= getNumIds() + 1); - assert(valArgs.empty() || valArgs.size() == getNumIds()); + assert(valArgs.empty() || valArgs.size() == getNumDimAndSymbolIds()); values.reserve(numReservedCols); if (valArgs.empty()) - values.resize(getNumIds(), None); + values.resize(getNumDimAndSymbolIds(), None); else values.append(valArgs.begin(), valArgs.end()); } @@ -70,9 +70,9 @@ FlatAffineValueConstraints(const IntegerPolyhedron &fac, ArrayRef> valArgs = {}) : IntegerPolyhedron(fac) { - assert(valArgs.empty() || valArgs.size() == getNumIds()); + assert(valArgs.empty() || valArgs.size() == getNumDimAndSymbolIds()); if (valArgs.empty()) - values.resize(getNumIds(), None); + values.resize(getNumDimAndSymbolIds(), None); else values.append(valArgs.begin(), valArgs.end()); } @@ -275,9 +275,10 @@ /// Insert identifiers of the specified kind at position `pos`. Positions are /// relative to the kind of identifier. The coefficient columns corresponding /// to the added identifiers are initialized to zero. `vals` are the Values - /// corresponding to the identifiers. Return the absolute column position - /// (i.e., not relative to the kind of identifier) of the first added - /// identifier. + /// corresponding to the identifiers. Values should not be used with + /// IdKind::Local since values can only be attached to non-local identifiers. + /// Return the absolute column position (i.e., not relative to the kind of + /// identifier) of the first added identifier. /// /// Note: Empty Values are allowed in `vals`. unsigned insertDimId(unsigned pos, unsigned num = 1) { @@ -397,12 +398,16 @@ /// Returns the Value associated with the pos^th identifier. Asserts if /// no Value identifier was associated. inline Value getValue(unsigned pos) const { + assert(pos < getNumDimAndSymbolIds() && "Invalid position"); assert(hasValue(pos) && "identifier's Value not set"); return values[pos].getValue(); } /// Returns true if the pos^th identifier has an associated Value. - inline bool hasValue(unsigned pos) const { return values[pos].hasValue(); } + inline bool hasValue(unsigned pos) const { + assert(pos < getNumDimAndSymbolIds() && "Invalid position"); + return values[pos].hasValue(); + } /// Returns true if at least one identifier has an associated Value. bool hasValues() const; @@ -411,15 +416,15 @@ /// Asserts if no Value was associated with one of these identifiers. inline void getValues(unsigned start, unsigned end, SmallVectorImpl *values) const { - assert((start < getNumIds() || start == end) && "invalid start position"); - assert(end <= getNumIds() && "invalid end position"); + assert(end <= getNumDimAndSymbolIds() && "invalid end position"); + assert(start <= end && "invalid start position"); values->clear(); values->reserve(end - start); for (unsigned i = start; i < end; i++) values->push_back(getValue(i)); } inline void getAllValues(SmallVectorImpl *values) const { - getValues(0, getNumIds(), values); + getValues(0, getNumDimAndSymbolIds(), values); } inline ArrayRef> getMaybeValues() const { @@ -440,15 +445,17 @@ /// Sets the Value associated with the pos^th identifier. inline void setValue(unsigned pos, Value val) { - assert(pos < getNumIds() && "invalid id position"); + assert(pos < getNumDimAndSymbolIds() && "invalid id position"); values[pos] = val; } /// Sets the Values associated with the identifiers in the range [start, end). + /// The range must contain only dim and symbol identifiers. void setValues(unsigned start, unsigned end, ArrayRef values) { - assert((start < getNumIds() || end == start) && "invalid start position"); assert(end <= getNumIds() && "invalid end position"); - assert(values.size() == end - start); + assert(start <= end && "invalid start position"); + assert(values.size() == end - start && + "value should be provided for each identifier in the range."); for (unsigned i = start; i < end; ++i) setValue(i, values[i - start]); } @@ -495,9 +502,9 @@ /// an SSA Value attached to it. void printSpace(raw_ostream &os) const override; - /// Values corresponding to the (column) identifiers of this constraint - /// system appearing in the order the identifiers correspond to columns. - /// Temporary ones or those that aren't associated with any Value are set to + /// Values corresponding to the (column) non-local identifiers of this + /// constraint system appearing in the order the identifiers correspond to + /// columns. Identifiers that aren't associated with any Value are set to /// None. SmallVector, 8> values; }; diff --git a/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp b/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp --- a/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp +++ b/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp @@ -157,7 +157,7 @@ /*numLocals=*/0)) { // Resize values. - values.resize(getNumIds(), None); + values.resize(getNumDimAndSymbolIds(), None); // Flatten expressions and add them to the constraint system. std::vector> flatExprs; @@ -294,14 +294,20 @@ unsigned FlatAffineValueConstraints::insertId(IdKind kind, unsigned pos, unsigned num) { unsigned absolutePos = IntegerPolyhedron::insertId(kind, pos, num); - values.insert(values.begin() + absolutePos, num, None); - assert(values.size() == getNumIds()); + + if (kind != IdKind::Local) { + values.insert(values.begin() + absolutePos, num, None); + assert(values.size() == getNumDimAndSymbolIds()); + } + return absolutePos; } unsigned FlatAffineValueConstraints::insertId(IdKind kind, unsigned pos, ValueRange vals) { - assert(!vals.empty() && "expected ValueRange with Values"); + assert(!vals.empty() && "expected ValueRange with Values."); + assert(kind != IdKind::Local && + "values cannot be attached to local identifiers."); unsigned num = vals.size(); unsigned absolutePos = IntegerPolyhedron::insertId(kind, pos, num); @@ -310,7 +316,7 @@ values.insert(values.begin() + absolutePos + i, vals[i] ? Optional(vals[i]) : None); - assert(values.size() == getNumIds()); + assert(values.size() == getNumDimAndSymbolIds()); return absolutePos; } @@ -342,8 +348,9 @@ static bool LLVM_ATTRIBUTE_UNUSED areIdsUnique( const FlatAffineValueConstraints &cst, unsigned start, unsigned end) { - assert(start <= cst.getNumIds() && "Start position out of bounds"); - assert(end <= cst.getNumIds() && "End position out of bounds"); + assert(start <= cst.getNumDimAndSymbolIds() && + "Start position out of bounds"); + assert(end <= cst.getNumDimAndSymbolIds() && "End position out of bounds"); if (start >= end) return true; @@ -361,7 +368,7 @@ /// Checks if the SSA values associated with `cst`'s identifiers are unique. static bool LLVM_ATTRIBUTE_UNUSED areIdsUnique(const FlatAffineValueConstraints &cst) { - return areIdsUnique(cst, 0, cst.getNumIds()); + return areIdsUnique(cst, 0, cst.getNumDimAndSymbolIds()); } /// Checks if the SSA values associated with `cst`'s identifiers of kind `kind` @@ -373,8 +380,6 @@ return areIdsUnique(cst, 0, cst.getNumDimIds()); if (kind == IdKind::Symbol) return areIdsUnique(cst, cst.getNumDimIds(), cst.getNumDimAndSymbolIds()); - if (kind == IdKind::Local) - return areIdsUnique(cst, cst.getNumDimAndSymbolIds(), cst.getNumIds()); llvm_unreachable("Unexpected IdKind"); } @@ -395,11 +400,11 @@ assert(areIdsUnique(*b) && "B's values aren't unique"); assert(std::all_of(a->getMaybeValues().begin() + offset, - a->getMaybeValues().begin() + a->getNumDimAndSymbolIds(), + a->getMaybeValues().end(), [](Optional id) { return id.hasValue(); })); assert(std::all_of(b->getMaybeValues().begin() + offset, - b->getMaybeValues().begin() + b->getNumDimAndSymbolIds(), + b->getMaybeValues().end(), [](Optional id) { return id.hasValue(); })); SmallVector aDimValues; @@ -703,15 +708,18 @@ bool FlatAffineValueConstraints::hasConsistentState() const { return IntegerPolyhedron::hasConsistentState() && - values.size() == getNumIds(); + values.size() == getNumDimAndSymbolIds(); } void FlatAffineValueConstraints::removeIdRange(IdKind kind, unsigned idStart, unsigned idLimit) { IntegerPolyhedron::removeIdRange(kind, idStart, idLimit); unsigned offset = getIdKindOffset(kind); - values.erase(values.begin() + idStart + offset, - values.begin() + idLimit + offset); + + if (kind != IdKind::Local) { + values.erase(values.begin() + idStart + offset, + values.begin() + idLimit + offset); + } } // Determine whether the identifier at 'pos' (say id_r) can be expressed as @@ -1339,7 +1347,17 @@ void FlatAffineValueConstraints::swapId(unsigned posA, unsigned posB) { IntegerPolyhedron::swapId(posA, posB); - std::swap(values[posA], values[posB]); + + if (getIdKindAt(posA) == IdKind::Local && getIdKindAt(posB) == IdKind::Local) + return; + + // Treat value of a local identifer as None. + if (getIdKindAt(posA) == IdKind::Local) + values[posB] = None; + else if (getIdKindAt(posB) == IdKind::Local) + values[posA] = None; + else + std::swap(values[posA], values[posB]); } void FlatAffineValueConstraints::addBound(BoundType type, Value val, @@ -1354,12 +1372,16 @@ void FlatAffineValueConstraints::printSpace(raw_ostream &os) const { IntegerPolyhedron::printSpace(os); os << "("; - for (unsigned i = 0, e = getNumIds(); i < e; i++) { + for (unsigned i = 0, e = getNumDimAndSymbolIds(); i < e; i++) { if (hasValue(i)) os << "Value "; else os << "None "; } + for (unsigned i = getIdKindOffset(IdKind::Local), + e = getIdKindEnd(IdKind::Local); + i < e; ++i) + os << "Local "; os << " const)\n"; } @@ -1372,21 +1394,20 @@ } else { *static_cast(this) = other; values.clear(); - values.resize(getNumIds(), None); + values.resize(getNumDimAndSymbolIds(), None); } } void FlatAffineValueConstraints::fourierMotzkinEliminate( unsigned pos, bool darkShadow, bool *isResultIntegerExact) { - SmallVector, 8> newVals; - newVals.reserve(getNumIds() - 1); - newVals.append(values.begin(), values.begin() + pos); - newVals.append(values.begin() + pos + 1, values.end()); + SmallVector, 8> newVals = values; + if (getIdKindAt(pos) != IdKind::Local) + newVals.erase(newVals.begin() + pos); // Note: Base implementation discards all associated Values. IntegerPolyhedron::fourierMotzkinEliminate(pos, darkShadow, isResultIntegerExact); values = newVals; - assert(values.size() == getNumIds()); + assert(values.size() == getNumDimAndSymbolIds()); } void FlatAffineValueConstraints::projectOut(Value val) {