summaryrefslogtreecommitdiff
path: root/include/linalg1
diff options
context:
space:
mode:
Diffstat (limited to 'include/linalg1')
-rw-r--r--include/linalg1/Analysis.h49
-rw-r--r--include/linalg1/Common.h120
-rw-r--r--include/linalg1/ConvertToLLVMDialect.h66
-rw-r--r--include/linalg1/Dialect.h42
-rw-r--r--include/linalg1/Intrinsics.h32
-rw-r--r--include/linalg1/LLVMIntrinsics.h41
-rw-r--r--include/linalg1/Ops.h26
-rw-r--r--include/linalg1/RangeOp.h56
-rw-r--r--include/linalg1/RangeType.h49
-rw-r--r--include/linalg1/SliceOp.h91
-rw-r--r--include/linalg1/Types.h36
-rw-r--r--include/linalg1/Utils.h37
-rw-r--r--include/linalg1/ViewOp.h67
-rw-r--r--include/linalg1/ViewType.h57
14 files changed, 769 insertions, 0 deletions
diff --git a/include/linalg1/Analysis.h b/include/linalg1/Analysis.h
new file mode 100644
index 0000000..ef8fb98
--- /dev/null
+++ b/include/linalg1/Analysis.h
@@ -0,0 +1,49 @@
+//===- Analysis.h - Linalg dialect Analysis function definitions ----------===//
+//
+// 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 LINALG1_ANALYSIS_H_
+#define LINALG1_ANALYSIS_H_
+
+#include "mlir/Support/LLVM.h"
+
+namespace mlir {
+class Value;
+} // namespace mlir
+
+namespace linalg {
+class ViewOp;
+
+/// Walks the chain of SliceOp until the unique base ViewOp.
+ViewOp getViewBaseViewOp(mlir::Value *view);
+
+/// Walks the chain of SliceOp until the unique base ViewOp and returns the
+/// MemRef upon which the ViewOp is laid.
+mlir::Value *getViewSupportingMemRef(mlir::Value *view);
+
+/// Extract the indexing from the root ViewOp that this slice constrins along
+/// `dim`. To achieve this, it walks back the chain of SliceOp and determine the
+/// first slice that constrains `dim`.
+/// Note that the dimension in the original ViewOp may shift due to
+/// rank-reducing operations.
+/// Returns a pair, with the indexing as the first element and the actual
+/// dimension, in the root ViewOp, as the second element.
+std::pair<mlir::Value *, unsigned> getViewRootIndexing(mlir::Value *view,
+ unsigned dim);
+
+} // namespace linalg
+
+#endif // LINALG1_ANALYSIS_H_
diff --git a/include/linalg1/Common.h b/include/linalg1/Common.h
new file mode 100644
index 0000000..6573c72
--- /dev/null
+++ b/include/linalg1/Common.h
@@ -0,0 +1,120 @@
+//===- Common.h - Linalg dialect RangeOp operation -----------------------===//
+//
+// 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 LINALG1_COMMON_H_
+#define LINALG1_COMMON_H_
+
+#include "mlir/AffineOps/AffineOps.h"
+#include "mlir/Analysis/SliceAnalysis.h"
+#include "mlir/EDSC/Builders.h"
+#include "mlir/EDSC/Helpers.h"
+#include "mlir/EDSC/Intrinsics.h"
+#include "mlir/IR/AffineExpr.h"
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/Identifier.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/Module.h"
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/IR/StandardTypes.h"
+#include "mlir/IR/Types.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Pass/PassManager.h"
+#include "mlir/StandardOps/Ops.h"
+#include "mlir/Support/LogicalResult.h"
+#include "mlir/Transforms/LoopUtils.h"
+#include "mlir/Transforms/Passes.h"
+
+namespace linalg {
+namespace common {
+
+////////////////////////////////////////////////////////////////////////////////
+// Define a few boilerplate objects used across all linalg examples.
+////////////////////////////////////////////////////////////////////////////////
+
+/// A 2-D abstraction over a flat contiguous memory region of f32 with symbolic
+/// sizes.
+template <int N>
+inline mlir::MemRefType floatMemRefType(mlir::MLIRContext *context,
+ unsigned memorySpace = 0) {
+ llvm::SmallVector<int64_t, 4> shape(N, -1);
+ auto f32 = mlir::FloatType::getF32(context);
+ return mlir::MemRefType::get(shape, f32, {}, memorySpace);
+}
+
+/// A basic function builder
+inline mlir::Function *makeFunction(mlir::Module &module, llvm::StringRef name,
+ llvm::ArrayRef<mlir::Type> types,
+ llvm::ArrayRef<mlir::Type> resultTypes) {
+ auto *context = module.getContext();
+ auto *function = new mlir::Function(
+ mlir::UnknownLoc::get(context), name,
+ mlir::FunctionType::get({types}, resultTypes, context));
+ function->addEntryBlock();
+ module.getFunctions().push_back(function);
+ return function;
+}
+
+/// A basic pass manager pre-populated with cleanup passes.
+inline std::unique_ptr<mlir::PassManager> cleanupPassManager() {
+ std::unique_ptr<mlir::PassManager> pm(new mlir::PassManager());
+ pm->addPass(mlir::createCanonicalizerPass());
+ pm->addPass(mlir::createSimplifyAffineStructuresPass());
+ pm->addPass(mlir::createCSEPass());
+ pm->addPass(mlir::createCanonicalizerPass());
+ return pm;
+}
+
+/// A simple function to verify and cleanup the IR before printing it to
+/// llvm::outs() for FileCheck'ing.
+/// If an error occurs, dump to llvm::errs() and do not print to llvm::outs()
+/// which will make the associated FileCheck test fail.
+inline void cleanupAndPrintFunction(mlir::Function *f) {
+ bool printToOuts = true;
+ auto check = [f, &printToOuts](mlir::LogicalResult result) {
+ if (failed(result)) {
+ f->getContext()->emitError(f->getLoc(),
+ "Verification and cleanup passes failed");
+ printToOuts = false;
+ }
+ };
+ auto pm = cleanupPassManager();
+ check(f->getModule()->verify());
+ check(pm->run(f->getModule()));
+ if (printToOuts)
+ f->print(llvm::outs());
+}
+
+/// Helper class to sugar building loop nests from indexings that appear in
+/// ViewOp and SliceOp.
+class LoopNestRangeBuilder {
+public:
+ LoopNestRangeBuilder(llvm::ArrayRef<mlir::edsc::ValueHandle *> ivs,
+ llvm::ArrayRef<mlir::edsc::ValueHandle> indexings);
+ LoopNestRangeBuilder(llvm::ArrayRef<mlir::edsc::ValueHandle *> ivs,
+ llvm::ArrayRef<mlir::Value *> indexings);
+ mlir::edsc::ValueHandle
+ operator()(llvm::ArrayRef<mlir::edsc::CapturableHandle> stmts);
+
+private:
+ llvm::SmallVector<mlir::edsc::LoopBuilder, 4> loops;
+};
+
+} // namespace common
+} // namespace linalg
+
+#endif // LINALG1_COMMON_H_
diff --git a/include/linalg1/ConvertToLLVMDialect.h b/include/linalg1/ConvertToLLVMDialect.h
new file mode 100644
index 0000000..8e5a7ce
--- /dev/null
+++ b/include/linalg1/ConvertToLLVMDialect.h
@@ -0,0 +1,66 @@
+//===- ConvertToLLVMDialect.h - conversion from Linalg to LLVM --*- 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 LINALG1_CONVERTTOLLVMDIALECT_H_
+#define LINALG1_CONVERTTOLLVMDIALECT_H_
+
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/Allocator.h"
+
+#include <memory>
+
+namespace mlir {
+class DialectConversion;
+class DialectOpConversion;
+class MLIRContext;
+class Module;
+class Type;
+namespace LLVM {
+class LLVMType;
+} // end namespace LLVM
+} // end namespace mlir
+
+namespace linalg {
+/// Convert the given Linalg dialect type `t` into an LLVM IR dialect type.
+/// Keep all other types unmodified.
+mlir::Type convertLinalgType(mlir::Type t);
+
+/// Allocate the conversion patterns for RangeOp, ViewOp and SliceOp from the
+/// Linalg dialect to the LLVM IR dialect. The converters are allocated in the
+/// `allocator` using the provided `context`. The latter must have the LLVM IR
+/// dialect registered.
+/// This function can be used to apply multiple conversion patterns in the same
+/// pass. It does not have to be called explicitly before the conversion.
+llvm::DenseSet<mlir::DialectOpConversion *>
+allocateDescriptorConverters(llvm::BumpPtrAllocator *allocator,
+ mlir::MLIRContext *context);
+
+/// Create a DialectConversion from the Linalg dialect to the LLVM IR dialect.
+/// The conversion is set up to convert types and function signatures using
+/// `convertLinalgType` and obtains operation converters by calling `initer`.
+std::unique_ptr<mlir::DialectConversion> makeLinalgToLLVMLowering(
+ std::function<llvm::DenseSet<mlir::DialectOpConversion *>(
+ llvm::BumpPtrAllocator *, mlir::MLIRContext *context)>
+ initer);
+
+/// Convert the Linalg dialect types and RangeOp, ViewOp and SliceOp operations
+/// to the LLVM IR dialect types and operations in the given `module`. This is
+/// the main entry point to the conversion.
+void convertToLLVM(mlir::Module &module);
+} // end namespace linalg
+
+#endif // LINALG1_CONVERTTOLLVMDIALECT_H_
diff --git a/include/linalg1/Dialect.h b/include/linalg1/Dialect.h
new file mode 100644
index 0000000..70023e1
--- /dev/null
+++ b/include/linalg1/Dialect.h
@@ -0,0 +1,42 @@
+//===- Dialect.h - Definition of the Linalg dialect -----------------------===//
+//
+// 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 LINALG1_DIALECT_H_
+#define LINALG1_DIALECT_H_
+
+#include "mlir/IR/Dialect.h"
+
+namespace linalg {
+
+/// The Linalg Dialect is not exposed to the outside world. It is registered by
+/// linking and accessed via generic MLIR accessors.
+class LinalgDialect : public mlir::Dialect {
+public:
+ /// Create a new Dialect that is registered on construction and adds the
+ /// relevant types and operations.
+ explicit LinalgDialect(mlir::MLIRContext *context);
+
+ /// Parse a type registered to this dialect.
+ mlir::Type parseType(llvm::StringRef spec, mlir::Location loc) const override;
+
+ /// Print a type registered to this dialect.
+ void printType(mlir::Type type, llvm::raw_ostream &os) const override;
+};
+
+} // namespace linalg
+
+#endif // LINALG1_DIALECT_H_
diff --git a/include/linalg1/Intrinsics.h b/include/linalg1/Intrinsics.h
new file mode 100644
index 0000000..305e3f3
--- /dev/null
+++ b/include/linalg1/Intrinsics.h
@@ -0,0 +1,32 @@
+//===- Intrinsics.h - Linalg intrinsics definitions -----------------------===//
+//
+// 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 LINALG1_INTRINSICS_H_
+#define LINALG1_INTRINSICS_H_
+
+#include "linalg1/Ops.h"
+#include "mlir/EDSC/Intrinsics.h"
+
+namespace linalg {
+namespace intrinsics {
+using range = mlir::edsc::intrinsics::ValueBuilder<RangeOp>;
+using slice = mlir::edsc::intrinsics::ValueBuilder<SliceOp>;
+using view = mlir::edsc::intrinsics::ValueBuilder<ViewOp>;
+} // namespace intrinsics
+} // namespace linalg
+
+#endif // LINALG1_INTRINSICS_H_
diff --git a/include/linalg1/LLVMIntrinsics.h b/include/linalg1/LLVMIntrinsics.h
new file mode 100644
index 0000000..577981b
--- /dev/null
+++ b/include/linalg1/LLVMIntrinsics.h
@@ -0,0 +1,41 @@
+//===- LLVMIntrinsics.h - declarative builders for LLVM 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 LINALG1_LLVMINTRINSICS_H_
+#define LINALG1_LLVMINTRINSICS_H_
+
+#include "mlir/EDSC/Builders.h"
+#include "mlir/EDSC/Intrinsics.h"
+#include "mlir/LLVMIR/LLVMDialect.h"
+
+// Expose some LLVM IR instructions to declarative builders.
+namespace intrinsics {
+using undef = mlir::edsc::intrinsics::ValueBuilder<mlir::LLVM::UndefOp>;
+using insertvalue =
+ mlir::edsc::intrinsics::ValueBuilder<mlir::LLVM::InsertValueOp>;
+using extractvalue =
+ mlir::edsc::intrinsics::ValueBuilder<mlir::LLVM::ExtractValueOp>;
+using constant = mlir::edsc::intrinsics::ValueBuilder<mlir::LLVM::ConstantOp>;
+using add = mlir::edsc::intrinsics::ValueBuilder<mlir::LLVM::AddOp>;
+using sub = mlir::edsc::intrinsics::ValueBuilder<mlir::LLVM::SubOp>;
+using mul = mlir::edsc::intrinsics::ValueBuilder<mlir::LLVM::MulOp>;
+using load = mlir::edsc::intrinsics::ValueBuilder<mlir::LLVM::LoadOp>;
+using store = mlir::edsc::intrinsics::OperationBuilder<mlir::LLVM::StoreOp>;
+using gep = mlir::edsc::intrinsics::ValueBuilder<mlir::LLVM::GEPOp>;
+} // end namespace intrinsics
+
+#endif // LINALG1_LLVMINTRINSICS_H_
diff --git a/include/linalg1/Ops.h b/include/linalg1/Ops.h
new file mode 100644
index 0000000..2e662cf
--- /dev/null
+++ b/include/linalg1/Ops.h
@@ -0,0 +1,26 @@
+//===- Ops.h - Linalg Ops single entry point ------------------------------===//
+//
+// 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 LINALG1_OPS_H_
+#define LINALG1_OPS_H_
+
+#include "linalg1/Types.h"
+#include "linalg1/RangeOp.h"
+#include "linalg1/SliceOp.h"
+#include "linalg1/ViewOp.h"
+
+#endif // LINALG1_OPS_H_
diff --git a/include/linalg1/RangeOp.h b/include/linalg1/RangeOp.h
new file mode 100644
index 0000000..9652f51
--- /dev/null
+++ b/include/linalg1/RangeOp.h
@@ -0,0 +1,56 @@
+//===- RangeOp.h - Linalg dialect RangeOp operation definition ------------===//
+//
+// 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 LINALG1_RANGEOP_H_
+#define LINALG1_RANGEOP_H_
+
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/Support/LLVM.h"
+
+namespace linalg {
+
+/// A RangeOp is used to create a value of RangeType from 3 values of type index
+/// that represent the min, max and step values of the range.
+/// Note: step must be an mlir::ConstantIndexOp for now due to current
+/// `affine.for` limitations.
+class RangeOp : public mlir::Op<RangeOp, mlir::OpTrait::NOperands<3>::Impl,
+ mlir::OpTrait::OneResult,
+ mlir::OpTrait::HasNoSideEffect> {
+public:
+ using Op::Op;
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Hooks to customize the behavior of this op.
+ //////////////////////////////////////////////////////////////////////////////
+ static llvm::StringRef getOperationName() { return "linalg.range"; }
+ static void build(mlir::Builder *b, mlir::OperationState *result,
+ mlir::Value *min, mlir::Value *max, mlir::Value *step);
+ mlir::LogicalResult verify();
+ static bool parse(mlir::OpAsmParser *parser, mlir::OperationState *result);
+ void print(mlir::OpAsmPrinter *p);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Op-specific functionality.
+ //////////////////////////////////////////////////////////////////////////////
+ mlir::Value *getMin() { return getOperand(0); }
+ mlir::Value *getMax() { return getOperand(1); }
+ mlir::Value *getStep() { return getOperand(2); }
+};
+
+} // namespace linalg
+
+#endif // LINALG1_RANGEOP_H_
diff --git a/include/linalg1/RangeType.h b/include/linalg1/RangeType.h
new file mode 100644
index 0000000..d17c058
--- /dev/null
+++ b/include/linalg1/RangeType.h
@@ -0,0 +1,49 @@
+//===- RangeType.h - Linalg RangeType definition --------------------------===//
+//
+// 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 LINALG1_RANGETYPE_H_
+#define LINALG1_RANGETYPE_H_
+
+#include "linalg1/Types.h"
+#include "mlir/IR/Types.h"
+
+namespace mlir {
+class MLIRContext;
+}
+
+namespace linalg {
+
+/// A RangeType is the simplest possible form of a type in MLIR. It represents
+/// a minimal range abstraction (min, max, step). Since RangeType is constructed
+/// without any additional argument, this example illustrates the minimal
+/// amount of information required to implement a new custom MLIR type.
+class RangeType : public mlir::Type::TypeBase<RangeType, mlir::Type> {
+public:
+ // Used to implement llvm-style cast.
+ using Base::Base;
+ /// Construction hook.
+ static RangeType get(mlir::MLIRContext *context) {
+ /// Custom, uniqu'ed construction in the mlir::MLIRContext.
+ return Base::get(context, LinalgTypes::Range);
+ }
+ /// Used to implement llvm-style cast.
+ static bool kindof(unsigned kind) { return kind == LinalgTypes::Range; }
+};
+
+} // namespace linalg
+
+#endif // LINALG1_RANGETYPE_H_
diff --git a/include/linalg1/SliceOp.h b/include/linalg1/SliceOp.h
new file mode 100644
index 0000000..1d79784
--- /dev/null
+++ b/include/linalg1/SliceOp.h
@@ -0,0 +1,91 @@
+//===- SliceOp.h - Linalg dialect SliceOp operation definition ------------===//
+//
+// 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 LINALG1_SLICEOP_H_
+#define LINALG1_SLICEOP_H_
+
+#include "linalg1/Types.h"
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/Support/LLVM.h"
+
+namespace linalg {
+
+/// A SliceOp is used to create a "sub-View" from a ViewType. It results in a
+/// new ViewType which is contained within its parent ViewType.
+class SliceOp : public mlir::Op<SliceOp, mlir::OpTrait::NOperands<2>::Impl,
+ mlir::OpTrait::OneResult,
+ mlir::OpTrait::HasNoSideEffect> {
+public:
+ using Op::Op;
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Hooks to customize the behavior of this op.
+ //////////////////////////////////////////////////////////////////////////////
+ static llvm::StringRef getOperationName() { return "linalg.slice"; }
+ static void build(mlir::Builder *b, mlir::OperationState *result,
+ mlir::Value *view, mlir::Value *indexing, unsigned dim);
+ mlir::LogicalResult verify();
+ static bool parse(mlir::OpAsmParser *parser, mlir::OperationState *result);
+ void print(mlir::OpAsmPrinter *p);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Op-specific functionality.
+ //////////////////////////////////////////////////////////////////////////////
+ enum { FirstIndexingOperand = 1 };
+ /// Returns the attribute name that describes which dimension of the input
+ /// view that this SliceOp slices.
+ static llvm::StringRef getSlicingDimAttrName() { return "dim"; }
+ /// Returns the unique result of the parent SliceOp of ViewOp instruction that
+ /// created the view on which this SliceOp operates.
+ mlir::Value *getParentView() { return getOperand(0); }
+ /// Returns the indexing operand of the current SliceOp.
+ /// This operands may either be:
+ /// 1. A range, in which case the operand comes from a RangeOp. This SliceOp
+ /// does not reduce the dimension of the input ViewType.
+ /// 2. An index, in which case the operand comes from any possible producer
+ /// of an index. This SliceOp reduces the dimension of the input ViewType
+ /// by 1.
+ mlir::Value *getIndexing() { return getOperand(1); }
+ /// Returns the dim of the parent ViewType that is sliced by this SliceOp.
+ unsigned getSlicingDim() {
+ return getAttrOfType<mlir::IntegerAttr>(getSlicingDimAttrName()).getInt();
+ }
+ /// Returns the ViewType resulting from this SliceOp.
+ ViewType getViewType();
+ /// Returns the rank of the current ViewType.
+ unsigned getRank();
+ /// Return the element type of the current ViewType.
+ mlir::Type getElementType();
+
+ /// Returns the ViewType of `getParentView()`.
+ ViewType getParentViewType();
+ /// Returns the rank of the ViewType of `getParentView()`.
+ unsigned getParentRank();
+ /// Returns the element Type of the ViewType of `getParentView()`.
+ mlir::Type getParentElementType();
+
+ /// Returns true if the rank of the part view is greater than the rank of
+ /// the child view.
+ bool isRankDecreasing();
+
+ // Get all the indexings in this slice.
+ mlir::Operation::operand_range getIndexings();
+};
+
+} // namespace linalg
+
+#endif // LINALG1_SLICEOP_H_
diff --git a/include/linalg1/Types.h b/include/linalg1/Types.h
new file mode 100644
index 0000000..5032e96
--- /dev/null
+++ b/include/linalg1/Types.h
@@ -0,0 +1,36 @@
+//===- Types.h - Linalg Types forward declarations ------------------------===//
+//
+// 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 LINALG1_TYPES_H_
+#define LINALG1_TYPES_H_
+
+#include "mlir/IR/Types.h"
+
+namespace linalg {
+
+enum LinalgTypes {
+ Range = mlir::Type::FIRST_PRIVATE_EXPERIMENTAL_0_TYPE,
+ View,
+ FIRST_PRIVATE_EXPERIMENTAL_0_TYPE = View,
+};
+
+} // namespace linalg
+
+#include "linalg1/RangeType.h"
+#include "linalg1/ViewType.h"
+
+#endif // LINALG1_TYPES_H_
diff --git a/include/linalg1/Utils.h b/include/linalg1/Utils.h
new file mode 100644
index 0000000..3f7bb76
--- /dev/null
+++ b/include/linalg1/Utils.h
@@ -0,0 +1,37 @@
+//===- Utils.h - Linalg dialect utility functions definitions -------------===//
+//
+// 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 LINALG1_UTILS_H_
+#define LINALG1_UTILS_H_
+
+namespace mlir {
+class Value;
+} // namespace mlir
+
+namespace linalg {
+class ViewOp;
+
+/// Asserts `view` is of ViewType and returns its rank.
+unsigned getViewRank(mlir::Value *view);
+
+/// Helper function to emit and return a new ViewOp from `memRef` that is
+/// assumed to be of MemRefType. This needs to be called under a ScopedContext.
+ViewOp emitAndReturnViewOpFromMemRef(mlir::Value *memRef);
+
+} // namespace linalg
+
+#endif // LINALG1_UTILS_H_
diff --git a/include/linalg1/ViewOp.h b/include/linalg1/ViewOp.h
new file mode 100644
index 0000000..fcda553
--- /dev/null
+++ b/include/linalg1/ViewOp.h
@@ -0,0 +1,67 @@
+//===- ViewOp.h - Linalg dialect ViewOp operation definition ------------===//
+//
+// 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 LINALG1_VIEWOP_H_
+#define LINALG1_VIEWOP_H_
+
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/Support/LLVM.h"
+
+namespace linalg {
+
+class ViewType;
+
+/// A `ViewOp` produces a `ViewType` which is a multi-dimensional range
+/// abstraction on top of an underlying data type. For now we use the existing
+/// mlir::MemRef for the underlying data type.
+class ViewOp : public mlir::Op<ViewOp, mlir::OpTrait::VariadicOperands,
+ mlir::OpTrait::OneResult,
+ mlir::OpTrait::HasNoSideEffect> {
+public:
+ using Op::Op;
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Hooks to customize the behavior of this op.
+ //////////////////////////////////////////////////////////////////////////////
+ static llvm::StringRef getOperationName() { return "linalg.view"; }
+ static void build(mlir::Builder *b, mlir::OperationState *result,
+ mlir::Value *memRef,
+ llvm::ArrayRef<mlir::Value *> indexings);
+ mlir::LogicalResult verify();
+ static bool parse(mlir::OpAsmParser *parser, mlir::OperationState *result);
+ void print(mlir::OpAsmPrinter *p);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Op-specific functionality.
+ //////////////////////////////////////////////////////////////////////////////
+ enum { FirstIndexingOperand = 1 };
+ unsigned getRank();
+ mlir::Type getElementType();
+ ViewType getViewType();
+ // May be something else than a MemRef in the future.
+ mlir::Value *getSupportingMemRef();
+ // Get the underlying indexing at a given rank.
+ mlir::Value *getIndexing(unsigned rank);
+ // Get all the indexings of type RangeOp.
+ llvm::SmallVector<mlir::Value *, 8> getRanges();
+ // Get all the indexings in this view.
+ mlir::Operation::operand_range getIndexings();
+};
+
+} // namespace linalg
+
+#endif // LINALG1_VIEWOP_H_
diff --git a/include/linalg1/ViewType.h b/include/linalg1/ViewType.h
new file mode 100644
index 0000000..c58e12c
--- /dev/null
+++ b/include/linalg1/ViewType.h
@@ -0,0 +1,57 @@
+//===- ViewType.h - Linalg ViewType definition --------------------------===//
+//
+// 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 LINALG1_VIEWTYPE_H_
+#define LINALG1_VIEWTYPE_H_
+
+#include "linalg1/Types.h"
+#include "mlir/IR/Types.h"
+
+namespace linalg {
+
+class ViewTypeStorage;
+
+/// A ViewType represents a range abstraction on top of an underlying storage
+/// type. It is parameterizable by the underlying element type and the rank of
+/// the view.
+class ViewType
+ : public mlir::Type::TypeBase<ViewType, mlir::Type, ViewTypeStorage> {
+public:
+ //////////////////////////////////////////////////////////////////////////////
+ // Hooks to customize the behavior of this type.
+ //////////////////////////////////////////////////////////////////////////////
+ // Used to implement llvm-style cast.
+ using Base::Base;
+ // Used to implement llvm-style cast.
+ static bool kindof(unsigned kind) { return kind == LinalgTypes::View; }
+ /// Construction hook.
+ static ViewType get(mlir::MLIRContext *context, mlir::Type elementType,
+ unsigned rank);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Type-specific functionality.
+ //////////////////////////////////////////////////////////////////////////////
+ /// Return the underlying elemental type.
+ mlir::Type getElementType();
+ /// Return the rank of the view.
+ /// This is the number of indexings needed to reach an underlying element.
+ unsigned getRank();
+};
+
+} // namespace linalg
+
+#endif // LINALG1_VIEWTYPE_H_