summaryrefslogtreecommitdiffstats
path: root/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'mlir/include/mlir/Dialect/Linalg/Utils/Utils.h')
-rw-r--r--mlir/include/mlir/Dialect/Linalg/Utils/Utils.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h b/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
new file mode 100644
index 00000000000..ff46f6a10ce
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
@@ -0,0 +1,156 @@
+//===- Utils.h - Utilities to support the Linalg dialect --------*- C++ -*-===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// =============================================================================
+
+#ifndef MLIR_DIALECT_LINALG_UTILS_H_
+#define MLIR_DIALECT_LINALG_UTILS_H_
+
+#include "mlir/Dialect/LoopOps/LoopOps.h"
+#include "mlir/EDSC/Helpers.h"
+#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
+#include "mlir/Dialect/Linalg/Utils/Intrinsics.h"
+#include "mlir/Support/LLVM.h"
+
+namespace mlir {
+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, linalg::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::LoopNestBuilder except it works on ranges directly.
+/// In the current implementation it produces loop.for operations.
+class LoopNestRangeBuilder {
+public:
+ LoopNestRangeBuilder(llvm::ArrayRef<edsc::ValueHandle *> ivs,
+ llvm::ArrayRef<edsc::ValueHandle> ranges);
+ LoopNestRangeBuilder(llvm::ArrayRef<edsc::ValueHandle *> ivs,
+ llvm::ArrayRef<Value *> ranges);
+ LoopNestRangeBuilder(llvm::ArrayRef<edsc::ValueHandle *> ivs,
+ llvm::ArrayRef<linalg::SubViewOp::Range> ranges);
+ edsc::ValueHandle operator()(std::function<void(void)> fun = nullptr);
+
+private:
+ llvm::SmallVector<LoopRangeBuilder, 4> loops;
+};
+
+} // namespace edsc
+
+namespace linalg {
+
+/// Returns the linearized list of all view dimensions in a linalgOp. Applying
+/// 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> res;
+ for (auto v : linalgOp.getInputsAndOutputs()) {
+ ViewType t = v->getType().template cast<ViewType>();
+ for (unsigned i = 0; i < t.getRank(); ++i)
+ res.push_back(intrinsics::dim(v, i));
+ }
+ return res;
+}
+
+/// Returns the values obtained by applying `map` to the list of values.
+/// Performs simplifications and foldings where possible.
+SmallVector<Value *, 4> applyMapToValues(OpBuilder &b, Location loc,
+ AffineMap map,
+ ArrayRef<Value *> values,
+ OperationFolder &state);
+
+struct TiledLinalgOp {
+ LinalgOp op;
+ SmallVector<loop::ForOp, 8> loops;
+};
+
+/// Performs standalone tiling of a single LinalgOp by `tileSizes`.
+/// Inserts scoped local buffers and copies tiled views into/from those buffers
+/// when the corresponding entry in `viewsToPromote` is true.
+/// Returns a struct containing the tiled loops and the cloned op if successful,
+/// llvm::None otherwise.
+// TODO(ntv) implement a heuristic for view promotion.
+llvm::Optional<TiledLinalgOp> tileLinalgOp(LinalgOp op,
+ ArrayRef<Value *> tileSizes,
+ OperationFolder &folder,
+ ArrayRef<bool> viewsToPromote = {});
+
+/// Performs standalone tiling of a single LinalgOp by constant `tileSizes`.
+/// Inserts scoped local buffers and copies tiled views into/from those buffers
+/// when the corresponding entry in `viewsToPromote` is true.
+/// Returns a struct containing the tiled loops and the cloned op if successful,
+/// llvm::None otherwise.
+// TODO(ntv) implement a heuristic for view promotion.
+llvm::Optional<TiledLinalgOp> tileLinalgOp(LinalgOp op,
+ ArrayRef<int64_t> tileSizes,
+ OperationFolder &folder,
+ ArrayRef<bool> viewsToPromote = {});
+
+struct PromotionInfo {
+ Value *buffer;
+ Value *fullLocalView;
+ Value *partialLocalView;
+};
+
+/// Promotes the `views` into a new buffer allocated at the insertion point `b`.
+/// For now, promotion occurs in 3 steps:
+/// 1. Create a new buffer for a full tile (i.e. not clipped at the boundary).
+/// 2. Take a full view on the buffer and `linalg.fill` it with zeros (use
+/// float zero for now).
+/// 3. Take a partial slice of the full view in step 2. and copy into it.
+///
+/// Returns a list of PromotionInfo which hold the promoted buffer and the
+/// full and partial views indexing into the buffer.
+llvm::SmallVector<PromotionInfo, 8> promoteLinalgViews(OpBuilder &b,
+ Location loc,
+ ArrayRef<Value *> views,
+ OperationFolder &folder);
+
+/// Returns all the operands of `linalgOp` that are not views.
+/// Asserts that these operands are value types to allow transformations like
+/// tiling to just use the values when cloning `linalgOp`.
+llvm::SmallVector<Value *, 4> getAssumedNonViewOperands(LinalgOp linalgOp);
+
+} // namespace linalg
+} // namespace mlir
+
+#endif // MLIR_DIALECT_LINALG_UTILS_H_
OpenPOWER on IntegriCloud