Summary: This diff removes the dependency of LinalgOps and VectorOps on EDSCs.
Reviewers: jpienaar, ftynse
Reviewed By: ftynse
Subscribers: merge_guards_bot, mgorny, mehdi_amini, rriddle, burmako, shauheen, antiagainst, csigg, arpith-jacob, mgester, lucyrfox, herhut, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D72481
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<void(void)> 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<edsc::ValueHandle *> ivs,
+ ArrayRef<edsc::ValueHandle> ranges);
+ LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
+ ArrayRef<Value> ranges);
+ LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
+ ArrayRef<SubViewOp::Range> ranges);
+ edsc::ValueHandle operator()(std::function<void(void)> fun = nullptr);
+
+private:
+ SmallVector<LoopRangeBuilder, 4> loops;
+};
+
+/// Helper template class for building loop.for and affine.loop nests from
+/// ranges.
+template <typename LoopTy> class GenericLoopNestRangeBuilder {
+public:
+ GenericLoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
+ ArrayRef<Value> ranges);
+ void operator()(std::function<void(void)> fun = nullptr) { (*builder)(fun); }
+
+private:
+ typedef typename std::conditional<std::is_same<LoopTy, AffineForOp>::value,
+ AffineLoopNestBuilder,
+ LoopNestRangeBuilder>::type BuilderType;
+ std::unique_ptr<BuilderType> builder;
+};
+
enum class IterType { Parallel, Reduction };
inline StringRef toString(IterType t) {
#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"
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<void(void)> 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<edsc::ValueHandle *> ivs,
- ArrayRef<edsc::ValueHandle> ranges);
- LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
- ArrayRef<Value> ranges);
- LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
- ArrayRef<SubViewOp::Range> ranges);
- edsc::ValueHandle operator()(std::function<void(void)> fun = nullptr);
-
-private:
- SmallVector<LoopRangeBuilder, 4> loops;
-};
-
-/// Helper template class for building loop.for and affine.loop nests from
-/// ranges.
-template <typename LoopTy> class GenericLoopNestRangeBuilder {
-public:
- GenericLoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
- ArrayRef<Value> ranges);
- void operator()(std::function<void(void)> fun = nullptr) { (*builder)(fun); }
-
-private:
- typedef typename std::conditional<std::is_same<LoopTy, AffineForOp>::value,
- AffineLoopNestBuilder,
- LoopNestRangeBuilder>::type BuilderType;
- std::unique_ptr<BuilderType> builder;
-};
-
-} // namespace edsc
-
namespace linalg {
class LinalgDependenceGraph;
/// the inverse, concatenated loopToOperandRangeMaps to this list allows the
/// derivation of loop ranges for any linalgOp.
template <typename ConcreteOp>
-SmallVector<Value, 8> getViewSizes(ConcreteOp linalgOp) {
+SmallVector<Value, 8> getViewSizes(OpBuilder &builder, ConcreteOp linalgOp) {
+ auto loc = linalgOp.getLoc();
SmallVector<Value, 8> res;
for (auto v : linalgOp.getInputsAndOutputBuffers()) {
MemRefType t = v.getType().template cast<MemRefType>();
for (unsigned i = 0; i < t.getRank(); ++i)
- res.push_back(edsc::intrinsics::dim(v, i));
+ res.push_back(builder.create<DimOp>(loc, v, i));
}
return res;
}
${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/LinalgToLLVM
)
set(LIBS
- MLIRLinalg
+ MLIRLinalgOps
MLIRLLVMIR
MLIRTransforms
LLVMCore
MLIRAffineOps
MLIRGPU
MLIRIR
- MLIRLinalg
+ MLIRLinalgOps
MLIRPass
MLIRStandardOps
MLIRSupport
--- /dev/null
+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})
-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)
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<RangeOp>(range.getValue().getDefiningOp());
+ auto lb = rangeOp.min();
+ auto ub = rangeOp.max();
+ auto step = rangeOp.step();
+ auto forOp = OperationHandle::createOp<ForOp>(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<ForOp>(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<void(void)> fun) {
+ if (fun)
+ fun();
+ exit();
+ return ValueHandle::null();
+}
+
+mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
+ ArrayRef<ValueHandle *> ivs, ArrayRef<SubViewOp::Range> 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<ValueHandle *> ivs, ArrayRef<ValueHandle> 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<ValueHandle *> ivs, ArrayRef<Value> ranges)
+ : LoopNestRangeBuilder(
+ ivs, SmallVector<ValueHandle, 4>(ranges.begin(), ranges.end())) {}
+
+ValueHandle LoopNestRangeBuilder::LoopNestRangeBuilder::
+operator()(std::function<void(void)> fun) {
+ if (fun)
+ fun();
+ for (auto &lit : reverse(loops)) {
+ lit({});
+ }
+ return ValueHandle::null();
+}
+
+template <>
+GenericLoopNestRangeBuilder<loop::ForOp>::GenericLoopNestRangeBuilder(
+ ArrayRef<edsc::ValueHandle *> ivs, ArrayRef<Value> ranges) {
+ builder = std::make_unique<LoopNestRangeBuilder>(ivs, ranges);
+}
+
+template <>
+GenericLoopNestRangeBuilder<AffineForOp>::GenericLoopNestRangeBuilder(
+ ArrayRef<ValueHandle *> ivs, ArrayRef<Value> ranges) {
+ SmallVector<ValueHandle, 4> lbs;
+ SmallVector<ValueHandle, 4> ubs;
+ SmallVector<int64_t, 4> steps;
+ for (Value range : ranges) {
+ assert(range.getType() && "expected linalg.range type");
+ assert(range.getDefiningOp() && "need operations to extract range parts");
+ RangeOp rangeOp = cast<RangeOp>(range.getDefiningOp());
+ lbs.emplace_back(ValueHandle(rangeOp.min()));
+ ubs.emplace_back(ValueHandle(rangeOp.max()));
+ steps.emplace_back(ValueHandle(rangeOp.step()));
+ }
+ builder = std::make_unique<AffineLoopNestBuilder>(ivs, lbs, ubs, steps);
+}
static void getMaxDimIndex(ArrayRef<StructuredIndexed> structuredIndices,
unsigned &pos) {
--- /dev/null
+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})
--- /dev/null
+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})
#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"
#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 /////////////////////////
--- /dev/null
+//===- LinalgRegistration.cpp - Register the linalg dialect statically ----===//
+//
+// Part of the MLIR 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/Dialect/Linalg/IR/LinalgOps.h"
+#include "mlir/Dialect/Linalg/IR/LinalgTypes.h"
+
+using namespace mlir;
+using namespace mlir::linalg;
+
+// Static initialization for LinalgOps dialect registration.
+static DialectRegistration<LinalgDialect> LinalgOps;
+++ /dev/null
-//===- LinalgRegistration.cpp - Register the linalg dialect statically ----===//
-//
-// Part of the MLIR 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/Dialect/Linalg/IR/LinalgOps.h"
-#include "mlir/Dialect/Linalg/IR/LinalgTypes.h"
-
-using namespace mlir;
-using namespace mlir::linalg;
-
-// Static initialization for LinalgOps dialect registration.
-static DialectRegistration<LinalgDialect> LinalgOps;
--- /dev/null
+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})
-//===- 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.
//
//===----------------------------------------------------------------------===//
+#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"
SmallVector<ValueHandle *, 4> allPIvs =
makeHandlePointers(MutableArrayRef<IndexHandle>(allIvs));
auto loopRanges = emitLoopRanges(scope.getBuilder(), scope.getLocation(),
- invertedMap, getViewSizes(linalgOp));
+ invertedMap, getViewSizes(b, linalgOp));
assert(loopRanges.size() == allIvs.size());
GenericLoopNestRangeBuilder<LoopTy>(allPIvs, loopRanges)([&] {
//
//===----------------------------------------------------------------------===//
+#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"
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 =
--- /dev/null
+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})
#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"
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<RangeOp>(range.getValue().getDefiningOp());
- auto lb = rangeOp.min();
- auto ub = rangeOp.max();
- auto step = rangeOp.step();
- auto forOp = OperationHandle::createOp<ForOp>(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<ForOp>(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<void(void)> fun) {
- if (fun)
- fun();
- exit();
- return ValueHandle::null();
-}
-
-mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
- ArrayRef<ValueHandle *> ivs, ArrayRef<SubViewOp::Range> 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<ValueHandle *> ivs, ArrayRef<ValueHandle> 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<ValueHandle *> ivs, ArrayRef<Value> ranges)
- : LoopNestRangeBuilder(
- ivs, SmallVector<ValueHandle, 4>(ranges.begin(), ranges.end())) {}
-
-ValueHandle LoopNestRangeBuilder::LoopNestRangeBuilder::operator()(
- std::function<void(void)> fun) {
- if (fun)
- fun();
- for (auto &lit : reverse(loops)) {
- lit({});
- }
- return ValueHandle::null();
-}
-
-namespace mlir {
-namespace edsc {
-
-template <>
-GenericLoopNestRangeBuilder<
- loop::ForOp>::GenericLoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
- ArrayRef<Value> ranges) {
- builder = std::make_unique<LoopNestRangeBuilder>(ivs, ranges);
-}
-
-template <>
-GenericLoopNestRangeBuilder<
- AffineForOp>::GenericLoopNestRangeBuilder(ArrayRef<ValueHandle *> ivs,
- ArrayRef<Value> ranges) {
- SmallVector<ValueHandle, 4> lbs;
- SmallVector<ValueHandle, 4> ubs;
- SmallVector<int64_t, 4> steps;
- for (Value range : ranges) {
- assert(range.getType() && "expected linalg.range type");
- assert(range.getDefiningOp() && "need operations to extract range parts");
- RangeOp rangeOp = cast<RangeOp>(range.getDefiningOp());
- lbs.emplace_back(ValueHandle(rangeOp.min()));
- ubs.emplace_back(ValueHandle(rangeOp.max()));
- steps.emplace_back(ValueHandle(rangeOp.step()));
- }
- builder = std::make_unique<AffineLoopNestBuilder>(ivs, lbs, ubs, steps);
-}
-
-} // namespace edsc
-} // namespace mlir
-
static Value emitOrFoldComposedAffineApply(OpBuilder &b, Location loc,
AffineMap map,
ArrayRef<Value> operandsRef,
#include <type_traits>
+#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"
MLIRAffineOps
MLIREDSC
MLIRIR
- MLIRLinalg
+ MLIRLinalgEDSC
+ MLIRLinalgOps
MLIRLoopOps
MLIRStandardOps
MLIRTransforms
whole_archive_link(mlir-edsc-builder-api-test
MLIRAffineOps
- MLIRLinalg
+ MLIRLinalgOps
MLIRLoopOps
MLIRStandardOps
MLIRTransforms
MLIRAnalysis
MLIREDSC
MLIRGPU
+ MLIRLinalgOps
+ MLIRLinalgTransforms
+ MLIRLinalgUtils
MLIRLoopOps
MLIRPass
MLIRTestDialect
MLIRGPUtoNVVMTransforms
MLIRGPUtoROCDLTransforms
MLIRGPUtoSPIRVTransforms
- MLIRLinalg
+ MLIRLinalgOps
MLIRLLVMIR
MLIRLoopOps
MLIRNVVMIR