From e753bc87458eb950e2a51200bb4dcc16cc775d82 Mon Sep 17 00:00:00 2001 From: Maksim Levental Date: Thu, 29 Sep 2022 11:08:36 -0500 Subject: [PATCH] [mlir][Affine] Move/expose hasNoInterveningEffect Expose [[ https://github.com/llvm/llvm-project/blob/main/mlir/lib/Dialect/Affine/Utils/Utils.cpp#L661 | Dialect/Affine/Utils/Utils.cpp#hasNoInterveningEffect ]] for downstream use (particular use case is a lazy implementation of [[ https://github.com/llvm/llvm-project/blob/main/mlir/lib/Dialect/Affine/Utils/Utils.cpp#L845 | forwardStoreToLoad ]] in CIRCT). This exposes hasNoInterveningEffect and instantiates for the necessary types. Reviewed By: bondhugula Differential Revision: https://reviews.llvm.org/D134374 --- mlir/include/mlir/Dialect/Affine/Utils.h | 9 +++++++++ mlir/lib/Dialect/Affine/Utils/Utils.cpp | 21 +++++++++------------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/mlir/include/mlir/Dialect/Affine/Utils.h b/mlir/include/mlir/Dialect/Affine/Utils.h index 006c61c..4381d1f 100644 --- a/mlir/include/mlir/Dialect/Affine/Utils.h +++ b/mlir/include/mlir/Dialect/Affine/Utils.h @@ -319,6 +319,15 @@ FailureOr> delinearizeIndex(OpBuilder &b, Location loc, Value linearIndex, ArrayRef basis); +/// Ensure that all operations that could be executed after `start` +/// (noninclusive) and prior to `memOp` (e.g. on a control flow/op path +/// between the operations) do not have the potential memory effect +/// `EffectType` on `memOp`. `memOp` is an operation that reads or writes to +/// a memref. For example, if `EffectType` is MemoryEffects::Write, this method +/// will check if there is no write to the memory between `start` and `memOp` +/// that would change the read within `memOp`. +template +bool hasNoInterveningEffect(Operation *start, T memOp); } // namespace mlir #endif // MLIR_DIALECT_AFFINE_UTILS_H diff --git a/mlir/lib/Dialect/Affine/Utils/Utils.cpp b/mlir/lib/Dialect/Affine/Utils/Utils.cpp index 0161325..c26a6b0 100644 --- a/mlir/lib/Dialect/Affine/Utils/Utils.cpp +++ b/mlir/lib/Dialect/Affine/Utils/Utils.cpp @@ -650,15 +650,8 @@ LogicalResult mlir::normalizeAffineFor(AffineForOp op) { return success(); } -/// Ensure that all operations that could be executed after `start` -/// (noninclusive) and prior to `memOp` (e.g. on a control flow/op path -/// between the operations) do not have the potential memory effect -/// `EffectType` on `memOp`. `memOp` is an operation that reads or writes to -/// a memref. For example, if `EffectType` is MemoryEffects::Write, this method -/// will check if there is no write to the memory between `start` and `memOp` -/// that would change the read within `memOp`. template -static bool hasNoInterveningEffect(Operation *start, T memOp) { +bool mlir::hasNoInterveningEffect(Operation *start, T memOp) { auto isLocallyAllocated = [](Value memref) { auto *defOp = memref.getDefiningOp(); return defOp && hasSingleEffect(defOp, memref); @@ -874,7 +867,7 @@ static LogicalResult forwardStoreToLoad( // 3. Ensure there is no intermediate operation which could replace the // value in memory. - if (!hasNoInterveningEffect(storeOp, loadOp)) + if (!mlir::hasNoInterveningEffect(storeOp, loadOp)) continue; // We now have a candidate for forwarding. @@ -901,6 +894,10 @@ static LogicalResult forwardStoreToLoad( return success(); } +template bool mlir::hasNoInterveningEffect( + mlir::Operation *, mlir::AffineReadOpInterface); + // This attempts to find stores which have no impact on the final result. // A writing op writeA will be eliminated if there exists an op writeB if // 1) writeA and writeB have mathematically equivalent affine access functions. @@ -937,7 +934,7 @@ static void findUnusedStore(AffineWriteOpInterface writeA, // There cannot be an operation which reads from memory between // the two writes. - if (!hasNoInterveningEffect(writeA, writeB)) + if (!mlir::hasNoInterveningEffect(writeA, writeB)) continue; opsToErase.push_back(writeA); @@ -973,8 +970,8 @@ static void loadCSE(AffineReadOpInterface loadA, continue; // 3. There is no write between loadA and loadB. - if (!hasNoInterveningEffect(loadB.getOperation(), - loadA)) + if (!mlir::hasNoInterveningEffect( + loadB.getOperation(), loadA)) continue; // Check if two values have the same shape. This is needed for affine vector -- 2.7.4