[mlir][EDSC] Refactor dependencies involving EDSCs.
authorNicolas Vasilache <ntv@google.com>
Wed, 15 Jan 2020 14:28:12 +0000 (09:28 -0500)
committerNicolas Vasilache <ntv@google.com>
Wed, 15 Jan 2020 14:34:29 +0000 (09:34 -0500)
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

21 files changed:
mlir/include/mlir/Dialect/Linalg/EDSC/Builders.h
mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
mlir/lib/Conversion/LinalgToLLVM/CMakeLists.txt
mlir/lib/Conversion/LoopsToGPU/CMakeLists.txt
mlir/lib/Dialect/Linalg/Analysis/CMakeLists.txt [new file with mode: 0644]
mlir/lib/Dialect/Linalg/CMakeLists.txt
mlir/lib/Dialect/Linalg/EDSC/Builders.cpp
mlir/lib/Dialect/Linalg/EDSC/CMakeLists.txt [new file with mode: 0644]
mlir/lib/Dialect/Linalg/IR/CMakeLists.txt [new file with mode: 0644]
mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
mlir/lib/Dialect/Linalg/IR/LinalgRegistration.cpp [new file with mode: 0644]
mlir/lib/Dialect/Linalg/LinalgRegistration.cpp [deleted file]
mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt [new file with mode: 0644]
mlir/lib/Dialect/Linalg/Transforms/LinalgToLoops.cpp
mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
mlir/lib/Dialect/Linalg/Utils/CMakeLists.txt [new file with mode: 0644]
mlir/lib/Dialect/Linalg/Utils/Utils.cpp
mlir/lib/Dialect/VectorOps/VectorTransforms.cpp
mlir/test/EDSC/CMakeLists.txt
mlir/test/lib/Transforms/CMakeLists.txt
mlir/tools/mlir-opt/CMakeLists.txt

index 03f697a787bbe2c91c655b53b46ab7aa451d789c..fa813503103f0f7e09266034aeff1a31d107cac7 100644 (file)
@@ -24,6 +24,64 @@ namespace mlir {
 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) {
index f559ba4423dfdb042aed0662165e7c0ffba28ad2..52e966c69b4bd614076751dc0f008e174e8ac9a4 100644 (file)
@@ -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 AffineExpr;
 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;
 
@@ -117,12 +55,13 @@ Optional<FusionInfo> fuseProducerOf(OpBuilder &b, LinalgOp consumer,
 /// 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;
 }
index 16e3a34854d4d5a0e13c41c2aa242e41474b8ecf..838bb2f764a4710c73a5f15245f781c771c8eb0b 100644 (file)
@@ -5,7 +5,7 @@ add_llvm_library(MLIRLinalgToLLVM
   ${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/LinalgToLLVM
 )
 set(LIBS
-  MLIRLinalg
+  MLIRLinalgOps
   MLIRLLVMIR
   MLIRTransforms
   LLVMCore
index 2dacc800cb23eba8d325c9008f1ec1a465e72e40..b47f9cb892ffb2e9f8e75084508a9b242bd453d1 100644 (file)
@@ -2,7 +2,7 @@ set(LIBS
   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 (file)
index 0000000..d87563f
--- /dev/null
@@ -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})
index 2ca5da3eb2f54b1ddacc794a4acc30d0de9d1021..448d93bd0203babdabd3153de905f299b21335b8 100644 (file)
@@ -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)
index 9b8504311130d4dcbcc24fb77a95cf36c24f81fe..17fc23d63f45a77f22a5439381b2ea20d2c78021 100644 (file)
@@ -19,6 +19,96 @@ using namespace mlir;
 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) {
diff --git a/mlir/lib/Dialect/Linalg/EDSC/CMakeLists.txt b/mlir/lib/Dialect/Linalg/EDSC/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1ebacc8
--- /dev/null
@@ -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 (file)
index 0000000..af09f31
--- /dev/null
@@ -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})
index 7850dd60be1a09587939c38a0eb76c8f3d9fed7f..ba54a9269216b7eca75bc45731ebb4493b8b2aab 100644 (file)
@@ -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"
 #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/IR/LinalgRegistration.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgRegistration.cpp
new file mode 100644 (file)
index 0000000..768b18b
--- /dev/null
@@ -0,0 +1,16 @@
+//===- 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;
diff --git a/mlir/lib/Dialect/Linalg/LinalgRegistration.cpp b/mlir/lib/Dialect/Linalg/LinalgRegistration.cpp
deleted file mode 100644 (file)
index 768b18b..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-//===- 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;
diff --git a/mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt b/mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2c0b6e4
--- /dev/null
@@ -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})
index 2f97b62280a88faa0c102b9ff92a2477982f2837..7e1176f854cf9a7116c105e432ec2539fd8d4649 100644 (file)
@@ -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"
@@ -438,7 +439,7 @@ LogicalResult LinalgOpToLoopsImpl<LoopTy, IndexedValueTy, ConcreteOpTy>::doit(
   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)([&] {
index ed9553d710d710999292dd006ad6201f3eab787c..003707b261396b35bb5e5234a8f8c4cec40e8d43 100644 (file)
@@ -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"
@@ -333,7 +334,7 @@ mlir::linalg::tileLinalgOp(OpBuilder &b, LinalgOp op, ArrayRef<Value> tileSizes,
   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 (file)
index 0000000..8b98077
--- /dev/null
@@ -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})
index 1b8a7be7a224a9765aa387ff9234ef3dde72ffdc..5288c44097029770bfcc5ce3c294b3eea78de48b 100644 (file)
@@ -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;
 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,
index c86c4325d794a34de1b1f222c06e90698ba31ec4..e09dcdac42726f07416134db3a201e0f2def789a 100644 (file)
 
 #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"
index 0fb770411ea3d224ea561abdd0404a91771f1d29..0bdf1653bbc1c4fda6df1f125621b7af5f84167c 100644 (file)
@@ -9,7 +9,8 @@ target_link_libraries(mlir-edsc-builder-api-test
   MLIRAffineOps
   MLIREDSC
   MLIRIR
-  MLIRLinalg
+  MLIRLinalgEDSC
+  MLIRLinalgOps
   MLIRLoopOps
   MLIRStandardOps
   MLIRTransforms
@@ -21,7 +22,7 @@ target_include_directories(mlir-edsc-builder-api-test PRIVATE ..)
 
 whole_archive_link(mlir-edsc-builder-api-test
   MLIRAffineOps
-  MLIRLinalg
+  MLIRLinalgOps
   MLIRLoopOps
   MLIRStandardOps
   MLIRTransforms
index ac4a4930e5a512b4eedbd5d4e360e4f990281b71..b0509dbf74a9325d72464a5061d469517503099b 100644 (file)
@@ -29,6 +29,9 @@ target_link_libraries(MLIRTestTransforms
   MLIRAnalysis
   MLIREDSC
   MLIRGPU
+  MLIRLinalgOps
+  MLIRLinalgTransforms
+  MLIRLinalgUtils
   MLIRLoopOps
   MLIRPass
   MLIRTestDialect
index 1281569ef274163b16860e5014d42af4ca59db38..24bbca3a0ef7650f0a44f63e4c624fae64a997de 100644 (file)
@@ -29,7 +29,7 @@ set(LIBS
   MLIRGPUtoNVVMTransforms
   MLIRGPUtoROCDLTransforms
   MLIRGPUtoSPIRVTransforms
-  MLIRLinalg
+  MLIRLinalgOps
   MLIRLLVMIR
   MLIRLoopOps
   MLIRNVVMIR