From fc367dfa6770fda4adc4e5de79846f22e7e4e215 Mon Sep 17 00:00:00 2001 From: Mahesh Ravishankar Date: Fri, 11 Nov 2022 17:10:38 +0000 Subject: [PATCH] [mlir] Remove `Transforms/SideEffectUtils.h` and move the methods into `Interface/SideEffectInterfaces.h`. The methods in `SideEffectUtils.h` (and their implementations in `SideEffectUtils.cpp`) seem to have similar intent to methods already existing in `SideEffectInterfaces.h`. Move the decleration (and implementation) from `SideEffectUtils.h` (and `SideEffectUtils.cpp`) into `SideEffectInterfaces.h` (and `SideEffectInterface.cpp`). Also drop the `SideEffectInterface::hasNoEffect` method in favor of `mlir::isMemoryEffectFree` which actually recurses into the operation instead of just relying on the `hasRecursiveMemoryEffectTrait` exclusively. Differential Revision: https://reviews.llvm.org/D137857 --- .../mlir/Interfaces/SideEffectInterfaceBase.td | 7 --- .../include/mlir/Interfaces/SideEffectInterfaces.h | 19 +++++++ mlir/include/mlir/Transforms/SideEffectUtils.h | 37 ------------- mlir/lib/Analysis/SliceAnalysis.cpp | 6 +-- mlir/lib/Conversion/SCFToGPU/CMakeLists.txt | 1 + mlir/lib/Conversion/SCFToGPU/SCFToGPU.cpp | 5 +- .../lib/Dialect/Affine/Analysis/AffineAnalysis.cpp | 2 +- mlir/lib/Dialect/Affine/Analysis/CMakeLists.txt | 1 + .../Dialect/Bufferization/Transforms/Bufferize.cpp | 3 +- .../Bufferization/Transforms/CMakeLists.txt | 1 + mlir/lib/Dialect/GPU/CMakeLists.txt | 1 + .../Dialect/GPU/Transforms/AsyncRegionRewriter.cpp | 5 +- mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp | 2 +- mlir/lib/Dialect/SCF/Transforms/CMakeLists.txt | 1 + .../Dialect/SCF/Transforms/ParallelLoopFusion.cpp | 4 +- mlir/lib/Dialect/SCF/Utils/CMakeLists.txt | 1 + mlir/lib/Dialect/SCF/Utils/Utils.cpp | 3 +- mlir/lib/Dialect/Vector/Transforms/CMakeLists.txt | 1 + .../Dialect/Vector/Transforms/VectorDistribute.cpp | 2 +- .../Transforms/VectorTransferOpTransforms.cpp | 2 +- mlir/lib/Interfaces/SideEffectInterfaces.cpp | 48 +++++++++++++++++ mlir/lib/Transforms/CMakeLists.txt | 1 + mlir/lib/Transforms/CSE.cpp | 2 +- mlir/lib/Transforms/ControlFlowSink.cpp | 1 - mlir/lib/Transforms/Inliner.cpp | 4 +- mlir/lib/Transforms/LoopInvariantCodeMotion.cpp | 2 +- mlir/lib/Transforms/Utils/CMakeLists.txt | 2 +- .../Utils/LoopInvariantCodeMotionUtils.cpp | 2 +- mlir/lib/Transforms/Utils/SideEffectUtils.cpp | 60 ---------------------- .../codegen_buffer_initialization.mlir | 3 +- utils/bazel/llvm-project-overlay/mlir/BUILD.bazel | 8 +++ 31 files changed, 108 insertions(+), 129 deletions(-) delete mode 100644 mlir/include/mlir/Transforms/SideEffectUtils.h delete mode 100644 mlir/lib/Transforms/Utils/SideEffectUtils.cpp diff --git a/mlir/include/mlir/Interfaces/SideEffectInterfaceBase.td b/mlir/include/mlir/Interfaces/SideEffectInterfaceBase.td index bddbaad..b703fa5 100644 --- a/mlir/include/mlir/Interfaces/SideEffectInterfaceBase.td +++ b/mlir/include/mlir/Interfaces/SideEffectInterfaceBase.td @@ -94,13 +94,6 @@ class EffectOpInterfaceBase return effects.empty(); } - /// Returns true if the given operation has no effects for this interface. - static bool hasNoEffect(Operation *op) { - if (auto interface = dyn_cast<}] # name # [{>(op)) - return interface.hasNoEffect(); - return op->hasTrait<::mlir::OpTrait::HasRecursiveMemoryEffects>(); - } - /// Collect all of the effect instances that operate on the provided value /// and place them in 'effects'. void getEffectsOnValue(::mlir::Value value, diff --git a/mlir/include/mlir/Interfaces/SideEffectInterfaces.h b/mlir/include/mlir/Interfaces/SideEffectInterfaces.h index 3be924a..a6922df 100644 --- a/mlir/include/mlir/Interfaces/SideEffectInterfaces.h +++ b/mlir/include/mlir/Interfaces/SideEffectInterfaces.h @@ -318,6 +318,25 @@ bool isOpTriviallyDead(Operation *op); /// `isOpTriviallyDead` if `op` was unused. bool wouldOpBeTriviallyDead(Operation *op); +/// Returns true if the given operation is free of memory effects. +/// +/// An operation is free of memory effects if its implementation of +/// `MemoryEffectOpInterface` indicates that it has no memory effects. For +/// example, it may implement `NoMemoryEffect` in ODS. Alternatively, if the +/// operation has the `HasRecursiveMemoryEffects` trait, then it is free of +/// memory effects if all of its nested operations are free of memory effects. +/// +/// If the operation has both, then it is free of memory effects if both +/// conditions are satisfied. +bool isMemoryEffectFree(Operation *op); + +/// Returns true if the given operation is speculatable, i.e. has no undefined +/// behavior or other side effects. +/// +/// An operation can indicate that it is speculatable by implementing the +/// getSpeculatability hook in the ConditionallySpeculatable op interface. +bool isSpeculatable(Operation *op); + } // namespace mlir //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/Transforms/SideEffectUtils.h b/mlir/include/mlir/Transforms/SideEffectUtils.h deleted file mode 100644 index 4c797a7..0000000 --- a/mlir/include/mlir/Transforms/SideEffectUtils.h +++ /dev/null @@ -1,37 +0,0 @@ -//===- SideEffectUtils.h - Side Effect Utils --------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef MLIR_TRANSFORMS_SIDEFFECTUTILS_H -#define MLIR_TRANSFORMS_SIDEFFECTUTILS_H - -namespace mlir { - -class Operation; - -/// Returns true if the given operation is free of memory effects. -/// -/// An operation is free of memory effects if its implementation of -/// `MemoryEffectOpInterface` indicates that it has no memory effects. For -/// example, it may implement `NoMemoryEffect` in ODS. Alternatively, if the -/// operation has the `HasRecursiveMemoryEffects` trait, then it is free of -/// memory effects if all of its nested operations are free of memory effects. -/// -/// If the operation has both, then it is free of memory effects if both -/// conditions are satisfied. -bool isMemoryEffectFree(Operation *op); - -/// Returns true if the given operation is speculatable, i.e. has no undefined -/// behavior or other side effects. -/// -/// An operation can indicate that it is speculatable by implementing the -/// getSpeculatability hook in the ConditionallySpeculatable op interface. -bool isSpeculatable(Operation *op); - -} // end namespace mlir - -#endif // MLIR_TRANSFORMS_SIDEFFECTUTILS_H diff --git a/mlir/lib/Analysis/SliceAnalysis.cpp b/mlir/lib/Analysis/SliceAnalysis.cpp index 4684ccf..8b098b5 100644 --- a/mlir/lib/Analysis/SliceAnalysis.cpp +++ b/mlir/lib/Analysis/SliceAnalysis.cpp @@ -13,6 +13,7 @@ #include "mlir/Analysis/SliceAnalysis.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Operation.h" +#include "mlir/Interfaces/SideEffectInterfaces.h" #include "mlir/Support/LLVM.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -293,9 +294,8 @@ Value mlir::matchReduction(ArrayRef iterCarriedArgs, // terminator is found. Gather all the combiner ops along the way in // topological order. while (!combinerOp->mightHaveTrait()) { - if (!MemoryEffectOpInterface::hasNoEffect(combinerOp) || - combinerOp->getNumResults() != 1 || !combinerOp->hasOneUse() || - combinerOp->getParentOp() != redRegionOp) + if (!isMemoryEffectFree(combinerOp) || combinerOp->getNumResults() != 1 || + !combinerOp->hasOneUse() || combinerOp->getParentOp() != redRegionOp) return nullptr; combinerOps.push_back(combinerOp); diff --git a/mlir/lib/Conversion/SCFToGPU/CMakeLists.txt b/mlir/lib/Conversion/SCFToGPU/CMakeLists.txt index 253b196..b785363 100644 --- a/mlir/lib/Conversion/SCFToGPU/CMakeLists.txt +++ b/mlir/lib/Conversion/SCFToGPU/CMakeLists.txt @@ -19,5 +19,6 @@ add_mlir_conversion_library(MLIRSCFToGPU MLIRMemRefDialect MLIRPass MLIRSupport + MLIRSideEffectInterfaces MLIRTransforms ) diff --git a/mlir/lib/Conversion/SCFToGPU/SCFToGPU.cpp b/mlir/lib/Conversion/SCFToGPU/SCFToGPU.cpp index 26361a3..b0c150f 100644 --- a/mlir/lib/Conversion/SCFToGPU/SCFToGPU.cpp +++ b/mlir/lib/Conversion/SCFToGPU/SCFToGPU.cpp @@ -24,6 +24,7 @@ #include "mlir/IR/AffineExpr.h" #include "mlir/IR/BlockAndValueMapping.h" #include "mlir/IR/Builders.h" +#include "mlir/Interfaces/SideEffectInterfaces.h" #include "mlir/Pass/Pass.h" #include "mlir/Transforms/DialectConversion.h" #include "mlir/Transforms/Passes.h" @@ -656,8 +657,8 @@ ParallelToGpuLaunchLowering::matchAndRewrite(ParallelOp parallelOp, cloningMap.map(op->getResults(), clone->getResults()); // Check for side effects. // TODO: Handle region side effects properly. - seenSideeffects |= !MemoryEffectOpInterface::hasNoEffect(clone) || - clone->getNumRegions() != 0; + seenSideeffects |= + !isMemoryEffectFree(clone) || clone->getNumRegions() != 0; // If we are no longer in the innermost scope, sideeffects are disallowed. if (seenSideeffects && leftNestingScope) return failure(); diff --git a/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp b/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp index 274c941..5af6a6a 100644 --- a/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp +++ b/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp @@ -150,7 +150,7 @@ bool mlir::isLoopMemoryParallel(AffineForOp forOp) { loadAndStoreOps.push_back(op); } else if (!isa(op) && !hasSingleEffect(op) && - !MemoryEffectOpInterface::hasNoEffect(op)) { + !isMemoryEffectFree(op)) { // Alloc-like ops inside `forOp` are fine (they don't impact parallelism) // as long as they don't escape the loop (which has been checked above). return WalkResult::interrupt(); diff --git a/mlir/lib/Dialect/Affine/Analysis/CMakeLists.txt b/mlir/lib/Dialect/Affine/Analysis/CMakeLists.txt index 9898dbc..38b64d5 100644 --- a/mlir/lib/Dialect/Affine/Analysis/CMakeLists.txt +++ b/mlir/lib/Dialect/Affine/Analysis/CMakeLists.txt @@ -14,6 +14,7 @@ add_mlir_dialect_library(MLIRAffineAnalysis MLIRCallInterfaces MLIRControlFlowInterfaces MLIRInferTypeOpInterface + MLIRSideEffectInterfaces MLIRPresburger MLIRSCFDialect ) diff --git a/mlir/lib/Dialect/Bufferization/Transforms/Bufferize.cpp b/mlir/lib/Dialect/Bufferization/Transforms/Bufferize.cpp index 7c3b7c8..8a33bf3 100644 --- a/mlir/lib/Dialect/Bufferization/Transforms/Bufferize.cpp +++ b/mlir/lib/Dialect/Bufferization/Transforms/Bufferize.cpp @@ -17,6 +17,7 @@ #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/Dialect/MemRef/IR/MemRef.h" #include "mlir/IR/Operation.h" +#include "mlir/Interfaces/SideEffectInterfaces.h" #include "mlir/Pass/PassManager.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" #include "mlir/Transforms/Passes.h" @@ -490,7 +491,7 @@ LogicalResult bufferization::bufferizeOp(Operation *op, if (opFilter && !opFilter->isOpAllowed(op)) continue; // Ops without any uses and no side effects will fold away. - if (op->getUses().empty() && MemoryEffectOpInterface::hasNoEffect(op)) + if (op->getUses().empty() && isMemoryEffectFree(op)) continue; // ToTensorOps/ToMemrefOps are allowed in the output. if (isa(op)) diff --git a/mlir/lib/Dialect/Bufferization/Transforms/CMakeLists.txt b/mlir/lib/Dialect/Bufferization/Transforms/CMakeLists.txt index e23c5c3..8940c58 100644 --- a/mlir/lib/Dialect/Bufferization/Transforms/CMakeLists.txt +++ b/mlir/lib/Dialect/Bufferization/Transforms/CMakeLists.txt @@ -29,6 +29,7 @@ add_mlir_dialect_library(MLIRBufferizationTransforms MLIRMemRefDialect MLIRPass MLIRTensorDialect + MLIRSideEffectInterfaces MLIRTransforms MLIRViewLikeInterface ) diff --git a/mlir/lib/Dialect/GPU/CMakeLists.txt b/mlir/lib/Dialect/GPU/CMakeLists.txt index dd7c7f2..53dd163 100644 --- a/mlir/lib/Dialect/GPU/CMakeLists.txt +++ b/mlir/lib/Dialect/GPU/CMakeLists.txt @@ -78,6 +78,7 @@ add_mlir_dialect_library(MLIRGPUTransforms MLIRMemRefDialect MLIRPass MLIRSCFDialect + MLIRSideEffectInterfaces MLIRSupport MLIRTransformUtils ) diff --git a/mlir/lib/Dialect/GPU/Transforms/AsyncRegionRewriter.cpp b/mlir/lib/Dialect/GPU/Transforms/AsyncRegionRewriter.cpp index 0c669c7..c8a835c 100644 --- a/mlir/lib/Dialect/GPU/Transforms/AsyncRegionRewriter.cpp +++ b/mlir/lib/Dialect/GPU/Transforms/AsyncRegionRewriter.cpp @@ -21,6 +21,7 @@ #include "mlir/IR/Builders.h" #include "mlir/IR/PatternMatch.h" #include "mlir/IR/SymbolTable.h" +#include "mlir/Interfaces/SideEffectInterfaces.h" #include "mlir/Support/LLVM.h" #include "mlir/Transforms/RegionUtils.h" #include "llvm/ADT/TypeSwitch.h" @@ -45,9 +46,7 @@ class GpuAsyncRegionPass static bool isTerminator(Operation *op) { return op->mightHaveTrait(); } -static bool hasSideEffects(Operation *op) { - return !MemoryEffectOpInterface::hasNoEffect(op); -} +static bool hasSideEffects(Operation *op) { return !isMemoryEffectFree(op); } // Region walk callback which makes GPU ops implementing the AsyncOpInterface // execute asynchronously. diff --git a/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp b/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp index 11aabd5..73c2b53 100644 --- a/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp +++ b/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp @@ -1486,7 +1486,7 @@ LogicalResult GenericAtomicRMWOp::verify() { bool hasSideEffects = body.walk([&](Operation *nestedOp) { - if (MemoryEffectOpInterface::hasNoEffect(nestedOp)) + if (isMemoryEffectFree(nestedOp)) return WalkResult::advance(); nestedOp->emitError( "body of 'memref.generic_atomic_rmw' should contain " diff --git a/mlir/lib/Dialect/SCF/Transforms/CMakeLists.txt b/mlir/lib/Dialect/SCF/Transforms/CMakeLists.txt index fce252f..3dd9099 100644 --- a/mlir/lib/Dialect/SCF/Transforms/CMakeLists.txt +++ b/mlir/lib/Dialect/SCF/Transforms/CMakeLists.txt @@ -31,6 +31,7 @@ add_mlir_dialect_library(MLIRSCFTransforms MLIRPass MLIRSCFDialect MLIRSCFUtils + MLIRSideEffectInterfaces MLIRSupport MLIRTensorDialect MLIRTensorTransforms diff --git a/mlir/lib/Dialect/SCF/Transforms/ParallelLoopFusion.cpp b/mlir/lib/Dialect/SCF/Transforms/ParallelLoopFusion.cpp index e253057..a525c05 100644 --- a/mlir/lib/Dialect/SCF/Transforms/ParallelLoopFusion.cpp +++ b/mlir/lib/Dialect/SCF/Transforms/ParallelLoopFusion.cpp @@ -18,6 +18,7 @@ #include "mlir/IR/BlockAndValueMapping.h" #include "mlir/IR/Builders.h" #include "mlir/IR/OpDefinition.h" +#include "mlir/Interfaces/SideEffectInterfaces.h" namespace mlir { #define GEN_PASS_DEF_SCFPARALLELLOOPFUSION @@ -155,8 +156,7 @@ void mlir::scf::naivelyFuseParallelOps(Region ®ion) { continue; } // TODO: Handle region side effects properly. - noSideEffects &= - MemoryEffectOpInterface::hasNoEffect(&op) && op.getNumRegions() == 0; + noSideEffects &= isMemoryEffectFree(&op) && op.getNumRegions() == 0; } for (ArrayRef ploops : ploopChains) { for (int i = 0, e = ploops.size(); i + 1 < e; ++i) diff --git a/mlir/lib/Dialect/SCF/Utils/CMakeLists.txt b/mlir/lib/Dialect/SCF/Utils/CMakeLists.txt index 15802da..5ac6ed5 100644 --- a/mlir/lib/Dialect/SCF/Utils/CMakeLists.txt +++ b/mlir/lib/Dialect/SCF/Utils/CMakeLists.txt @@ -14,6 +14,7 @@ add_mlir_dialect_library(MLIRSCFUtils MLIRFuncDialect MLIRIR MLIRSCFDialect + MLIRSideEffectInterfaces MLIRSupport MLIRTransforms ) diff --git a/mlir/lib/Dialect/SCF/Utils/Utils.cpp b/mlir/lib/Dialect/SCF/Utils/Utils.cpp index e99510e..d5272f4 100644 --- a/mlir/lib/Dialect/SCF/Utils/Utils.cpp +++ b/mlir/lib/Dialect/SCF/Utils/Utils.cpp @@ -18,6 +18,7 @@ #include "mlir/IR/BlockAndValueMapping.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/PatternMatch.h" +#include "mlir/Interfaces/SideEffectInterfaces.h" #include "mlir/Support/MathExtras.h" #include "mlir/Transforms/RegionUtils.h" #include "llvm/ADT/STLExtras.h" @@ -825,7 +826,7 @@ static LogicalResult hoistOpsBetween(scf::ForOp outer, scf::ForOp inner) { } // Skip if op has side effects. // TODO: loads to immutable memory regions are ok. - if (!MemoryEffectOpInterface::hasNoEffect(&op)) { + if (!isMemoryEffectFree(&op)) { status = failure(); continue; } diff --git a/mlir/lib/Dialect/Vector/Transforms/CMakeLists.txt b/mlir/lib/Dialect/Vector/Transforms/CMakeLists.txt index 6350350..cfbf289 100644 --- a/mlir/lib/Dialect/Vector/Transforms/CMakeLists.txt +++ b/mlir/lib/Dialect/Vector/Transforms/CMakeLists.txt @@ -31,6 +31,7 @@ add_mlir_dialect_library(MLIRVectorTransforms MLIRLinalgDialect MLIRMemRefDialect MLIRSCFDialect + MLIRSideEffectInterfaces MLIRTransforms MLIRVectorDialect MLIRVectorInterfaces diff --git a/mlir/lib/Dialect/Vector/Transforms/VectorDistribute.cpp b/mlir/lib/Dialect/Vector/Transforms/VectorDistribute.cpp index c56af3a..b954f4a 100644 --- a/mlir/lib/Dialect/Vector/Transforms/VectorDistribute.cpp +++ b/mlir/lib/Dialect/Vector/Transforms/VectorDistribute.cpp @@ -13,8 +13,8 @@ #include "mlir/Dialect/Vector/IR/VectorOps.h" #include "mlir/Dialect/Vector/Transforms/VectorDistribution.h" #include "mlir/IR/AffineExpr.h" +#include "mlir/Interfaces/SideEffectInterfaces.h" #include "mlir/Transforms/RegionUtils.h" -#include "mlir/Transforms/SideEffectUtils.h" #include "llvm/ADT/SetVector.h" #include diff --git a/mlir/lib/Dialect/Vector/Transforms/VectorTransferOpTransforms.cpp b/mlir/lib/Dialect/Vector/Transforms/VectorTransferOpTransforms.cpp index 7ab8e8a..b59b10c 100644 --- a/mlir/lib/Dialect/Vector/Transforms/VectorTransferOpTransforms.cpp +++ b/mlir/lib/Dialect/Vector/Transforms/VectorTransferOpTransforms.cpp @@ -18,7 +18,7 @@ #include "mlir/Dialect/Vector/Utils/VectorUtils.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Dominance.h" -#include "mlir/Transforms/SideEffectUtils.h" +#include "mlir/Interfaces/SideEffectInterfaces.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Debug.h" diff --git a/mlir/lib/Interfaces/SideEffectInterfaces.cpp b/mlir/lib/Interfaces/SideEffectInterfaces.cpp index e1669ec..a59d52d 100644 --- a/mlir/lib/Interfaces/SideEffectInterfaces.cpp +++ b/mlir/lib/Interfaces/SideEffectInterfaces.cpp @@ -154,3 +154,51 @@ bool mlir::wouldOpBeTriviallyDead(Operation *op) { return false; return wouldOpBeTriviallyDeadImpl(op); } + +bool mlir::isMemoryEffectFree(Operation *op) { + if (auto memInterface = dyn_cast(op)) { + if (!memInterface.hasNoEffect()) + return false; + // If the op does not have recursive side effects, then it is memory effect + // free. + if (!op->hasTrait()) + return true; + } else if (!op->hasTrait()) { + // Otherwise, if the op does not implement the memory effect interface and + // it does not have recursive side effects, then it cannot be known that the + // op is moveable. + return false; + } + + // Recurse into the regions and ensure that all nested ops are memory effect + // free. + for (Region ®ion : op->getRegions()) + for (Operation &op : region.getOps()) + if (!isMemoryEffectFree(&op)) + return false; + return true; +} + +bool mlir::isSpeculatable(Operation *op) { + auto conditionallySpeculatable = dyn_cast(op); + if (!conditionallySpeculatable) + return false; + + switch (conditionallySpeculatable.getSpeculatability()) { + case Speculation::RecursivelySpeculatable: + for (Region ®ion : op->getRegions()) { + for (Operation &op : region.getOps()) + if (!isSpeculatable(&op)) + return false; + } + return true; + + case Speculation::Speculatable: + return true; + + case Speculation::NotSpeculatable: + return false; + } + + llvm_unreachable("Unhandled enum in mlir::isSpeculatable!"); +} diff --git a/mlir/lib/Transforms/CMakeLists.txt b/mlir/lib/Transforms/CMakeLists.txt index 52976c7..71ca9b0 100644 --- a/mlir/lib/Transforms/CMakeLists.txt +++ b/mlir/lib/Transforms/CMakeLists.txt @@ -26,6 +26,7 @@ add_mlir_library(MLIRTransforms MLIRCopyOpInterface MLIRLoopLikeInterface MLIRPass + MLIRSideEffectInterfaces MLIRSupport MLIRTransformUtils ) diff --git a/mlir/lib/Transforms/CSE.cpp b/mlir/lib/Transforms/CSE.cpp index 959cec3..3df419c 100644 --- a/mlir/lib/Transforms/CSE.cpp +++ b/mlir/lib/Transforms/CSE.cpp @@ -209,7 +209,7 @@ LogicalResult CSE::simplifyOperation(ScopedMapTy &knownValues, Operation *op, // Some simple use case of operation with memory side-effect are dealt with // here. Operations with no side-effect are done after. - if (!MemoryEffectOpInterface::hasNoEffect(op)) { + if (!isMemoryEffectFree(op)) { auto memEffects = dyn_cast(op); // TODO: Only basic use case for operations with MemoryEffects::Read can be // eleminated now. More work needs to be done for more complicated patterns diff --git a/mlir/lib/Transforms/ControlFlowSink.cpp b/mlir/lib/Transforms/ControlFlowSink.cpp index 1000a79..4e1dfa1 100644 --- a/mlir/lib/Transforms/ControlFlowSink.cpp +++ b/mlir/lib/Transforms/ControlFlowSink.cpp @@ -19,7 +19,6 @@ #include "mlir/Interfaces/ControlFlowInterfaces.h" #include "mlir/Interfaces/SideEffectInterfaces.h" #include "mlir/Transforms/ControlFlowSinkUtils.h" -#include "mlir/Transforms/SideEffectUtils.h" namespace mlir { #define GEN_PASS_DEF_CONTROLFLOWSINK diff --git a/mlir/lib/Transforms/Inliner.cpp b/mlir/lib/Transforms/Inliner.cpp index 83e8530..790810b 100644 --- a/mlir/lib/Transforms/Inliner.cpp +++ b/mlir/lib/Transforms/Inliner.cpp @@ -201,7 +201,7 @@ bool CGUseList::isDead(CallGraphNode *node) const { // If the parent operation isn't a symbol, simply check normal SSA deadness. Operation *nodeOp = node->getCallableRegion()->getParentOp(); if (!isa(nodeOp)) - return MemoryEffectOpInterface::hasNoEffect(nodeOp) && nodeOp->use_empty(); + return isMemoryEffectFree(nodeOp) && nodeOp->use_empty(); // Otherwise, check the number of symbol uses. auto symbolIt = discardableSymNodeUses.find(node); @@ -212,7 +212,7 @@ bool CGUseList::hasOneUseAndDiscardable(CallGraphNode *node) const { // If this isn't a symbol node, check for side-effects and SSA use count. Operation *nodeOp = node->getCallableRegion()->getParentOp(); if (!isa(nodeOp)) - return MemoryEffectOpInterface::hasNoEffect(nodeOp) && nodeOp->hasOneUse(); + return isMemoryEffectFree(nodeOp) && nodeOp->hasOneUse(); // Otherwise, check the number of symbol uses. auto symbolIt = discardableSymNodeUses.find(node); diff --git a/mlir/lib/Transforms/LoopInvariantCodeMotion.cpp b/mlir/lib/Transforms/LoopInvariantCodeMotion.cpp index 4711937..854fde0 100644 --- a/mlir/lib/Transforms/LoopInvariantCodeMotion.cpp +++ b/mlir/lib/Transforms/LoopInvariantCodeMotion.cpp @@ -13,8 +13,8 @@ #include "mlir/Transforms/Passes.h" #include "mlir/Interfaces/LoopLikeInterface.h" +#include "mlir/Interfaces/SideEffectInterfaces.h" #include "mlir/Transforms/LoopInvariantCodeMotionUtils.h" -#include "mlir/Transforms/SideEffectUtils.h" namespace mlir { #define GEN_PASS_DEF_LOOPINVARIANTCODEMOTION diff --git a/mlir/lib/Transforms/Utils/CMakeLists.txt b/mlir/lib/Transforms/Utils/CMakeLists.txt index 57307e6..ba8fa20 100644 --- a/mlir/lib/Transforms/Utils/CMakeLists.txt +++ b/mlir/lib/Transforms/Utils/CMakeLists.txt @@ -7,7 +7,6 @@ add_mlir_library(MLIRTransformUtils InliningUtils.cpp LoopInvariantCodeMotionUtils.cpp RegionUtils.cpp - SideEffectUtils.cpp TopologicalSortUtils.cpp ADDITIONAL_HEADER_DIRS @@ -16,5 +15,6 @@ add_mlir_library(MLIRTransformUtils LINK_LIBS PUBLIC MLIRAnalysis MLIRLoopLikeInterface + MLIRSideEffectInterfaces MLIRRewrite ) diff --git a/mlir/lib/Transforms/Utils/LoopInvariantCodeMotionUtils.cpp b/mlir/lib/Transforms/Utils/LoopInvariantCodeMotionUtils.cpp index 770255f..d546ab3 100644 --- a/mlir/lib/Transforms/Utils/LoopInvariantCodeMotionUtils.cpp +++ b/mlir/lib/Transforms/Utils/LoopInvariantCodeMotionUtils.cpp @@ -13,7 +13,7 @@ #include "mlir/Transforms/LoopInvariantCodeMotionUtils.h" #include "mlir/IR/Operation.h" #include "mlir/Interfaces/LoopLikeInterface.h" -#include "mlir/Transforms/SideEffectUtils.h" +#include "mlir/Interfaces/SideEffectInterfaces.h" #include "llvm/Support/Debug.h" #include diff --git a/mlir/lib/Transforms/Utils/SideEffectUtils.cpp b/mlir/lib/Transforms/Utils/SideEffectUtils.cpp deleted file mode 100644 index fcfdb7c..0000000 --- a/mlir/lib/Transforms/Utils/SideEffectUtils.cpp +++ /dev/null @@ -1,60 +0,0 @@ -//===- SideEffectUtils.cpp - Side Effect Utils ------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "mlir/Transforms/SideEffectUtils.h" -#include "mlir/IR/Operation.h" -#include "mlir/Interfaces/SideEffectInterfaces.h" - -using namespace mlir; - -bool mlir::isMemoryEffectFree(Operation *op) { - if (auto memInterface = dyn_cast(op)) { - // If the op has side-effects, it cannot be moved. - if (!memInterface.hasNoEffect()) - return false; - // If the op does not have recursive side effects, then it can be moved. - if (!op->hasTrait()) - return true; - } else if (!op->hasTrait()) { - // Otherwise, if the op does not implement the memory effect interface and - // it does not have recursive side effects, then it cannot be known that the - // op is moveable. - return false; - } - - // Recurse into the regions and ensure that all nested ops can also be moved. - for (Region ®ion : op->getRegions()) - for (Operation &op : region.getOps()) - if (!isMemoryEffectFree(&op)) - return false; - return true; -} - -bool mlir::isSpeculatable(Operation *op) { - auto conditionallySpeculatable = dyn_cast(op); - if (!conditionallySpeculatable) - return false; - - switch (conditionallySpeculatable.getSpeculatability()) { - case Speculation::RecursivelySpeculatable: - for (Region ®ion : op->getRegions()) { - for (Operation &op : region.getOps()) - if (!isSpeculatable(&op)) - return false; - } - return true; - - case Speculation::Speculatable: - return true; - - case Speculation::NotSpeculatable: - return false; - } - - llvm_unreachable("Unhandled enum in mlir::isSpeculatable!"); -} diff --git a/mlir/test/Dialect/SparseTensor/codegen_buffer_initialization.mlir b/mlir/test/Dialect/SparseTensor/codegen_buffer_initialization.mlir index 043cdbb..cc5f861 100644 --- a/mlir/test/Dialect/SparseTensor/codegen_buffer_initialization.mlir +++ b/mlir/test/Dialect/SparseTensor/codegen_buffer_initialization.mlir @@ -7,7 +7,6 @@ // CHECK-SAME: memref<1xindex>, memref<3xindex>, memref, memref, memref // CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index // CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index -// CHECK-DAG: %[[F0:.*]] = arith.constant 0.{{0*}}e+00 : f64 // CHECK: %[[T0:.*]] = memref.alloc() : memref<1xindex> // CHECK: %[[T1:.*]] = memref.alloc() : memref<3xindex> // CHECK: %[[T2:.*]] = memref.alloc() : memref<16xindex> @@ -18,7 +17,7 @@ // CHECK: linalg.fill ins(%[[C0]] : index) outs(%[[T4]] : memref<16xindex>) // CHECK: %[[T6:.*]] = memref.alloc() : memref<16xf64> // CHECK: %[[T7:.*]] = memref.cast %[[T6]] : memref<16xf64> to memref -// CHECK: linalg.fill ins(%[[F0]] : f64) outs(%[[T6]] : memref<16xf64>) +// CHECK: linalg.fill ins(%{{.*}} : f64) outs(%[[T6]] : memref<16xf64>) // CHECK: linalg.fill ins(%[[C0]] : index) outs(%[[T1]] : memref<3xindex>) // CHECK: memref.store %[[A]], %[[T0]][%[[C0]]] : memref<1xindex> // CHECK: %[[P0:.*]] = sparse_tensor.push_back %[[T1]], %[[T3]] diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel index 4469fcb..f68d7b6 100644 --- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel @@ -1942,6 +1942,7 @@ cc_library( ":SCFDialect", ":SCFPassIncGen", ":SCFUtils", + ":SideEffectInterfaces", ":Support", ":TensorDialect", ":TensorTransforms", @@ -2553,6 +2554,7 @@ cc_library( ":ArithDialect", ":FuncDialect", ":IR", + ":SideEffectInterfaces", ":Support", ":ViewLikeInterface", "//llvm:Support", @@ -2855,6 +2857,7 @@ cc_library( ":FuncDialect", ":IR", ":SCFDialect", + ":SideEffectInterfaces", ":Support", ":Transforms", "//llvm:Support", @@ -3337,6 +3340,7 @@ cc_library( ":MemRefDialect", ":Pass", ":SCFDialect", + ":SideEffectInterfaces", ":Support", ":TensorDialect", ":Transforms", @@ -3841,6 +3845,7 @@ cc_library( ":ROCDLToLLVMIRTranslation", ":SCFDialect", ":FuncDialect", + ":SideEffectInterfaces", ":Support", ":Transforms", ":ToLLVMIRTranslation", @@ -5694,6 +5699,7 @@ cc_library( ":LoopLikeInterface", ":Pass", ":Rewrite", + ":SideEffectInterfaces", ":Support", ":TransformUtils", ":TransformsPassIncGen", @@ -5731,6 +5737,7 @@ cc_library( ":MemRefDialect", ":Pass", ":SCFDialect", + ":SideEffectInterfaces", ":Support", ":TransformUtils", ":Transforms", @@ -10053,6 +10060,7 @@ cc_library( ":LoopLikeInterface", ":MemRefDialect", ":Pass", + ":SideEffectInterfaces", ":TensorDialect", ":Transforms", ":ViewLikeInterface", -- 2.7.4