Skip to content

Commit 9e6e081

Browse files
[mlir][Analysis][NFC] Reimplement FlatAffineConstraints::composeMap
Reimplement this function in terms of `composeMatchingMap`. Also fix a bug in `composeMatchingMap` where local dims of `this` could be missing in `localCst`. Differential Revision: https://reviews.llvm.org/D107813
1 parent 61526b1 commit 9e6e081

File tree

2 files changed

+43
-98
lines changed

2 files changed

+43
-98
lines changed

mlir/include/mlir/Analysis/AffineStructures.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -350,16 +350,15 @@ class FlatAffineConstraints {
350350
/// and with the dimensions set to the equalities specified by the value map.
351351
/// Returns failure if the composition fails (when vMap is a semi-affine map).
352352
/// The vMap's operand Value's are used to look up the right positions in
353-
/// the FlatAffineConstraints with which to associate. The dimensional and
354-
/// symbolic operands of vMap should match 1:1 (in the same order) with those
355-
/// of this constraint system, but the latter could have additional trailing
356-
/// operands.
353+
/// the FlatAffineConstraints with which to associate. Every operand of vMap
354+
/// should have a matching dim/symbol column in this constraint system (with
355+
/// the same associated Value).
357356
LogicalResult composeMap(const AffineValueMap *vMap);
358357

359-
/// Composes an affine map whose dimensions match one to one to the
360-
/// dimensions of this FlatAffineConstraints. The results of the map 'other'
361-
/// are added as the leading dimensions of this constraint system. Returns
362-
/// failure if 'other' is a semi-affine map.
358+
/// Composes an affine map whose dimensions and symbols match one to one with
359+
/// the dimensions and symbols of this FlatAffineConstraints. The results of
360+
/// the map `other` are added as the leading dimensions of this constraint
361+
/// system. Returns failure if `other` is a semi-affine map.
363362
LogicalResult composeMatchingMap(AffineMap other);
364363

365364
/// Projects out (aka eliminates) 'num' identifiers starting at position
@@ -599,6 +598,10 @@ class FlatAffineConstraints {
599598
template <bool isLower>
600599
Optional<int64_t> computeConstantLowerOrUpperBound(unsigned pos);
601600

601+
/// Align `map` with this constraint system based on `operands`. Each operand
602+
/// must already have a corresponding dim/symbol in this constraint system.
603+
AffineMap computeAlignedMap(AffineMap map, ValueRange operands) const;
604+
602605
// Eliminates a single identifier at 'position' from equality and inequality
603606
// constraints. Returns 'success' if the identifier was eliminated, and
604607
// 'failure' otherwise.

mlir/lib/Analysis/AffineStructures.cpp

Lines changed: 32 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -387,81 +387,14 @@ void FlatAffineConstraints::mergeAndAlignIdsWithOther(
387387
mergeAndAlignIds(offset, this, other);
388388
}
389389

390-
// This routine may add additional local variables if the flattened expression
391-
// corresponding to the map has such variables due to mod's, ceildiv's, and
392-
// floordiv's in it.
393390
LogicalResult FlatAffineConstraints::composeMap(const AffineValueMap *vMap) {
394-
std::vector<SmallVector<int64_t, 8>> flatExprs;
395-
FlatAffineConstraints localCst;
396-
if (failed(getFlattenedAffineExprs(vMap->getAffineMap(), &flatExprs,
397-
&localCst))) {
398-
LLVM_DEBUG(llvm::dbgs()
399-
<< "composition unimplemented for semi-affine maps\n");
400-
return failure();
401-
}
402-
assert(flatExprs.size() == vMap->getNumResults());
403-
404-
// Add localCst information.
405-
if (localCst.getNumLocalIds() > 0) {
406-
localCst.setIdValues(0, /*end=*/localCst.getNumDimAndSymbolIds(),
407-
/*values=*/vMap->getOperands());
408-
// Align localCst and this.
409-
mergeAndAlignIds(/*offset=*/0, &localCst, this);
410-
// Finally, append localCst to this constraint set.
411-
append(localCst);
412-
}
413-
414-
// Add dimensions corresponding to the map's results.
415-
for (unsigned t = 0, e = vMap->getNumResults(); t < e; t++) {
416-
// TODO: Consider using a batched version to add a range of IDs.
417-
addDimId(0);
418-
}
419-
420-
// We add one equality for each result connecting the result dim of the map to
421-
// the other identifiers.
422-
// For eg: if the expression is 16*i0 + i1, and this is the r^th
423-
// iteration/result of the value map, we are adding the equality:
424-
// d_r - 16*i0 - i1 = 0. Hence, when flattening say (i0 + 1, i0 + 8*i2), we
425-
// add two equalities overall: d_0 - i0 - 1 == 0, d1 - i0 - 8*i2 == 0.
426-
for (unsigned r = 0, e = flatExprs.size(); r < e; r++) {
427-
const auto &flatExpr = flatExprs[r];
428-
assert(flatExpr.size() >= vMap->getNumOperands() + 1);
429-
430-
// eqToAdd is the equality corresponding to the flattened affine expression.
431-
SmallVector<int64_t, 8> eqToAdd(getNumCols(), 0);
432-
// Set the coefficient for this result to one.
433-
eqToAdd[r] = 1;
434-
435-
// Dims and symbols.
436-
for (unsigned i = 0, e = vMap->getNumOperands(); i < e; i++) {
437-
unsigned loc;
438-
bool ret = findId(vMap->getOperand(i), &loc);
439-
assert(ret && "value map's id can't be found");
440-
(void)ret;
441-
// Negate 'eq[r]' since the newly added dimension will be set to this one.
442-
eqToAdd[loc] = -flatExpr[i];
443-
}
444-
// Local vars common to eq and localCst are at the beginning.
445-
unsigned j = getNumDimIds() + getNumSymbolIds();
446-
unsigned end = flatExpr.size() - 1;
447-
for (unsigned i = vMap->getNumOperands(); i < end; i++, j++) {
448-
eqToAdd[j] = -flatExpr[i];
449-
}
450-
451-
// Constant term.
452-
eqToAdd[getNumCols() - 1] = -flatExpr[flatExpr.size() - 1];
453-
454-
// Add the equality connecting the result of the map to this constraint set.
455-
addEquality(eqToAdd);
456-
}
457-
458-
return success();
391+
return composeMatchingMap(
392+
computeAlignedMap(vMap->getAffineMap(), vMap->getOperands()));
459393
}
460394

461-
// Similar to composeMap except that no Value's need be associated with the
462-
// constraint system nor are they looked at -- since the dimensions and
463-
// symbols of 'other' are expected to correspond 1:1 to 'this' system. It
464-
// is thus not convenient to share code with composeMap.
395+
// Similar to `composeMap` except that no Values need be associated with the
396+
// constraint system nor are they looked at -- the dimensions and symbols of
397+
// `other` are expected to correspond 1:1 to `this` system.
465398
LogicalResult FlatAffineConstraints::composeMatchingMap(AffineMap other) {
466399
assert(other.getNumDims() == getNumDimIds() && "dim mismatch");
467400
assert(other.getNumSymbols() == getNumSymbolIds() && "symbol mismatch");
@@ -477,11 +410,15 @@ LogicalResult FlatAffineConstraints::composeMatchingMap(AffineMap other) {
477410

478411
// Add localCst information.
479412
if (localCst.getNumLocalIds() > 0) {
480-
// Place local id's of A after local id's of B.
481-
for (unsigned l = 0, e = localCst.getNumLocalIds(); l < e; l++) {
413+
unsigned numLocalIds = getNumLocalIds();
414+
// Insert local dims of localCst at the beginning.
415+
for (unsigned l = 0, e = localCst.getNumLocalIds(); l < e; ++l)
482416
addLocalId(0);
483-
}
484-
// Finally, append localCst to this constraint set.
417+
// Insert local dims of `this` at the end of localCst.
418+
for (unsigned l = 0; l < numLocalIds; ++l)
419+
localCst.addLocalId(localCst.getNumLocalIds());
420+
// Dimensions of localCst and this constraint set match. Append localCst to
421+
// this constraint set.
485422
append(localCst);
486423
}
487424

@@ -2001,19 +1938,9 @@ LogicalResult FlatAffineConstraints::addLowerOrUpperBound(unsigned pos,
20011938
return success();
20021939
}
20031940

2004-
LogicalResult
2005-
FlatAffineConstraints::addLowerOrUpperBound(unsigned pos, AffineMap boundMap,
2006-
ValueRange boundOperands, bool eq,
2007-
bool lower) {
2008-
// Fully compose map and operands; canonicalize and simplify so that we
2009-
// transitively get to terminal symbols or loop IVs.
2010-
auto map = boundMap;
2011-
SmallVector<Value, 4> operands(boundOperands.begin(), boundOperands.end());
2012-
fullyComposeAffineMapAndOperands(&map, &operands);
2013-
map = simplifyAffineMap(map);
2014-
canonicalizeMapAndOperands(&map, &operands);
2015-
for (auto operand : operands)
2016-
addInductionVarOrTerminalSymbol(operand);
1941+
AffineMap FlatAffineConstraints::computeAlignedMap(AffineMap map,
1942+
ValueRange operands) const {
1943+
assert(map.getNumInputs() == operands.size() && "number of inputs mismatch");
20171944

20181945
SmallVector<Value> dims, syms;
20191946
#ifndef NDEBUG
@@ -2036,8 +1963,23 @@ FlatAffineConstraints::addLowerOrUpperBound(unsigned pos, AffineMap boundMap,
20361963
assert(syms.size() == newSymsPtr->size() && "unexpected new/missing symbols");
20371964
assert(std::equal(syms.begin(), syms.end(), newSymsPtr->begin()) &&
20381965
"unexpected new/missing symbols");
1966+
return alignedMap;
1967+
}
20391968

2040-
return addLowerOrUpperBound(pos, alignedMap, eq, lower);
1969+
LogicalResult
1970+
FlatAffineConstraints::addLowerOrUpperBound(unsigned pos, AffineMap boundMap,
1971+
ValueRange boundOperands, bool eq,
1972+
bool lower) {
1973+
// Fully compose map and operands; canonicalize and simplify so that we
1974+
// transitively get to terminal symbols or loop IVs.
1975+
auto map = boundMap;
1976+
SmallVector<Value, 4> operands(boundOperands.begin(), boundOperands.end());
1977+
fullyComposeAffineMapAndOperands(&map, &operands);
1978+
map = simplifyAffineMap(map);
1979+
canonicalizeMapAndOperands(&map, &operands);
1980+
for (auto operand : operands)
1981+
addInductionVarOrTerminalSymbol(operand);
1982+
return addLowerOrUpperBound(pos, computeAlignedMap(map, operands), eq, lower);
20411983
}
20421984

20431985
// Adds slice lower bounds represented by lower bounds in 'lbMaps' and upper

0 commit comments

Comments
 (0)