[Mlir-commits] [mlir] [mlir][vector] Enable transfer op hoisting with dynamic indices (PR #68500)
Kunwar Grover
llvmlistbot at llvm.org
Sun Oct 15 13:03:30 PDT 2023
================
@@ -168,39 +170,77 @@ bool mlir::vector::checkSameValueWAW(vector::TransferWriteOp write,
}
bool mlir::vector::isDisjointTransferIndices(
- VectorTransferOpInterface transferA, VectorTransferOpInterface transferB) {
+ VectorTransferOpInterface transferA, VectorTransferOpInterface transferB,
+ bool testDynamicValueUsingBounds) {
// For simplicity only look at transfer of same type.
if (transferA.getVectorType() != transferB.getVectorType())
return false;
unsigned rankOffset = transferA.getLeadingShapedRank();
for (unsigned i = 0, e = transferA.indices().size(); i < e; i++) {
- auto indexA = getConstantIntValue(transferA.indices()[i]);
- auto indexB = getConstantIntValue(transferB.indices()[i]);
- // If any of the indices are dynamic we cannot prove anything.
- if (!indexA.has_value() || !indexB.has_value())
- continue;
+ Value indexA = transferA.indices()[i];
+ Value indexB = transferB.indices()[i];
+ std::optional<int64_t> cstIndexA = getConstantIntValue(indexA);
+ std::optional<int64_t> cstIndexB = getConstantIntValue(indexB);
if (i < rankOffset) {
// For leading dimensions, if we can prove that index are different we
// know we are accessing disjoint slices.
- if (*indexA != *indexB)
- return true;
+ if (cstIndexA.has_value() && cstIndexB.has_value()) {
+ if (*cstIndexA != *cstIndexB)
+ return true;
+ continue;
+ }
+ if (testDynamicValueUsingBounds) {
+ // First try to see if we can fully compose and simplify the affine
+ // expression as a fast track.
+ FailureOr<uint64_t> delta =
+ affine::fullyComposeAndComputeConstantDelta(indexA, indexB);
+ if (succeeded(delta) && *delta != 0)
+ return true;
+
+ FailureOr<bool> testEqual =
+ ValueBoundsConstraintSet::areEqual(indexA, indexB);
+ if (succeeded(testEqual) && !testEqual.value())
+ return true;
+ }
} else {
// For this dimension, we slice a part of the memref we need to make sure
// the intervals accessed don't overlap.
- int64_t distance = std::abs(*indexA - *indexB);
- if (distance >= transferA.getVectorType().getDimSize(i - rankOffset))
- return true;
+ int64_t vectorDim = transferA.getVectorType().getDimSize(i - rankOffset);
+ if (cstIndexA.has_value() && cstIndexB.has_value()) {
+ int64_t distance = std::abs(*cstIndexA - *cstIndexB);
+ if (distance >= vectorDim)
+ return true;
+ continue;
+ }
+ if (testDynamicValueUsingBounds) {
+ // First try to see if we can fully compose and simplify the affine
+ // expression as a fast track.
+ FailureOr<int64_t> delta =
+ affine::fullyComposeAndComputeConstantDelta(indexA, indexB);
+ if (succeeded(delta) && *delta >= vectorDim)
+ return true;
----------------
Groverkss wrote:
While this is okay for now, I'm not a fan of computing a constant delta here. Instead, a better way is to compute a lower/upper bound on an expression (indexA - indexB here). This upper/lower bound computation is already possible, just not exposed through ValueBoundsConstraintsSet.
https://github.com/llvm/llvm-project/pull/68500
More information about the Mlir-commits
mailing list