Adding HAL dialect skeleton for executable lowering.
PiperOrigin-RevId: 282396945
diff --git a/iree/compiler/Dialect/HAL/IR/BUILD b/iree/compiler/Dialect/HAL/IR/BUILD
new file mode 100644
index 0000000..d8a1c30
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/IR/BUILD
@@ -0,0 +1,105 @@
+# Copyright 2019 Google LLC
+#
+# 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
+#
+# https://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.
+
+load("@local_config_mlir//:tblgen.bzl", "gentbl")
+
+package(
+ default_visibility = ["//visibility:public"],
+ licenses = ["notice"], # Apache 2.0
+)
+
+exports_files(["HALBase.td"])
+
+filegroup(
+ name = "td_files",
+ srcs = glob(["*.td"]),
+)
+
+cc_library(
+ name = "IR",
+ srcs = [
+ "HALDialect.cpp",
+ "HALEnums.cpp.inc",
+ "HALOpFolders.cpp",
+ "HALOpInterface.cpp.inc",
+ "HALOps.cpp",
+ "HALOps.cpp.inc",
+ "HALTypes.cpp",
+ ],
+ hdrs = [
+ "HALDialect.h",
+ "HALEnums.h.inc",
+ "HALOpInterface.h.inc",
+ "HALOps.h",
+ "HALOps.h.inc",
+ "HALTypes.h",
+ ],
+ deps = [
+ ":HALEnumsGen",
+ ":HALOpInterfaceGen",
+ ":HALOpsGen",
+ "//iree/compiler/Dialect",
+ "@llvm//:support",
+ "@local_config_mlir//:IR",
+ "@local_config_mlir//:StandardOps",
+ "@local_config_mlir//:Support",
+ "@local_config_mlir//:TransformUtils",
+ ],
+ alwayslink = 1,
+)
+
+gentbl(
+ name = "HALEnumsGen",
+ tbl_outs = [
+ ("-gen-enum-decls", "HALEnums.h.inc"),
+ ("-gen-enum-defs", "HALEnums.cpp.inc"),
+ ],
+ tblgen = "@local_config_mlir//:mlir-tblgen",
+ td_file = "HALBase.td",
+ td_srcs = [
+ ":td_files",
+ "//iree/compiler/Dialect:td_files",
+ "@local_config_mlir//:OpBaseTdFiles",
+ ],
+)
+
+gentbl(
+ name = "HALOpInterfaceGen",
+ tbl_outs = [
+ ("-gen-op-interface-decls", "HALOpInterface.h.inc"),
+ ("-gen-op-interface-defs", "HALOpInterface.cpp.inc"),
+ ],
+ tblgen = "@local_config_mlir//:mlir-tblgen",
+ td_file = "HALBase.td",
+ td_srcs = [
+ ":td_files",
+ "//iree/compiler/Dialect:td_files",
+ "@local_config_mlir//:OpBaseTdFiles",
+ ],
+)
+
+gentbl(
+ name = "HALOpsGen",
+ tbl_outs = [
+ ("-gen-op-decls", "HALOps.h.inc"),
+ ("-gen-op-defs", "HALOps.cpp.inc"),
+ ],
+ tblgen = "@local_config_mlir//:mlir-tblgen",
+ td_file = "HALOps.td",
+ td_srcs = [
+ ":td_files",
+ "//iree/compiler/Dialect:td_files",
+ "@local_config_mlir//:OpBaseTdFiles",
+ ],
+)
diff --git a/iree/compiler/Dialect/HAL/IR/HALBase.td b/iree/compiler/Dialect/HAL/IR/HALBase.td
new file mode 100644
index 0000000..003c09b
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/IR/HALBase.td
@@ -0,0 +1,213 @@
+// Copyright 2019 Google LLC
+//
+// 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
+//
+// https://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 IREE_DIALECT_HAL_BASE
+#define IREE_DIALECT_HAL_BASE
+
+include "iree/compiler/Dialect/CommonBase.td"
+
+//===----------------------------------------------------------------------===//
+// IREE HAL (Hardware Abstraction Layer) dialect
+//===----------------------------------------------------------------------===//
+
+def HAL_Dialect : Dialect {
+ let name = "hal";
+ let cppNamespace = "IREE::HAL";
+
+ let summary = [{
+ A dialect representing operations against the IREE HAL.
+ }];
+ let description = [{
+ This can be thought of as a Vulkan-like model with all of the graphics bits
+ chopped out.
+
+ The type set is limited to those that can be represented in the IREE HAL
+ design: buffers and views, synchronization primitives like semaphores, and
+ and command buffers. The intent is that if a device could implement the HAL
+ interface the sequencer ops could run on that device, such as being able to
+ run on a GPU via indirect command buffers.
+
+ Though this is mostly a 1:1 mapping to the iree::hal API there are some
+ methods omitted as they are not likely to be needed in IR. It's assumed that
+ either sequencer interfaces will encapsulate the logic (such as device
+ resolution) or that certain features are unsafe to expose to user-defined
+ input.
+ }];
+}
+
+//===----------------------------------------------------------------------===//
+// HAL types
+//===----------------------------------------------------------------------===//
+
+def HAL_Allocator : DialectType<
+ HAL_Dialect,
+ CPred<"$_self.isa<IREE::HAL::AllocatorType>()">,
+ "allocator"> {
+ let typeDescription = [{
+ Allocates buffers for a particular device memory space.
+ }];
+}
+
+def HAL_Buffer : DialectType<
+ HAL_Dialect,
+ CPred<"$_self.isa<IREE::HAL::BufferType>()">,
+ "buffer"> {
+ let typeDescription = [{
+ A memory buffer with a specific memory_type that is used to describe the
+ capabilities and behavior of the backing memory of the buffer. Buffers may
+ be any mix of host-accessible, host-coherent, or device-accessible for
+ various usages. Depending on these memory types the buffers may be mapped
+ for access on the host as memory though certain restrictions may be imposed.
+ }];
+}
+
+def HAL_CommandBuffer : DialectType<
+ HAL_Dialect,
+ CPred<"$_self.isa<IREE::HAL::CommandBufferType>()">,
+ "command_buffer"> {
+ let typeDescription = [{
+ Asynchronous command buffer recording interface. Commands are recorded by
+ the implementation for later submission to command queues.
+ }];
+}
+
+def HAL_Device : DialectType<
+ HAL_Dialect,
+ CPred<"$_self.isa<IREE::HAL::DeviceType>()">,
+ "device"> {
+ let typeDescription = [{
+ Logical device instance.
+ }];
+}
+
+def HAL_Event : DialectType<
+ HAL_Dialect,
+ CPred<"$_self.isa<IREE::HAL::EventType>()">,
+ "event"> {
+ let typeDescription = [{
+ Events are used for defining synchronization scopes within CommandBuffers.
+ An event only exists within a single CommandBuffer and must not be used
+ across CommandBuffers from the same device or others.
+ }];
+}
+def HAL_EventList : TupleOf<[RefPtrOf<HAL_Event>]>;
+
+def HAL_Executable : DialectType<
+ HAL_Dialect,
+ CPred<"$_self.isa<IREE::HAL::ExecutableType>()">,
+ "executable"> {
+ let typeDescription = [{
+ A prepared and ready-to-dispatch executable.
+ }];
+}
+
+def HAL_ExecutableCache : DialectType<
+ HAL_Dialect,
+ CPred<"$_self.isa<IREE::HAL::ExecutableCacheType>()">,
+ "executable_cache"> {
+ let typeDescription = [{
+ A cache of prepared executables for a particular device.
+ Caches may be shared across multiple devices from the same driver or
+ specific to individual devices. Caches may persist prepared executables
+ across process launches or reprepare them each run. Callers should assume
+ that the cache is a no-op and the returned Executables only live for as long
+ as the cache does.
+ }];
+}
+
+def HAL_Fence : DialectType<
+ HAL_Dialect,
+ CPred<"$_self.isa<IREE::HAL::FenceType>()">,
+ "fence"> {
+ let typeDescription = [{
+ Synchronization mechanism for device->host notification.
+ Fences behave like timeline semaphores and contain a monotonically
+ increasing uint64_t payload. They may be waited on any number of times -
+ even if they have already been signaled.
+ }];
+}
+
+def HAL_RingBuffer : DialectType<
+ HAL_Dialect,
+ CPred<"$_self.isa<IREE::HAL::RingBufferType>()">,
+ "ring_buffer"> {
+ let typeDescription = [{
+ Ringbuffer used for transient buffer allocation.
+ }];
+}
+
+def HAL_Semaphore : DialectType<
+ HAL_Dialect,
+ CPred<"$_self.isa<IREE::HAL::SemaphoreType>()">,
+ "semaphore"> {
+ let typeDescription = [{
+ A synchronization primitive used to indicate submission dependencies.
+ Semaphores are either of type binary (signaled or unsignaled) or timeline
+ (uint64_t payload with >= semantics).
+ }];
+}
+
+def HAL_OrdinalAttr : IntegerAttrBase<I32, "32-bit integer ordinal attribute">;
+
+def HAL_ExecutableFormatAttr : IntegerAttrBase<I32, "uint32_t">;
+def HAL_ExecutableDataAttr : IntElementsAttr<8>;
+
+def HAL_DeviceSize : TypeAlias<I32>;
+def HAL_DeviceSizeAttr : IntegerAttrBase<I32, "device_size_t">;
+
+def HAL_HostSize : TypeAlias<I32>;
+def HAL_HostSizeAttr : IntegerAttrBase<I32, "size_t">;
+
+def HAL_TimelineValue : TypeAlias<I32>;
+
+def HAL_Status : TypeAlias<I32>;
+
+def HAL_Dim : I<32>;
+def HAL_Dims : VectorOf<[HAL_Dim]>;
+def HAL_Shape : TypeAlias<HAL_Dims>;
+
+def HAL_Workload : VectorOfLengthAndType<[3], [I32]> {
+ let typeDescription = [{
+ An (X, Y, Z) invocation count describing the workload of an operation.
+ }];
+}
+
+def HAL_HostBufferRef : AnyTypeOf<[
+ RefPtrOf<ByteBufferType>,
+ RefPtrOf<MutableByteBufferType>,
+]>;
+
+//===----------------------------------------------------------------------===//
+// Base HAL op classes
+//===----------------------------------------------------------------------===//
+
+def HAL_OpInterface : OpInterface<"HALOp"> {
+ let description = [{
+ Interface for HAL ops.
+ }];
+}
+
+class HAL_Op<string mnemonic, list<OpTrait> traits = []> :
+ Op<HAL_Dialect, mnemonic, !listconcat(traits, [HAL_OpInterface])> {
+ let parser = [{ return parse$cppClass(parser, &result); }];
+ let printer = [{ return print$cppClass(p, *this); }];
+}
+
+class HAL_PureOp<string mnemonic, list<OpTrait> traits = []> :
+ HAL_Op<mnemonic, !listconcat(traits, [NoSideEffect])>;
+
+class HAL_MakeTupleOp<string mnemonic, list<OpTrait> traits = []> :
+ HAL_PureOp<mnemonic, traits>;
+
+#endif // IREE_DIALECT_HAL_BASE
diff --git a/iree/compiler/Dialect/HAL/IR/HALDialect.cpp b/iree/compiler/Dialect/HAL/IR/HALDialect.cpp
new file mode 100644
index 0000000..620924b
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/IR/HALDialect.cpp
@@ -0,0 +1,100 @@
+// Copyright 2019 Google LLC
+//
+// 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
+//
+// https://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.
+
+#include "iree/compiler/Dialect/HAL/IR/HALDialect.h"
+
+#include "iree/compiler/Dialect/HAL/IR/HALOps.h"
+#include "iree/compiler/Dialect/HAL/IR/HALTypes.h"
+#include "mlir/IR/DialectImplementation.h"
+#include "mlir/IR/OpImplementation.h"
+#include "third_party/llvm/llvm/include/llvm/Support/SourceMgr.h"
+
+namespace mlir {
+namespace iree_compiler {
+namespace IREE {
+namespace HAL {
+
+#include "iree/compiler/Dialect/HAL/IR/HALOpInterface.cpp.inc"
+
+static DialectRegistration<HALDialect> hal_dialect;
+
+HALDialect::HALDialect(MLIRContext *context)
+ : Dialect(getDialectNamespace(), context) {
+ addTypes<AllocatorType, BufferType, CommandBufferType, DeviceType, EventType,
+ ExecutableType, ExecutableCacheType, FenceType, RingBufferType,
+ SemaphoreType>();
+
+#define GET_OP_LIST
+ addOperations<
+#include "iree/compiler/Dialect/HAL/IR/HALOps.cpp.inc"
+ >();
+}
+
+//===----------------------------------------------------------------------===//
+// Type printing and parsing
+//===----------------------------------------------------------------------===//
+
+Type HALDialect::parseType(DialectAsmParser &parser) const {
+ StringRef typeName;
+ if (parser.parseKeyword(&typeName)) return Type();
+ auto type =
+ llvm::StringSwitch<Type>(typeName)
+ .Case("allocator", AllocatorType::get(getContext()))
+ .Case("buffer", BufferType::get(getContext()))
+ .Case("command_buffer", CommandBufferType::get(getContext()))
+ .Case("device", DeviceType::get(getContext()))
+ .Case("event", EventType::get(getContext()))
+ .Case("executable", ExecutableType::get(getContext()))
+ .Case("executable_cache", ExecutableCacheType::get(getContext()))
+ .Case("fence", FenceType::get(getContext()))
+ .Case("ring_buffer", RingBufferType::get(getContext()))
+ .Case("semaphore", SemaphoreType::get(getContext()))
+ .Default(nullptr);
+ if (!type) {
+ parser.emitError(parser.getCurrentLocation())
+ << "unknown HAL type: " << typeName;
+ }
+ return type;
+}
+
+void HALDialect::printType(Type type, DialectAsmPrinter &p) const {
+ if (type.isa<AllocatorType>()) {
+ p << "allocator";
+ } else if (type.isa<BufferType>()) {
+ p << "buffer";
+ } else if (type.isa<CommandBufferType>()) {
+ p << "command_buffer";
+ } else if (type.isa<DeviceType>()) {
+ p << "device";
+ } else if (type.isa<EventType>()) {
+ p << "event";
+ } else if (type.isa<ExecutableType>()) {
+ p << "executable";
+ } else if (type.isa<ExecutableCacheType>()) {
+ p << "executable_cache";
+ } else if (type.isa<FenceType>()) {
+ p << "fence";
+ } else if (type.isa<RingBufferType>()) {
+ p << "ring_buffer";
+ } else if (type.isa<SemaphoreType>()) {
+ p << "semaphore";
+ } else {
+ llvm_unreachable("unknown HAL type");
+ }
+}
+
+} // namespace HAL
+} // namespace IREE
+} // namespace iree_compiler
+} // namespace mlir
diff --git a/iree/compiler/Dialect/HAL/IR/HALDialect.h b/iree/compiler/Dialect/HAL/IR/HALDialect.h
new file mode 100644
index 0000000..dc30a49
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/IR/HALDialect.h
@@ -0,0 +1,42 @@
+// Copyright 2019 Google LLC
+//
+// 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
+//
+// https://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 IREE_COMPILER_DIALECT_HAL_IR_HALDIALECT_H_
+#define IREE_COMPILER_DIALECT_HAL_IR_HALDIALECT_H_
+
+#include "mlir/IR/Dialect.h"
+#include "mlir/IR/OpDefinition.h"
+
+namespace mlir {
+namespace iree_compiler {
+namespace IREE {
+namespace HAL {
+
+#include "iree/compiler/Dialect/HAL/IR/HALOpInterface.h.inc"
+
+class HALDialect : public Dialect {
+ public:
+ explicit HALDialect(MLIRContext *context);
+ static StringRef getDialectNamespace() { return "hal"; }
+
+ Type parseType(DialectAsmParser &parser) const override;
+ void printType(Type type, DialectAsmPrinter &p) const override;
+};
+
+} // namespace HAL
+} // namespace IREE
+} // namespace iree_compiler
+} // namespace mlir
+
+#endif // IREE_COMPILER_DIALECT_HAL_IR_HALDIALECT_H_
diff --git a/iree/compiler/Dialect/HAL/IR/HALOpFolders.cpp b/iree/compiler/Dialect/HAL/IR/HALOpFolders.cpp
new file mode 100644
index 0000000..bb34005
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/IR/HALOpFolders.cpp
@@ -0,0 +1,37 @@
+// Copyright 2019 Google LLC
+//
+// 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
+//
+// https://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.
+
+#include "iree/compiler/Dialect/HAL/IR/HALDialect.h"
+#include "iree/compiler/Dialect/HAL/IR/HALOps.h"
+#include "llvm/ADT/StringExtras.h"
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/Matchers.h"
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/IR/OpImplementation.h"
+#include "mlir/IR/PatternMatch.h"
+#include "mlir/IR/SymbolTable.h"
+#include "mlir/Support/LogicalResult.h"
+
+namespace mlir {
+namespace iree_compiler {
+namespace IREE {
+namespace HAL {
+
+// TODO(benvanik): folders.
+
+} // namespace HAL
+} // namespace IREE
+} // namespace iree_compiler
+} // namespace mlir
diff --git a/iree/compiler/Dialect/HAL/IR/HALOps.cpp b/iree/compiler/Dialect/HAL/IR/HALOps.cpp
new file mode 100644
index 0000000..84d26cc
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/IR/HALOps.cpp
@@ -0,0 +1,147 @@
+// Copyright 2019 Google LLC
+//
+// 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
+//
+// https://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.
+
+#include "iree/compiler/Dialect/HAL/IR/HALOps.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/OpImplementation.h"
+#include "mlir/IR/SymbolTable.h"
+
+namespace mlir {
+namespace iree_compiler {
+namespace IREE {
+namespace HAL {
+
+//===----------------------------------------------------------------------===//
+// hal.executable
+//===----------------------------------------------------------------------===//
+
+void ExecutableOp::build(Builder *builder, OperationState &state,
+ StringRef name) {
+ ensureTerminator(*state.addRegion(), *builder, state.location);
+ state.addAttribute(mlir::SymbolTable::getSymbolAttrName(),
+ builder->getStringAttr(name));
+}
+
+static ParseResult parseExecutableOp(OpAsmParser &parser,
+ OperationState *result) {
+ StringAttr nameAttr;
+ if (failed(parser.parseSymbolName(nameAttr,
+ mlir::SymbolTable::getSymbolAttrName(),
+ result->attributes)) ||
+ failed(parser.parseOptionalAttrDictWithKeyword(result->attributes))) {
+ return failure();
+ }
+
+ // Parse the module body.
+ auto *body = result->addRegion();
+ if (failed(parser.parseRegion(*body, llvm::None, llvm::None))) {
+ return failure();
+ }
+
+ // Ensure that this module has a valid terminator.
+ ExecutableOp::ensureTerminator(*body, parser.getBuilder(), result->location);
+ return success();
+}
+
+static void printExecutableOp(OpAsmPrinter &p, ExecutableOp op) {
+ p << op.getOperationName() << ' ';
+ p.printSymbolName(op.sym_name());
+ p.printOptionalAttrDictWithKeyword(
+ op.getAttrs(),
+ /*elidedAttrs=*/{mlir::SymbolTable::getSymbolAttrName()});
+ p.printRegion(op.body(), /*printEntryBlockArgs=*/false,
+ /*printBlockTerminators=*/false);
+}
+
+static LogicalResult verifyExecutableOp(ExecutableOp op) {
+ // TODO(benvanik): check export name conflicts.
+ return success();
+}
+
+static ParseResult parseRegionEndOp(OpAsmParser &parser,
+ OperationState *result) {
+ return parser.parseOptionalAttrDict(result->attributes);
+}
+
+static void printRegionEndOp(OpAsmPrinter &p, Operation *op) {
+ p << op->getName();
+ p.printOptionalAttrDict(op->getAttrs());
+}
+
+//===----------------------------------------------------------------------===//
+// hal.executable.binary
+//===----------------------------------------------------------------------===//
+
+void ExecutableBinaryOp::build(Builder *builder, OperationState &state,
+ uint32_t format, std::vector<uint8_t> data) {
+ ensureTerminator(*state.addRegion(), *builder, state.location);
+ state.addAttribute(
+ "format", builder->getIntegerAttr(builder->getIntegerType(32), format));
+ state.addAttribute("data",
+ DenseIntElementsAttr::get(
+ VectorType::get({static_cast<int64_t>(data.size())},
+ builder->getIntegerType(8)),
+ data));
+}
+
+static ParseResult parseExecutableBinaryOp(OpAsmParser &parser,
+ OperationState *result) {
+ auto *body = result->addRegion();
+ if (failed(parser.parseOptionalAttrDictWithKeyword(result->attributes)) ||
+ failed(parser.parseOptionalRegion(*body, llvm::None, llvm::None))) {
+ return failure();
+ }
+
+ // Ensure that this module has a valid terminator.
+ ExecutableBinaryOp::ensureTerminator(*body, parser.getBuilder(),
+ result->location);
+ return success();
+}
+
+static void printExecutableBinaryOp(OpAsmPrinter &p, ExecutableBinaryOp op) {
+ p << op.getOperationName();
+ p.printOptionalAttrDictWithKeyword(
+ op.getAttrs(),
+ /*elidedAttrs=*/{mlir::SymbolTable::getSymbolAttrName()});
+ if (!op.body().empty()) {
+ p.printRegion(op.body(), /*printEntryBlockArgs=*/false,
+ /*printBlockTerminators=*/false);
+ }
+}
+
+static LogicalResult verifyExecutableBinaryOp(ExecutableBinaryOp op) {
+ // Zero or one ModuleOps allowed.
+ if (std::distance(op.getBlock().getOps<ModuleOp>().begin(),
+ op.getBlock().getOps<ModuleOp>().end()) > 1) {
+ return op.emitOpError() << "expects zero or one nested std.module ops";
+ }
+
+ // TODO(benvanik): check export name conflicts.
+ return success();
+}
+
+//===----------------------------------------------------------------------===//
+// TableGen definitions (intentionally last)
+//===----------------------------------------------------------------------===//
+
+#define GET_OP_CLASSES
+#include "iree/compiler/Dialect/HAL/IR/HALOps.cpp.inc"
+
+} // namespace HAL
+} // namespace IREE
+} // namespace iree_compiler
+} // namespace mlir
diff --git a/iree/compiler/Dialect/HAL/IR/HALOps.h b/iree/compiler/Dialect/HAL/IR/HALOps.h
new file mode 100644
index 0000000..cb81be5
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/IR/HALOps.h
@@ -0,0 +1,43 @@
+// Copyright 2019 Google LLC
+//
+// 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
+//
+// https://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 IREE_COMPILER_DIALECT_HAL_IR_HALOPS_H_
+#define IREE_COMPILER_DIALECT_HAL_IR_HALOPS_H_
+
+#include <cstdint>
+
+#include "iree/compiler/Dialect/HAL/IR/HALDialect.h"
+#include "iree/compiler/Dialect/HAL/IR/HALTypes.h"
+#include "iree/compiler/Dialect/Traits.h"
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/Dialect.h"
+#include "mlir/IR/Module.h"
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/IR/StandardTypes.h"
+#include "mlir/IR/SymbolTable.h"
+
+namespace mlir {
+namespace iree_compiler {
+namespace IREE {
+namespace HAL {
+
+#define GET_OP_CLASSES
+#include "iree/compiler/Dialect/HAL/IR/HALOps.h.inc"
+
+} // namespace HAL
+} // namespace IREE
+} // namespace iree_compiler
+} // namespace mlir
+
+#endif // IREE_COMPILER_DIALECT_HAL_IR_HALOPS_H_
diff --git a/iree/compiler/Dialect/HAL/IR/HALOps.td b/iree/compiler/Dialect/HAL/IR/HALOps.td
new file mode 100644
index 0000000..38c4ec9
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/IR/HALOps.td
@@ -0,0 +1,118 @@
+// Copyright 2019 Google LLC
+//
+// 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
+//
+// https://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 IREE_DIALECT_HAL_OPS
+#define IREE_DIALECT_HAL_OPS
+
+include "iree/compiler/Dialect/HAL/IR/HALBase.td"
+
+//===----------------------------------------------------------------------===//
+// iree::hal::Executable
+//===----------------------------------------------------------------------===//
+
+// TODO(benvanik): executable runtime type.
+
+def HAL_ExecutableOp : HAL_Op<"executable", [
+ IsolatedFromAbove,
+ SingleBlockImplicitTerminator<"IREE::HAL::ExecutableEndOp">,
+ Symbol,
+ ]> {
+ let summary = [{target-specific executable module}];
+ let description = [{
+ An executable module representing a target-specific compiled
+ kernel/shader/etc.
+ }];
+
+ let arguments = (ins
+ StrAttr:$sym_name
+ // TODO(benvanik): entry point types for verification.
+ );
+
+ let regions = (region SizedRegion<1>:$body);
+
+ let skipDefaultBuilders = 1;
+ let builders = [
+ OpBuilder<[{
+ Builder *builder, OperationState &state, StringRef name
+ }]>,
+ ];
+
+ let extraClassDeclaration = [{
+ Block& getBlock() { return body().front(); }
+ }];
+
+ let verifier = [{ return verifyExecutableOp(*this); }];
+}
+
+def HAL_ExecutableEndOp : HAL_Op<"executable_end", [
+ HasParent<"IREE::HAL::ExecutableOp">,
+ Terminator,
+ ]> {
+ let summary = [{terminator pseudo-op for the executable op}];
+ let parser = [{ return parseRegionEndOp(parser, &result); }];
+ let printer = [{ return printRegionEndOp(p, *this); }];
+}
+
+// TODO(benvanik): add HAL_ExecutableSourceOp for auto serialization.
+
+def HAL_ExecutableBinaryOp : HAL_Op<"executable.binary", [
+ IsolatedFromAbove,
+ HasParent<"IREE::HAL::ExecutableOp">,
+ SingleBlockImplicitTerminator<"IREE::HAL::ExecutableBinaryEndOp">,
+ ]> {
+ let summary = [{compiled executable binary data}];
+ let description = [{
+ A compiled executable binary with an optional nested module containing the
+ IR prior to serialization (for debugging).
+ }];
+
+ let arguments = (ins
+ HAL_ExecutableFormatAttr:$format,
+ HAL_ExecutableDataAttr:$data
+ // TODO(benvanik): add compatibility and versioning attributes.
+ );
+
+ let regions = (region SizedRegion<1>:$body);
+
+ let skipDefaultBuilders = 1;
+ let builders = [
+ OpBuilder<[{
+ Builder *builder, OperationState &state, uint32_t format,
+ std::vector<uint8_t> data
+ }]>,
+ ];
+
+ let extraClassDeclaration = [{
+ Block& getBlock() { return body().front(); }
+
+ llvm::Optional<::mlir::ModuleOp> getInnerModule() {
+ auto moduleOps = getBlock().getOps<::mlir::ModuleOp>();
+ if (moduleOps.empty()) return llvm::None;
+ return *moduleOps.begin();
+ }
+ }];
+
+ let verifier = [{ return verifyExecutableBinaryOp(*this); }];
+}
+
+def HAL_ExecutableBinaryEndOp : HAL_Op<"executable.binary_end", [
+ HasParent<"IREE::HAL::ExecutableBinaryOp">,
+ Terminator,
+ ]> {
+ let summary = [{terminator pseudo-op for the executable binary op}];
+ let parser = [{ return parseRegionEndOp(parser, &result); }];
+ let printer = [{ return printRegionEndOp(p, *this); }];
+}
+
+#endif // IREE_DIALECT_HAL_OPS
diff --git a/iree/compiler/Dialect/HAL/IR/HALTypes.cpp b/iree/compiler/Dialect/HAL/IR/HALTypes.cpp
new file mode 100644
index 0000000..daa2021
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/IR/HALTypes.cpp
@@ -0,0 +1,32 @@
+// Copyright 2019 Google LLC
+//
+// 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
+//
+// https://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.
+
+#include "iree/compiler/Dialect/HAL/IR/HALTypes.h"
+
+#include "third_party/llvm/llvm/include/llvm/ADT/StringExtras.h"
+
+// Order matters:
+#include "iree/compiler/Dialect/HAL/IR/HALEnums.cpp.inc"
+
+namespace mlir {
+namespace iree_compiler {
+namespace IREE {
+namespace HAL {
+
+// TODO(benvanik): struct types.
+
+} // namespace HAL
+} // namespace IREE
+} // namespace iree_compiler
+} // namespace mlir
diff --git a/iree/compiler/Dialect/HAL/IR/HALTypes.h b/iree/compiler/Dialect/HAL/IR/HALTypes.h
new file mode 100644
index 0000000..d7639d8
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/IR/HALTypes.h
@@ -0,0 +1,135 @@
+// Copyright 2019 Google LLC
+//
+// 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
+//
+// https://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 IREE_COMPILER_DIALECT_HAL_IR_HALTYPES_H_
+#define IREE_COMPILER_DIALECT_HAL_IR_HALTYPES_H_
+
+#include <cstdint>
+
+#include "iree/compiler/Dialect/Types.h"
+#include "mlir/IR/TypeSupport.h"
+#include "mlir/IR/Types.h"
+#include "mlir/Support/LLVM.h"
+#include "third_party/llvm/llvm/include/llvm/ADT/DenseMap.h"
+#include "third_party/llvm/llvm/include/llvm/ADT/DenseMapInfo.h"
+#include "third_party/llvm/llvm/include/llvm/ADT/Optional.h"
+#include "third_party/llvm/llvm/include/llvm/ADT/SmallVector.h"
+#include "third_party/llvm/llvm/include/llvm/ADT/StringSwitch.h"
+
+// Order matters.
+#include "iree/compiler/Dialect/HAL/IR/HALEnums.h.inc"
+
+namespace mlir {
+namespace iree_compiler {
+namespace IREE {
+namespace HAL {
+
+class AllocatorType : public Type::TypeBase<AllocatorType, Type> {
+ public:
+ using Base::Base;
+ static AllocatorType get(MLIRContext *context) {
+ return Base::get(context, TypeKind::Allocator);
+ }
+ static bool kindof(unsigned kind) { return kind == TypeKind::Allocator; }
+};
+
+class BufferType : public Type::TypeBase<BufferType, Type> {
+ public:
+ using Base::Base;
+ static BufferType get(MLIRContext *context) {
+ return Base::get(context, TypeKind::Buffer);
+ }
+ static bool kindof(unsigned kind) { return kind == TypeKind::Buffer; }
+};
+
+class CommandBufferType : public Type::TypeBase<CommandBufferType, Type> {
+ public:
+ using Base::Base;
+ static CommandBufferType get(MLIRContext *context) {
+ return Base::get(context, TypeKind::CommandBuffer);
+ }
+ static bool kindof(unsigned kind) { return kind == TypeKind::CommandBuffer; }
+};
+
+class DeviceType : public Type::TypeBase<DeviceType, Type> {
+ public:
+ using Base::Base;
+ static DeviceType get(MLIRContext *context) {
+ return Base::get(context, TypeKind::Device);
+ }
+ static bool kindof(unsigned kind) { return kind == TypeKind::Device; }
+};
+
+class EventType : public Type::TypeBase<EventType, Type> {
+ public:
+ using Base::Base;
+ static EventType get(MLIRContext *context) {
+ return Base::get(context, TypeKind::Event);
+ }
+ static bool kindof(unsigned kind) { return kind == TypeKind::Event; }
+};
+
+class ExecutableType : public Type::TypeBase<ExecutableType, Type> {
+ public:
+ using Base::Base;
+ static ExecutableType get(MLIRContext *context) {
+ return Base::get(context, TypeKind::Executable);
+ }
+ static bool kindof(unsigned kind) { return kind == TypeKind::Executable; }
+};
+
+class ExecutableCacheType : public Type::TypeBase<ExecutableCacheType, Type> {
+ public:
+ using Base::Base;
+ static ExecutableCacheType get(MLIRContext *context) {
+ return Base::get(context, TypeKind::ExecutableCache);
+ }
+ static bool kindof(unsigned kind) {
+ return kind == TypeKind::ExecutableCache;
+ }
+};
+
+class FenceType : public Type::TypeBase<FenceType, Type> {
+ public:
+ using Base::Base;
+ static FenceType get(MLIRContext *context) {
+ return Base::get(context, TypeKind::Fence);
+ }
+ static bool kindof(unsigned kind) { return kind == TypeKind::Fence; }
+};
+
+class RingBufferType : public Type::TypeBase<RingBufferType, Type> {
+ public:
+ using Base::Base;
+ static RingBufferType get(MLIRContext *context) {
+ return Base::get(context, TypeKind::RingBuffer);
+ }
+ static bool kindof(unsigned kind) { return kind == TypeKind::RingBuffer; }
+};
+
+class SemaphoreType : public Type::TypeBase<SemaphoreType, Type> {
+ public:
+ using Base::Base;
+ static SemaphoreType get(MLIRContext *context) {
+ return Base::get(context, TypeKind::Semaphore);
+ }
+ static bool kindof(unsigned kind) { return kind == TypeKind::Semaphore; }
+};
+
+} // namespace HAL
+} // namespace IREE
+} // namespace iree_compiler
+} // namespace mlir
+
+#endif // IREE_COMPILER_DIALECT_HAL_IR_HALTYPES_H_
diff --git a/iree/compiler/Dialect/HAL/IR/test/BUILD b/iree/compiler/Dialect/HAL/IR/test/BUILD
new file mode 100644
index 0000000..beab62e
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/IR/test/BUILD
@@ -0,0 +1,28 @@
+# Copyright 2019 Google LLC
+#
+# 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
+#
+# https://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.
+
+load("//iree:build_defs.bzl", "iree_glob_lit_tests", "iree_setup_lit_package")
+
+package(
+ default_visibility = ["//visibility:public"],
+ licenses = ["notice"], # Apache 2.0
+)
+
+iree_setup_lit_package(
+ data = [
+ "//iree/tools:iree-opt",
+ ],
+)
+
+iree_glob_lit_tests()
diff --git a/iree/compiler/Dialect/HAL/IR/test/executable_ops.mlir b/iree/compiler/Dialect/HAL/IR/test/executable_ops.mlir
new file mode 100644
index 0000000..1782ea0
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/IR/test/executable_ops.mlir
@@ -0,0 +1,57 @@
+// Copyright 2019 Google LLC
+//
+// 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
+//
+// https://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.
+
+// Tests printing and parsing of executable/structural ops.
+
+// RUN: iree-opt -split-input-file %s | iree-opt | FileCheck %s --dump-input=fail
+
+// CHECK-LABEL: @ex
+hal.executable @ex {
+ // CHECK-NEXT: hal.executable.binary
+ hal.executable.binary attributes {
+ // CHECK-SAME: data = dense<1> : vector<128xi8>,
+ data = dense<1> : vector<128xi8>,
+ // CHECK-SAME: format = 1230128453 : i32
+ format = 1230128453 : i32
+ }
+}
+
+// -----
+
+// CHECK-LABEL: @ex_with_source
+hal.executable @ex_with_source {
+ // CHECK-NEXT: hal.executable.binary
+ hal.executable.binary attributes {
+ // CHECK-SAME: data = dense<1> : vector<128xi8>,
+ data = dense<1> : vector<128xi8>,
+ // CHECK-SAME: format = 1230128453 : i32
+ format = 1230128453 : i32
+ } {
+ // CHECK-NEXT: module {
+ module {
+ // CHECK-NEXT: func @dispatch0
+ func @dispatch0(%arg0: memref<4xf32>, %arg1: memref<4xf32>) attributes {
+ iree.executable.export,
+ iree.executable.workload = dense<[4, 1, 1]> : tensor<3xi32>,
+ iree.ordinal = 0 : i32} {
+ %0 = "iree_ll_interp.alloc_heap"() : () -> memref<4xf32>
+ "iree_ll_interp.add_f"(%arg0, %arg0, %0) : (memref<4xf32>, memref<4xf32>, memref<4xf32>) -> ()
+ %1 = "iree_ll_interp.constant"() {value = dense<0> : tensor<1xi64>} : () -> memref<1xi64>
+ %2 = "iree_ll_interp.constant"() {value = dense<4> : tensor<1xi64>} : () -> memref<1xi64>
+ "iree_ll_interp.dynamic_copy"(%0, %1, %arg1, %1, %2) : (memref<4xf32>, memref<1xi64>, memref<4xf32>, memref<1xi64>, memref<1xi64>) -> ()
+ iree.return
+ }
+ }
+ }
+}
diff --git a/iree/compiler/Dialect/Types.h b/iree/compiler/Dialect/Types.h
index 7e88bb0..bd9ab40 100644
--- a/iree/compiler/Dialect/Types.h
+++ b/iree/compiler/Dialect/Types.h
@@ -49,6 +49,7 @@
Executable,
ExecutableCache,
Fence,
+ RingBuffer,
Semaphore,
};
} // namespace TypeKind
@@ -77,12 +78,15 @@
case IREE::TypeKind::OpaqueRefObject:
case IREE::TypeKind::ByteBuffer:
case IREE::TypeKind::MutableByteBuffer:
+ case HAL::TypeKind::Allocator:
case HAL::TypeKind::Buffer:
case HAL::TypeKind::CommandBuffer:
case HAL::TypeKind::Device:
case HAL::TypeKind::Event:
case HAL::TypeKind::Executable:
+ case HAL::TypeKind::ExecutableCache:
case HAL::TypeKind::Fence:
+ case HAL::TypeKind::RingBuffer:
case HAL::TypeKind::Semaphore:
case SEQ::TypeKind::Device:
case SEQ::TypeKind::Policy:
diff --git a/iree/tools/BUILD b/iree/tools/BUILD
index 8e12641..abf8e11 100644
--- a/iree/tools/BUILD
+++ b/iree/tools/BUILD
@@ -35,6 +35,7 @@
"//iree/compiler/Dialect/Flow/Analysis",
"//iree/compiler/Dialect/Flow/IR",
"//iree/compiler/Dialect/Flow/Transforms",
+ "//iree/compiler/Dialect/HAL/IR",
"//iree/compiler/Dialect/VM/Analysis",
"//iree/compiler/Dialect/VM/Conversion/StandardToVM",
"//iree/compiler/Dialect/VM/IR",