diff --git a/mlir/include/mlir/Dialect/Linalg/EDSC/Builders.h b/mlir/include/mlir/Dialect/Linalg/EDSC/Builders.h --- a/mlir/include/mlir/Dialect/Linalg/EDSC/Builders.h +++ b/mlir/include/mlir/Dialect/Linalg/EDSC/Builders.h @@ -24,6 +24,64 @@ class BlockArgument; namespace edsc { + +/// A LoopRangeBuilder is a generic NestedBuilder for loop.for operations. +/// More specifically it is meant to be used as a temporary object for +/// representing any nested MLIR construct that is "related to" an mlir::Value +/// (for now an induction variable). +class LoopRangeBuilder : public NestedBuilder { +public: + /// Constructs a new loop.for and captures the associated induction + /// variable. A ValueHandle pointer is passed as the first argument and is the + /// *only* way to capture the loop induction variable. + LoopRangeBuilder(ValueHandle *iv, ValueHandle range); + LoopRangeBuilder(ValueHandle *iv, Value range); + LoopRangeBuilder(ValueHandle *iv, SubViewOp::Range range); + + LoopRangeBuilder(const LoopRangeBuilder &) = delete; + LoopRangeBuilder(LoopRangeBuilder &&) = default; + + LoopRangeBuilder &operator=(const LoopRangeBuilder &) = delete; + LoopRangeBuilder &operator=(LoopRangeBuilder &&) = default; + + /// The only purpose of this operator is to serve as a sequence point so that + /// the evaluation of `fun` (which build IR snippets in a scoped fashion) is + /// scoped within a LoopRangeBuilder. + ValueHandle operator()(std::function fun = nullptr); +}; + +/// Helper class to sugar building loop.for loop nests from ranges. +/// This is similar to edsc::AffineLoopNestBuilder except it works on ranges +/// directly. In the current implementation it produces loop.for operations. +class LoopNestRangeBuilder { +public: + LoopNestRangeBuilder(ArrayRef ivs, + ArrayRef ranges); + LoopNestRangeBuilder(ArrayRef ivs, + ArrayRef ranges); + LoopNestRangeBuilder(ArrayRef ivs, + ArrayRef ranges); + edsc::ValueHandle operator()(std::function fun = nullptr); + +private: + SmallVector loops; +}; + +/// Helper template class for building loop.for and affine.loop nests from +/// ranges. +template class GenericLoopNestRangeBuilder { +public: + GenericLoopNestRangeBuilder(ArrayRef ivs, + ArrayRef ranges); + void operator()(std::function fun = nullptr) { (*builder)(fun); } + +private: + typedef typename std::conditional::value, + AffineLoopNestBuilder, + LoopNestRangeBuilder>::type BuilderType; + std::unique_ptr builder; +}; + enum class IterType { Parallel, Reduction }; inline StringRef toString(IterType t) { diff --git a/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h b/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h --- a/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h +++ b/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h @@ -12,7 +12,6 @@ #include "mlir/Dialect/Linalg/IR/LinalgOps.h" #include "mlir/Dialect/LoopOps/LoopOps.h" #include "mlir/Dialect/StandardOps/Ops.h" -#include "mlir/EDSC/Helpers.h" #include "llvm/ADT/SetVector.h" @@ -21,67 +20,6 @@ class AffineMap; class OperationFolder; -namespace edsc { - -/// A LoopRangeBuilder is a generic NestedBuilder for loop.for operations. -/// More specifically it is meant to be used as a temporary object for -/// representing any nested MLIR construct that is "related to" an mlir::Value -/// (for now an induction variable). -class LoopRangeBuilder : public NestedBuilder { -public: - /// Constructs a new loop.for and captures the associated induction - /// variable. A ValueHandle pointer is passed as the first argument and is the - /// *only* way to capture the loop induction variable. - LoopRangeBuilder(ValueHandle *iv, ValueHandle range); - LoopRangeBuilder(ValueHandle *iv, Value range); - LoopRangeBuilder(ValueHandle *iv, SubViewOp::Range range); - - LoopRangeBuilder(const LoopRangeBuilder &) = delete; - LoopRangeBuilder(LoopRangeBuilder &&) = default; - - LoopRangeBuilder &operator=(const LoopRangeBuilder &) = delete; - LoopRangeBuilder &operator=(LoopRangeBuilder &&) = default; - - /// The only purpose of this operator is to serve as a sequence point so that - /// the evaluation of `fun` (which build IR snippets in a scoped fashion) is - /// scoped within a LoopRangeBuilder. - ValueHandle operator()(std::function fun = nullptr); -}; - -/// Helper class to sugar building loop.for loop nests from ranges. -/// This is similar to edsc::AffineLoopNestBuilder except it works on ranges -/// directly. In the current implementation it produces loop.for operations. -class LoopNestRangeBuilder { -public: - LoopNestRangeBuilder(ArrayRef ivs, - ArrayRef ranges); - LoopNestRangeBuilder(ArrayRef ivs, - ArrayRef ranges); - LoopNestRangeBuilder(ArrayRef ivs, - ArrayRef ranges); - edsc::ValueHandle operator()(std::function fun = nullptr); - -private: - SmallVector loops; -}; - -/// Helper template class for building loop.for and affine.loop nests from -/// ranges. -template class GenericLoopNestRangeBuilder { -public: - GenericLoopNestRangeBuilder(ArrayRef ivs, - ArrayRef ranges); - void operator()(std::function fun = nullptr) { (*builder)(fun); } - -private: - typedef typename std::conditional::value, - AffineLoopNestBuilder, - LoopNestRangeBuilder>::type BuilderType; - std::unique_ptr builder; -}; - -} // namespace edsc - namespace linalg { class LinalgDependenceGraph; @@ -117,12 +55,13 @@ /// the inverse, concatenated loopToOperandRangeMaps to this list allows the /// derivation of loop ranges for any linalgOp. template -SmallVector getViewSizes(ConcreteOp linalgOp) { +SmallVector getViewSizes(OpBuilder &builder, ConcreteOp linalgOp) { + auto loc = linalgOp.getLoc(); SmallVector res; for (auto v : linalgOp.getInputsAndOutputs()) { MemRefType t = v.getType().template cast(); for (unsigned i = 0; i < t.getRank(); ++i) - res.push_back(edsc::intrinsics::dim(v, i)); + res.push_back(builder.create(loc, v, i)); } return res; } diff --git a/mlir/lib/Conversion/LinalgToLLVM/CMakeLists.txt b/mlir/lib/Conversion/LinalgToLLVM/CMakeLists.txt --- a/mlir/lib/Conversion/LinalgToLLVM/CMakeLists.txt +++ b/mlir/lib/Conversion/LinalgToLLVM/CMakeLists.txt @@ -5,7 +5,7 @@ ${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/LinalgToLLVM ) set(LIBS - MLIRLinalg + MLIRLinalgOps MLIRLLVMIR MLIRTransforms LLVMCore diff --git a/mlir/lib/Conversion/LoopsToGPU/CMakeLists.txt b/mlir/lib/Conversion/LoopsToGPU/CMakeLists.txt --- a/mlir/lib/Conversion/LoopsToGPU/CMakeLists.txt +++ b/mlir/lib/Conversion/LoopsToGPU/CMakeLists.txt @@ -2,7 +2,7 @@ MLIRAffineOps MLIRGPU MLIRIR - MLIRLinalg + MLIRLinalgOps MLIRPass MLIRStandardOps MLIRSupport diff --git a/mlir/lib/Dialect/Linalg/Analysis/CMakeLists.txt b/mlir/lib/Dialect/Linalg/Analysis/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/mlir/lib/Dialect/Linalg/Analysis/CMakeLists.txt @@ -0,0 +1,18 @@ +set(LIBS + + MLIRLinalgOps + MLIRStandardOps + ) + + +add_llvm_library(MLIRLinalgAnalysis + DependenceAnalysis.cpp + + ADDITIONAL_HEADER_DIRS + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg + DEPENDS + intrinsics_gen + ) + +add_dependencies(MLIRLinalgAnalysis ${LIBS}) +target_link_libraries(MLIRLinalgAnalysis ${LIBS}) diff --git a/mlir/lib/Dialect/Linalg/CMakeLists.txt b/mlir/lib/Dialect/Linalg/CMakeLists.txt --- a/mlir/lib/Dialect/Linalg/CMakeLists.txt +++ b/mlir/lib/Dialect/Linalg/CMakeLists.txt @@ -1,31 +1,5 @@ -add_llvm_library(MLIRLinalg - LinalgRegistration.cpp - Analysis/DependenceAnalysis.cpp - EDSC/Builders.cpp - IR/LinalgOps.cpp - IR/LinalgTypes.cpp - Transforms/Fusion.cpp - Transforms/LinalgTransforms.cpp - Transforms/LinalgToLoops.cpp - Transforms/Promotion.cpp - Transforms/Tiling.cpp - Utils/Utils.cpp - - ADDITIONAL_HEADER_DIRS - ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg - DEPENDS - intrinsics_gen - ) - -add_dependencies(MLIRLinalg - - MLIRAffineOps - MLIRAnalysis - MLIREDSC - MLIRLinalgOpsIncGen - MLIRLinalgStructuredOpsIncGen - MLIRLinalgTransformPatternsIncGen - MLIRStandardOps - MLIRStandardToLLVM - MLIRVectorOps - ) +add_subdirectory(Analysis) +add_subdirectory(EDSC) +add_subdirectory(IR) +add_subdirectory(Transforms) +add_subdirectory(Utils) diff --git a/mlir/lib/Dialect/Linalg/EDSC/Builders.cpp b/mlir/lib/Dialect/Linalg/EDSC/Builders.cpp --- a/mlir/lib/Dialect/Linalg/EDSC/Builders.cpp +++ b/mlir/lib/Dialect/Linalg/EDSC/Builders.cpp @@ -19,6 +19,96 @@ using namespace mlir::edsc; using namespace mlir::edsc::intrinsics; using namespace mlir::edsc::ops; +using namespace mlir::linalg; +using namespace mlir::loop; + +mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv, + ValueHandle range) { + assert(range.getType() && "expected !linalg.range type"); + assert(range.getValue().getDefiningOp() && + "need operations to extract range parts"); + auto rangeOp = cast(range.getValue().getDefiningOp()); + auto lb = rangeOp.min(); + auto ub = rangeOp.max(); + auto step = rangeOp.step(); + auto forOp = OperationHandle::createOp(lb, ub, step); + *iv = ValueHandle(forOp.getInductionVar()); + auto *body = forOp.getBody(); + enter(body, /*prev=*/1); +} + +mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv, + SubViewOp::Range range) { + auto forOp = + OperationHandle::createOp(range.offset, range.size, range.stride); + *iv = ValueHandle(forOp.getInductionVar()); + auto *body = forOp.getBody(); + enter(body, /*prev=*/1); +} + +ValueHandle mlir::edsc::LoopRangeBuilder:: +operator()(std::function fun) { + if (fun) + fun(); + exit(); + return ValueHandle::null(); +} + +mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder( + ArrayRef ivs, ArrayRef ranges) { + loops.reserve(ranges.size()); + for (unsigned i = 0, e = ranges.size(); i < e; ++i) { + loops.emplace_back(ivs[i], ranges[i]); + } + assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size"); +} + +mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder( + ArrayRef ivs, ArrayRef ranges) { + loops.reserve(ranges.size()); + for (unsigned i = 0, e = ranges.size(); i < e; ++i) { + loops.emplace_back(ivs[i], ranges[i]); + } + assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size"); +} + +mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder( + ArrayRef ivs, ArrayRef ranges) + : LoopNestRangeBuilder( + ivs, SmallVector(ranges.begin(), ranges.end())) {} + +ValueHandle LoopNestRangeBuilder::LoopNestRangeBuilder:: +operator()(std::function fun) { + if (fun) + fun(); + for (auto &lit : reverse(loops)) { + lit({}); + } + return ValueHandle::null(); +} + +template <> +GenericLoopNestRangeBuilder::GenericLoopNestRangeBuilder( + ArrayRef ivs, ArrayRef ranges) { + builder = std::make_unique(ivs, ranges); +} + +template <> +GenericLoopNestRangeBuilder::GenericLoopNestRangeBuilder( + ArrayRef ivs, ArrayRef ranges) { + SmallVector lbs; + SmallVector ubs; + SmallVector steps; + for (Value range : ranges) { + assert(range.getType() && "expected linalg.range type"); + assert(range.getDefiningOp() && "need operations to extract range parts"); + RangeOp rangeOp = cast(range.getDefiningOp()); + lbs.emplace_back(ValueHandle(rangeOp.min())); + ubs.emplace_back(ValueHandle(rangeOp.max())); + steps.emplace_back(ValueHandle(rangeOp.step())); + } + builder = std::make_unique(ivs, lbs, ubs, steps); +} static void getMaxDimIndex(ArrayRef structuredIndices, unsigned &pos) { diff --git a/mlir/lib/Dialect/Linalg/EDSC/CMakeLists.txt b/mlir/lib/Dialect/Linalg/EDSC/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/mlir/lib/Dialect/Linalg/EDSC/CMakeLists.txt @@ -0,0 +1,20 @@ +set(LIBS + + MLIREDSC + MLIRIR + MLIRLinalgOps + MLIRLoopOps + MLIRStandardOps + ) + +add_llvm_library(MLIRLinalgEDSC + Builders.cpp + + ADDITIONAL_HEADER_DIRS + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg + DEPENDS + intrinsics_gen + ) + +add_dependencies(MLIRLinalgEDSC ${LIBS}) +target_link_libraries(MLIRLinalgEDSC ${LIBS}) diff --git a/mlir/lib/Dialect/Linalg/IR/CMakeLists.txt b/mlir/lib/Dialect/Linalg/IR/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/mlir/lib/Dialect/Linalg/IR/CMakeLists.txt @@ -0,0 +1,23 @@ +set(LIBS + + MLIRIR + ) + +add_llvm_library(MLIRLinalgOps + LinalgOps.cpp + LinalgTypes.cpp + LinalgRegistration.cpp + + ADDITIONAL_HEADER_DIRS + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg + DEPENDS + intrinsics_gen + ) + +add_dependencies(MLIRLinalgOps + + ${LIBS} + MLIRLinalgOpsIncGen + MLIRLinalgStructuredOpsIncGen + ) +target_link_libraries(MLIRLinalgOps ${LIBS}) diff --git a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp --- a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp +++ b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp @@ -12,9 +12,6 @@ #include "mlir/Dialect/Linalg/IR/LinalgOps.h" #include "mlir/Dialect/Linalg/IR/LinalgTypes.h" -#include "mlir/Dialect/Linalg/Utils/Utils.h" -#include "mlir/Dialect/LoopOps/LoopOps.h" -#include "mlir/EDSC/Helpers.h" #include "mlir/IR/AffineExpr.h" #include "mlir/IR/AffineMap.h" #include "mlir/IR/Builders.h" @@ -26,15 +23,12 @@ #include "mlir/Support/Functional.h" #include "mlir/Support/LLVM.h" #include "mlir/Support/STLExtras.h" -#include "mlir/Transforms/FoldUtils.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" using namespace mlir; -using namespace mlir::edsc; -using namespace mlir::edsc::intrinsics; using namespace mlir::linalg; ///////////////////// Operations defined with Tablegen ///////////////////////// diff --git a/mlir/lib/Dialect/Linalg/LinalgRegistration.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgRegistration.cpp rename from mlir/lib/Dialect/Linalg/LinalgRegistration.cpp rename to mlir/lib/Dialect/Linalg/IR/LinalgRegistration.cpp diff --git a/mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt b/mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt @@ -0,0 +1,36 @@ +set(LIBS + + MLIRAffineOps + MLIRAnalysis + MLIREDSC + MLIRIR + MLIRLinalgAnalysis + MLIRLinalgEDSC + MLIRLinalgOps + MLIRLoopOps + MLIRPass + MLIRStandardOps + MLIRStandardToLLVM + MLIRTransformUtils + MLIRVectorOps + ) + +add_llvm_library(MLIRLinalgTransforms + Fusion.cpp + LinalgTransforms.cpp + LinalgToLoops.cpp + Promotion.cpp + Tiling.cpp + + ADDITIONAL_HEADER_DIRS + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg + DEPENDS + intrinsics_gen + ) + +add_dependencies(MLIRLinalgTransforms + + ${LIBS} + MLIRLinalgTransformPatternsIncGen + ) +target_link_libraries(MLIRLinalgTransforms ${LIBS}) diff --git a/mlir/lib/Dialect/Linalg/Transforms/LinalgToLoops.cpp b/mlir/lib/Dialect/Linalg/Transforms/LinalgToLoops.cpp --- a/mlir/lib/Dialect/Linalg/Transforms/LinalgToLoops.cpp +++ b/mlir/lib/Dialect/Linalg/Transforms/LinalgToLoops.cpp @@ -1,4 +1,4 @@ -//===- LowerToLoops.cpp - conversion from Linalg library ops to loops------===// +//===- LinalgToLoops.cpp - conversion from Linalg library ops to loops-----===// // // Part of the MLIR Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "mlir/Dialect/Linalg/EDSC/Builders.h" #include "mlir/Dialect/Linalg/IR/LinalgOps.h" #include "mlir/Dialect/Linalg/IR/LinalgTypes.h" #include "mlir/Dialect/Linalg/Passes.h" @@ -419,7 +420,7 @@ SmallVector allPIvs = makeHandlePointers(MutableArrayRef(allIvs)); auto loopRanges = emitLoopRanges(scope.getBuilder(), scope.getLocation(), - invertedMap, getViewSizes(linalgOp)); + invertedMap, getViewSizes(b, linalgOp)); assert(loopRanges.size() == allIvs.size()); GenericLoopNestRangeBuilder(allPIvs, loopRanges)([&] { diff --git a/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp b/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp --- a/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp +++ b/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "mlir/Dialect/Linalg/EDSC/Builders.h" #include "mlir/Dialect/Linalg/IR/LinalgOps.h" #include "mlir/Dialect/Linalg/IR/LinalgTypes.h" #include "mlir/Dialect/Linalg/Passes.h" @@ -329,7 +330,7 @@ b.setInsertionPoint(op); ScopedContext scope(b, op.getLoc()); // 2. Build the tiled loop ranges. - auto viewSizes = getViewSizes(op); + auto viewSizes = getViewSizes(b, op); // The flattened loopToOperandRangesMaps is expected to be an invertible // permutation map (asserted in the inverse calculation). auto viewSizesToLoopsMap = diff --git a/mlir/lib/Dialect/Linalg/Utils/CMakeLists.txt b/mlir/lib/Dialect/Linalg/Utils/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/mlir/lib/Dialect/Linalg/Utils/CMakeLists.txt @@ -0,0 +1,23 @@ +set(LIBS + + MLIREDSC + MLIRIR + MLIRLinalgOps + MLIRLoopOps + MLIRPass + MLIRStandardOps + MLIRTransformUtils + ) + +add_llvm_library(MLIRLinalgUtils + + Utils.cpp + + ADDITIONAL_HEADER_DIRS + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg + DEPENDS + intrinsics_gen + ) + +add_dependencies(MLIRLinalgUtils ${LIBS}) +target_link_libraries(MLIRLinalgUtils ${LIBS}) diff --git a/mlir/lib/Dialect/Linalg/Utils/Utils.cpp b/mlir/lib/Dialect/Linalg/Utils/Utils.cpp --- a/mlir/lib/Dialect/Linalg/Utils/Utils.cpp +++ b/mlir/lib/Dialect/Linalg/Utils/Utils.cpp @@ -13,7 +13,6 @@ #include "mlir/Dialect/Linalg/Utils/Utils.h" #include "mlir/Dialect/Linalg/IR/LinalgOps.h" #include "mlir/Dialect/Linalg/IR/LinalgTypes.h" -#include "mlir/Dialect/Linalg/Passes.h" #include "mlir/Dialect/Linalg/Utils/Intrinsics.h" #include "mlir/Dialect/LoopOps/LoopOps.h" #include "mlir/Dialect/StandardOps/Ops.h" @@ -32,102 +31,6 @@ using namespace mlir::linalg::intrinsics; using namespace mlir::loop; -mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv, - ValueHandle range) { - assert(range.getType() && "expected !linalg.range type"); - assert(range.getValue().getDefiningOp() && - "need operations to extract range parts"); - auto rangeOp = cast(range.getValue().getDefiningOp()); - auto lb = rangeOp.min(); - auto ub = rangeOp.max(); - auto step = rangeOp.step(); - auto forOp = OperationHandle::createOp(lb, ub, step); - *iv = ValueHandle(forOp.getInductionVar()); - auto *body = forOp.getBody(); - enter(body, /*prev=*/1); -} - -mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv, - SubViewOp::Range range) { - auto forOp = - OperationHandle::createOp(range.offset, range.size, range.stride); - *iv = ValueHandle(forOp.getInductionVar()); - auto *body = forOp.getBody(); - enter(body, /*prev=*/1); -} - -ValueHandle -mlir::edsc::LoopRangeBuilder::operator()(std::function fun) { - if (fun) - fun(); - exit(); - return ValueHandle::null(); -} - -mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder( - ArrayRef ivs, ArrayRef ranges) { - loops.reserve(ranges.size()); - for (unsigned i = 0, e = ranges.size(); i < e; ++i) { - loops.emplace_back(ivs[i], ranges[i]); - } - assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size"); -} - -mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder( - ArrayRef ivs, ArrayRef ranges) { - loops.reserve(ranges.size()); - for (unsigned i = 0, e = ranges.size(); i < e; ++i) { - loops.emplace_back(ivs[i], ranges[i]); - } - assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size"); -} - -mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder( - ArrayRef ivs, ArrayRef ranges) - : LoopNestRangeBuilder( - ivs, SmallVector(ranges.begin(), ranges.end())) {} - -ValueHandle LoopNestRangeBuilder::LoopNestRangeBuilder::operator()( - std::function fun) { - if (fun) - fun(); - for (auto &lit : reverse(loops)) { - lit({}); - } - return ValueHandle::null(); -} - -namespace mlir { -namespace edsc { - -template <> -GenericLoopNestRangeBuilder< - loop::ForOp>::GenericLoopNestRangeBuilder(ArrayRef ivs, - ArrayRef ranges) { - builder = std::make_unique(ivs, ranges); -} - -template <> -GenericLoopNestRangeBuilder< - AffineForOp>::GenericLoopNestRangeBuilder(ArrayRef ivs, - ArrayRef ranges) { - SmallVector lbs; - SmallVector ubs; - SmallVector steps; - for (Value range : ranges) { - assert(range.getType() && "expected linalg.range type"); - assert(range.getDefiningOp() && "need operations to extract range parts"); - RangeOp rangeOp = cast(range.getDefiningOp()); - lbs.emplace_back(ValueHandle(rangeOp.min())); - ubs.emplace_back(ValueHandle(rangeOp.max())); - steps.emplace_back(ValueHandle(rangeOp.step())); - } - builder = std::make_unique(ivs, lbs, ubs, steps); -} - -} // namespace edsc -} // namespace mlir - static Value emitOrFoldComposedAffineApply(OpBuilder &b, Location loc, AffineMap map, ArrayRef operandsRef, diff --git a/mlir/lib/Dialect/VectorOps/VectorTransforms.cpp b/mlir/lib/Dialect/VectorOps/VectorTransforms.cpp --- a/mlir/lib/Dialect/VectorOps/VectorTransforms.cpp +++ b/mlir/lib/Dialect/VectorOps/VectorTransforms.cpp @@ -12,11 +12,10 @@ #include +#include "mlir/Dialect/AffineOps/AffineOps.h" #include "mlir/Dialect/VectorOps/Utils.h" #include "mlir/Dialect/VectorOps/VectorOps.h" #include "mlir/Dialect/VectorOps/VectorTransforms.h" -#include "mlir/EDSC/Builders.h" -#include "mlir/EDSC/Helpers.h" #include "mlir/IR/AffineExpr.h" #include "mlir/IR/AffineMap.h" #include "mlir/IR/Attributes.h" diff --git a/mlir/test/EDSC/CMakeLists.txt b/mlir/test/EDSC/CMakeLists.txt --- a/mlir/test/EDSC/CMakeLists.txt +++ b/mlir/test/EDSC/CMakeLists.txt @@ -9,7 +9,8 @@ MLIRAffineOps MLIREDSC MLIRIR - MLIRLinalg + MLIRLinalgEDSC + MLIRLinalgOps MLIRLoopOps MLIRStandardOps MLIRTransforms @@ -21,7 +22,7 @@ whole_archive_link(mlir-edsc-builder-api-test MLIRAffineOps - MLIRLinalg + MLIRLinalgOps MLIRLoopOps MLIRStandardOps MLIRTransforms diff --git a/mlir/test/lib/Transforms/CMakeLists.txt b/mlir/test/lib/Transforms/CMakeLists.txt --- a/mlir/test/lib/Transforms/CMakeLists.txt +++ b/mlir/test/lib/Transforms/CMakeLists.txt @@ -29,6 +29,9 @@ MLIRAnalysis MLIREDSC MLIRGPU + MLIRLinalgOps + MLIRLinalgTransforms + MLIRLinalgUtils MLIRLoopOps MLIRPass MLIRTestDialect diff --git a/mlir/tools/mlir-opt/CMakeLists.txt b/mlir/tools/mlir-opt/CMakeLists.txt --- a/mlir/tools/mlir-opt/CMakeLists.txt +++ b/mlir/tools/mlir-opt/CMakeLists.txt @@ -29,7 +29,7 @@ MLIRGPUtoNVVMTransforms MLIRGPUtoROCDLTransforms MLIRGPUtoSPIRVTransforms - MLIRLinalg + MLIRLinalgOps MLIRLLVMIR MLIRLoopOps MLIRNVVMIR