Adding a skeleton for a HAL backend for JITing serialized LLVMIR executables.
PiperOrigin-RevId: 293898800
diff --git a/iree/hal/llvmjit/BUILD b/iree/hal/llvmjit/BUILD
new file mode 100644
index 0000000..a82ce91
--- /dev/null
+++ b/iree/hal/llvmjit/BUILD
@@ -0,0 +1,108 @@
+# Copyright 2020 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.
+
+# HAL implementation for jitting CPU code from LLVMIR.
+
+package(
+ default_visibility = ["//visibility:public"],
+ licenses = ["notice"], # Apache 2.0
+)
+
+cc_library(
+ name = "llvmjit_executable",
+ srcs = ["llvmjit_executable.cc"],
+ hdrs = ["llvmjit_executable.h"],
+ deps = [
+ "//iree/base:status",
+ "//iree/hal:allocator",
+ "//iree/hal:executable",
+ "//iree/hal:executable_spec",
+ "@com_google_absl//absl/types:span",
+ ],
+)
+
+cc_library(
+ name = "llvmjit_command_processor",
+ srcs = ["llvmjit_command_processor.cc"],
+ hdrs = ["llvmjit_command_processor.h"],
+ deps = [
+ ":llvmjit_executable",
+ "//iree/base:tracing",
+ "//iree/hal/host:host_local_command_processor",
+ ],
+)
+
+cc_library(
+ name = "llvmjit_executable_cache",
+ srcs = ["llvmjit_executable_cache.cc"],
+ hdrs = ["llvmjit_executable_cache.h"],
+ deps = [
+ ":llvmjit_executable",
+ "//iree/base:source_location",
+ "//iree/base:status",
+ "//iree/base:tracing",
+ "//iree/hal:allocator",
+ "//iree/hal:executable",
+ "//iree/hal:executable_cache",
+ "//iree/hal:executable_format",
+ ],
+)
+
+cc_library(
+ name = "llvmjit_device",
+ srcs = ["llvmjit_device.cc"],
+ hdrs = ["llvmjit_device.h"],
+ deps = [
+ ":llvmjit_command_processor",
+ ":llvmjit_executable_cache",
+ "//iree/base:memory",
+ "//iree/base:status",
+ "//iree/base:tracing",
+ "//iree/hal:command_buffer_validation",
+ "//iree/hal:command_queue",
+ "//iree/hal:device",
+ "//iree/hal:fence",
+ "//iree/hal/host:async_command_queue",
+ "//iree/hal/host:host_event",
+ "//iree/hal/host:host_local_allocator",
+ "//iree/hal/host:host_submission_queue",
+ "//iree/hal/host:inproc_command_buffer",
+ "@com_google_absl//absl/container:inlined_vector",
+ "@com_google_absl//absl/memory",
+ "@com_google_absl//absl/types:span",
+ ],
+)
+
+cc_library(
+ name = "llvmjit_driver",
+ srcs = ["llvmjit_driver.cc"],
+ hdrs = ["llvmjit_driver.h"],
+ deps = [
+ ":llvmjit_device",
+ "//iree/hal:device_info",
+ "//iree/hal:driver",
+ ],
+)
+
+cc_library(
+ name = "llvmjit_driver_module",
+ srcs = ["llvmjit_driver_module.cc"],
+ deps = [
+ ":llvmjit_driver",
+ "//iree/base:init",
+ "//iree/base:status",
+ "//iree/hal:driver_registry",
+ ],
+ alwayslink = 1,
+)
diff --git a/iree/hal/llvmjit/CMakeLists.txt b/iree/hal/llvmjit/CMakeLists.txt
new file mode 100644
index 0000000..81f36ee
--- /dev/null
+++ b/iree/hal/llvmjit/CMakeLists.txt
@@ -0,0 +1,158 @@
+# Copyright 2020 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.
+
+iree_cc_library(
+ NAME
+ llvmjit_executable_cache
+ HDRS
+ "llvmjit_executable_cache.h"
+ SRCS
+ "llvmjit_executable_cache.cc"
+ DEPS
+ ::llvmjit_executable
+ iree::base::source_location
+ iree::base::status
+ iree::base::tracing
+ iree::hal::allocator
+ iree::hal::executable
+ iree::hal::executable_cache
+ iree::hal::executable_format
+ iree::vm::instance
+ iree::vm::module
+ PUBLIC
+)
+
+iree_cc_library(
+ NAME
+ llvmjit_command_processor
+ HDRS
+ "llvmjit_command_processor.h"
+ SRCS
+ "llvmjit_command_processor.cc"
+ DEPS
+ ::llvmjit_executable
+ iree::base::api_util
+ iree::base::status
+ iree::base::tracing
+ iree::hal::host::host_local_command_processor
+ iree::vm::invocation
+ iree::vm::variant_list
+ PUBLIC
+)
+
+iree_cc_library(
+ NAME
+ llvmjit_device
+ HDRS
+ "llvmjit_device.h"
+ SRCS
+ "llvmjit_device.cc"
+ DEPS
+ ::llvmjit_executable_cache
+ ::llvmjit_command_processor
+ iree::base::memory
+ iree::base::status
+ iree::base::tracing
+ iree::hal::command_buffer_validation
+ iree::hal::command_queue
+ iree::hal::device
+ iree::hal::fence
+ iree::hal::host::async_command_queue
+ iree::hal::host::host_event
+ iree::hal::host::host_local_allocator
+ iree::hal::host::host_submission_queue
+ iree::hal::host::inproc_command_buffer
+ iree::vm::instance
+ iree::vm::module
+ absl::inlined_vector
+ absl::memory
+ absl::span
+ PUBLIC
+)
+
+iree_cc_library(
+ NAME
+ llvmjit_driver
+ HDRS
+ "llvmjit_driver.h"
+ SRCS
+ "llvmjit_driver.cc"
+ DEPS
+ ::llvmjit_device
+ ::llvmjit_module
+ iree::base::api_util
+ iree::base::tracing
+ iree::hal::device_info
+ iree::hal::driver
+ iree::vm::instance
+ iree::vm::module
+ PUBLIC
+)
+
+iree_cc_library(
+ NAME
+ llvmjit_driver_module
+ SRCS
+ "llvmjit_driver_module.cc"
+ DEPS
+ ::llvmjit_driver
+ iree::base::init
+ iree::base::status
+ iree::hal::driver_registry
+ ALWAYSLINK
+ PUBLIC
+)
+
+iree_cc_library(
+ NAME
+ llvmjit_executable
+ HDRS
+ "llvmjit_executable.h"
+ SRCS
+ "llvmjit_executable.cc"
+ DEPS
+ iree::base::api_util
+ iree::base::status
+ iree::base::tracing
+ iree::hal::allocator
+ iree::hal::executable
+ iree::hal::executable_spec
+ iree::vm::bytecode_module
+ iree::vm::context
+ iree::vm::instance
+ iree::vm::module
+ absl::inlined_vector
+ absl::span
+ PUBLIC
+)
+
+iree_cc_library(
+ NAME
+ llvmjit_module
+ HDRS
+ "llvmjit_module.h"
+ SRCS
+ "llvmjit_module.cc"
+ DEPS
+ ::op_kernels
+ iree::base::api
+ iree::base::memory
+ iree::base::ref_ptr
+ iree::base::tracing
+ iree::vm
+ iree::vm::module_abi_cc
+ iree::vm::types
+ absl::span
+ PUBLIC
+)
diff --git a/iree/hal/llvmjit/llvmjit_command_processor.cc b/iree/hal/llvmjit/llvmjit_command_processor.cc
new file mode 100644
index 0000000..29710ce
--- /dev/null
+++ b/iree/hal/llvmjit/llvmjit_command_processor.cc
@@ -0,0 +1,38 @@
+// Copyright 2020 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/hal/llvmjit/llvmjit_command_processor.h"
+
+#include "iree/base/tracing.h"
+#include "iree/hal/llvmjit/llvmjit_executable.h"
+
+namespace iree {
+namespace hal {
+namespace llvmjit {
+
+LLVMJITCommandProcessor::LLVMJITCommandProcessor(
+ Allocator* allocator, CommandBufferModeBitfield mode,
+ CommandCategoryBitfield command_categories)
+ : HostLocalCommandProcessor(allocator, mode, command_categories) {}
+
+LLVMJITCommandProcessor::~LLVMJITCommandProcessor() = default;
+
+Status LLVMJITCommandProcessor::Dispatch(
+ const DispatchRequest& dispatch_request) {
+ IREE_TRACE_SCOPE0("LLVMJITCommandProcessor::Dispatch");
+ return OkStatus();
+}
+} // namespace llvmjit
+} // namespace hal
+} // namespace iree
diff --git a/iree/hal/llvmjit/llvmjit_command_processor.h b/iree/hal/llvmjit/llvmjit_command_processor.h
new file mode 100644
index 0000000..ec5eda6
--- /dev/null
+++ b/iree/hal/llvmjit/llvmjit_command_processor.h
@@ -0,0 +1,35 @@
+// Copyright 2020 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_HAL_LLVMJIT_LLVMJIT_COMMAND_PROCESSOR_H_
+#define IREE_HAL_LLVMJIT_LLVMJIT_COMMAND_PROCESSOR_H_
+#include "iree/hal/host/host_local_command_processor.h"
+
+namespace iree {
+namespace hal {
+namespace llvmjit {
+
+class LLVMJITCommandProcessor final : public HostLocalCommandProcessor {
+ public:
+ LLVMJITCommandProcessor(Allocator* allocator, CommandBufferModeBitfield mode,
+ CommandCategoryBitfield command_categories);
+ ~LLVMJITCommandProcessor() override;
+
+ Status Dispatch(const DispatchRequest& dispatch_request) override;
+};
+} // namespace llvmjit
+} // namespace hal
+} // namespace iree
+
+#endif // IREE_HAL_LLVMJIT_LLVMJIT_COMMAND_PROCESSOR_H_
diff --git a/iree/hal/llvmjit/llvmjit_device.cc b/iree/hal/llvmjit/llvmjit_device.cc
new file mode 100644
index 0000000..185e191
--- /dev/null
+++ b/iree/hal/llvmjit/llvmjit_device.cc
@@ -0,0 +1,173 @@
+// Copyright 2020 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/hal/llvmjit/llvmjit_device.h"
+
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "iree/base/status.h"
+#include "iree/base/tracing.h"
+#include "iree/hal/command_buffer_validation.h"
+#include "iree/hal/command_queue.h"
+#include "iree/hal/fence.h"
+#include "iree/hal/host/async_command_queue.h"
+#include "iree/hal/host/host_event.h"
+#include "iree/hal/host/host_submission_queue.h"
+#include "iree/hal/host/inproc_command_buffer.h"
+#include "iree/hal/llvmjit/llvmjit_command_processor.h"
+#include "iree/hal/llvmjit/llvmjit_executable_cache.h"
+
+namespace iree {
+namespace hal {
+namespace llvmjit {
+
+namespace {
+
+// A CommandQueue that performs no synchronization (semaphores/fences) and just
+// directly executes command buffers inline.
+//
+// This is meant to be wrapped by SyncCommandQueue or AsyncCommandQueue that
+// themselves perform the synchronization/threading/etc. As such we ignore
+// all semaphores in the provided batches under the assumption that if Submit is
+// being called then all dependencies are valid. The wrapping queue is also
+// responsible for signaling the fence as well as propagating errors in a way
+// that is dependent on how it is performing its synchronization.
+class UnsynchronizedCommandQueue final : public CommandQueue {
+ public:
+ UnsynchronizedCommandQueue(Allocator* allocator, std::string name,
+ CommandCategoryBitfield supported_categories)
+ : CommandQueue(std::move(name), supported_categories),
+ allocator_(allocator) {}
+ ~UnsynchronizedCommandQueue() override = default;
+
+ Status Submit(absl::Span<const SubmissionBatch> batches,
+ FenceValue fence) override {
+ IREE_TRACE_SCOPE0("UnsynchronizedCommandQueue::Submit");
+ DCHECK_EQ(nullptr, fence.first)
+ << "Fences must be handled by the wrapping queue";
+
+ // Process command buffers and propagate errors asynchronously through the
+ // fence. This ensures that even if we are running synchronously we still
+ // get consistent failure behavior with drivers that are purely async.
+ for (auto& batch : batches) {
+ DCHECK(batch.wait_semaphores.empty() && batch.signal_semaphores.empty())
+ << "Semaphores must be handled by the wrapping queue";
+ RETURN_IF_ERROR(ProcessCommandBuffers(batch.command_buffers));
+ }
+
+ // NOTE: fence is ignored here.
+ return OkStatus();
+ }
+
+ Status WaitIdle(absl::Time deadline) override {
+ // No-op.
+ return OkStatus();
+ }
+
+ private:
+ // Processes each command buffer in-turn with a fresh processor.
+ // This ensures we don't have any state that can carry across buffers.
+ Status ProcessCommandBuffers(
+ absl::Span<CommandBuffer* const> command_buffers) {
+ IREE_TRACE_SCOPE0("UnsynchronizedCommandQueue::ProcessCommandBuffers");
+ for (auto* command_buffer : command_buffers) {
+ auto* inproc_command_buffer =
+ static_cast<InProcCommandBuffer*>(command_buffer->impl());
+ LLVMJITCommandProcessor command_processor(
+ allocator_, command_buffer->mode(), supported_categories());
+ RETURN_IF_ERROR(inproc_command_buffer->Process(&command_processor));
+ }
+ return OkStatus();
+ }
+
+ Allocator* const allocator_;
+};
+
+} // namespace
+
+LLVMJITDevice::LLVMJITDevice(DeviceInfo device_info)
+ : Device(std::move(device_info)) {
+ // We currently only expose a single command queue.
+ auto command_queue = absl::make_unique<UnsynchronizedCommandQueue>(
+ &allocator_, "cpu0",
+ CommandCategory::kTransfer | CommandCategory::kDispatch);
+
+ // TODO(benvanik): allow injection of the wrapper type to support
+ // SyncCommandQueue without always linking in both.
+ auto async_command_queue =
+ absl::make_unique<AsyncCommandQueue>(std::move(command_queue));
+ command_queues_.push_back(std::move(async_command_queue));
+}
+
+LLVMJITDevice::~LLVMJITDevice() = default;
+
+ref_ptr<ExecutableCache> LLVMJITDevice::CreateExecutableCache() {
+ return make_ref<LLVMJITExecutableCache>(&allocator_);
+}
+
+StatusOr<ref_ptr<CommandBuffer>> LLVMJITDevice::CreateCommandBuffer(
+ CommandBufferModeBitfield mode,
+ CommandCategoryBitfield command_categories) {
+ // TODO(b/140026716): conditionally enable validation.
+ auto impl =
+ make_ref<InProcCommandBuffer>(&allocator_, mode, command_categories);
+ return WrapCommandBufferWithValidation(std::move(impl));
+}
+
+StatusOr<ref_ptr<Event>> LLVMJITDevice::CreateEvent() {
+ return make_ref<HostEvent>();
+}
+
+StatusOr<ref_ptr<BinarySemaphore>> LLVMJITDevice::CreateBinarySemaphore(
+ bool initial_value) {
+ IREE_TRACE_SCOPE0("LLVMJITDevice::CreateBinarySemaphore");
+ return make_ref<HostBinarySemaphore>(initial_value);
+}
+
+StatusOr<ref_ptr<TimelineSemaphore>> LLVMJITDevice::CreateTimelineSemaphore(
+ uint64_t initial_value) {
+ IREE_TRACE_SCOPE0("LLVMJITDevice::CreateTimelineSemaphore");
+
+ // TODO(b/140141417): implement timeline semaphores.
+ return UnimplementedErrorBuilder(IREE_LOC)
+ << "Timeline semaphores not yet implemented";
+}
+
+StatusOr<ref_ptr<Fence>> LLVMJITDevice::CreateFence(uint64_t initial_value) {
+ IREE_TRACE_SCOPE0("LLVMJITDevice::CreateFence");
+ return make_ref<HostFence>(initial_value);
+}
+
+Status LLVMJITDevice::WaitAllFences(absl::Span<const FenceValue> fences,
+ absl::Time deadline) {
+ IREE_TRACE_SCOPE0("LLVMJITDevice::WaitAllFences");
+ return HostFence::WaitForFences(fences, /*wait_all=*/true, deadline);
+}
+
+StatusOr<int> LLVMJITDevice::WaitAnyFence(absl::Span<const FenceValue> fences,
+ absl::Time deadline) {
+ IREE_TRACE_SCOPE0("LLVMJITDevice::WaitAnyFence");
+ return HostFence::WaitForFences(fences, /*wait_all=*/false, deadline);
+}
+
+Status LLVMJITDevice::WaitIdle(absl::Time deadline) {
+ for (auto& command_queue : command_queues_) {
+ RETURN_IF_ERROR(command_queue->WaitIdle(deadline));
+ }
+ return OkStatus();
+}
+} // namespace llvmjit
+} // namespace hal
+} // namespace iree
diff --git a/iree/hal/llvmjit/llvmjit_device.h b/iree/hal/llvmjit/llvmjit_device.h
new file mode 100644
index 0000000..ca0f274
--- /dev/null
+++ b/iree/hal/llvmjit/llvmjit_device.h
@@ -0,0 +1,72 @@
+// Copyright 2020 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_HAL_LLVMJIT_LLVMJIT_DEVICE_H_
+#define IREE_HAL_LLVMJIT_LLVMJIT_DEVICE_H_
+
+#include "absl/container/inlined_vector.h"
+#include "absl/types/span.h"
+#include "iree/base/memory.h"
+#include "iree/hal/device.h"
+#include "iree/hal/host/host_local_allocator.h"
+
+namespace iree {
+namespace hal {
+namespace llvmjit {
+
+class LLVMJITDevice final : public Device {
+ public:
+ explicit LLVMJITDevice(DeviceInfo device_info);
+ ~LLVMJITDevice() override;
+
+ Allocator* allocator() const override { return &allocator_; }
+
+ absl::Span<CommandQueue*> dispatch_queues() const override {
+ return RawPtrSpan(absl::MakeSpan(command_queues_));
+ }
+
+ absl::Span<CommandQueue*> transfer_queues() const override {
+ return RawPtrSpan(absl::MakeSpan(command_queues_));
+ }
+
+ ref_ptr<ExecutableCache> CreateExecutableCache() override;
+
+ StatusOr<ref_ptr<CommandBuffer>> CreateCommandBuffer(
+ CommandBufferModeBitfield mode,
+ CommandCategoryBitfield command_categories) override;
+
+ StatusOr<ref_ptr<Event>> CreateEvent() override;
+
+ StatusOr<ref_ptr<BinarySemaphore>> CreateBinarySemaphore(
+ bool initial_value) override;
+ StatusOr<ref_ptr<TimelineSemaphore>> CreateTimelineSemaphore(
+ uint64_t initial_value) override;
+
+ StatusOr<ref_ptr<Fence>> CreateFence(uint64_t initial_value) override;
+ Status WaitAllFences(absl::Span<const FenceValue> fences,
+ absl::Time deadline) override;
+ StatusOr<int> WaitAnyFence(absl::Span<const FenceValue> fences,
+ absl::Time deadline) override;
+
+ Status WaitIdle(absl::Time deadline) override;
+
+ private:
+ mutable HostLocalAllocator allocator_;
+ mutable absl::InlinedVector<std::unique_ptr<CommandQueue>, 1> command_queues_;
+};
+} // namespace llvmjit
+} // namespace hal
+} // namespace iree
+
+#endif // IREE_HAL_LLVMJIT_LLVMJIT_DEVICE_H_
diff --git a/iree/hal/llvmjit/llvmjit_driver.cc b/iree/hal/llvmjit/llvmjit_driver.cc
new file mode 100644
index 0000000..3c92f47
--- /dev/null
+++ b/iree/hal/llvmjit/llvmjit_driver.cc
@@ -0,0 +1,61 @@
+// Copyright 2020 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/hal/llvmjit/llvmjit_driver.h"
+
+#include <memory>
+
+#include "iree/hal/device_info.h"
+#include "iree/hal/llvmjit/llvmjit_device.h"
+
+namespace iree {
+namespace hal {
+namespace llvmjit {
+namespace {
+
+DeviceInfo GetDefaultDeviceInfo() {
+ DeviceFeatureBitfield supported_features = DeviceFeature::kNone;
+ // TODO(benvanik): implement debugging/profiling features.
+ // supported_features |= DeviceFeature::kDebugging;
+ // supported_features |= DeviceFeature::kCoverage;
+ // supported_features |= DeviceFeature::kProfiling;
+ DeviceInfo device_info("llvm", supported_features);
+ // TODO(benvanik): device info.
+ return device_info;
+}
+
+} // namespace
+
+LLVMJITDriver::LLVMJITDriver() : Driver("interpreter") {}
+
+LLVMJITDriver::~LLVMJITDriver() = default;
+
+StatusOr<std::vector<DeviceInfo>> LLVMJITDriver::EnumerateAvailableDevices() {
+ std::vector<DeviceInfo> device_infos;
+ device_infos.push_back(GetDefaultDeviceInfo());
+ return device_infos;
+}
+
+StatusOr<ref_ptr<Device>> LLVMJITDriver::CreateDefaultDevice() {
+ return CreateDevice(0);
+}
+
+StatusOr<ref_ptr<Device>> LLVMJITDriver::CreateDevice(
+ DriverDeviceID device_id) {
+ auto device = make_ref<LLVMJITDevice>(GetDefaultDeviceInfo());
+ return device;
+}
+} // namespace llvmjit
+} // namespace hal
+} // namespace iree
diff --git a/iree/hal/llvmjit/llvmjit_driver.h b/iree/hal/llvmjit/llvmjit_driver.h
new file mode 100644
index 0000000..7a53b60
--- /dev/null
+++ b/iree/hal/llvmjit/llvmjit_driver.h
@@ -0,0 +1,39 @@
+// Copyright 2020 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_HAL_LLVMJIT_LLVMJIT_DRIVER_H_
+#define IREE_HAL_LLVMJIT_LLVMJIT_DRIVER_H_
+
+#include "iree/hal/driver.h"
+
+namespace iree {
+namespace hal {
+namespace llvmjit {
+
+class LLVMJITDriver final : public Driver {
+ public:
+ LLVMJITDriver();
+ ~LLVMJITDriver() override;
+
+ StatusOr<std::vector<DeviceInfo>> EnumerateAvailableDevices() override;
+
+ StatusOr<ref_ptr<Device>> CreateDefaultDevice() override;
+
+ StatusOr<ref_ptr<Device>> CreateDevice(DriverDeviceID device_id) override;
+};
+} // namespace llvmjit
+} // namespace hal
+} // namespace iree
+
+#endif // IREE_HAL_LLVMJIT_LLVMJIT_DRIVER_H_
diff --git a/iree/hal/llvmjit/llvmjit_driver_module.cc b/iree/hal/llvmjit/llvmjit_driver_module.cc
new file mode 100644
index 0000000..d3a12c7
--- /dev/null
+++ b/iree/hal/llvmjit/llvmjit_driver_module.cc
@@ -0,0 +1,37 @@
+// Copyright 2020 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 <memory>
+
+#include "iree/base/init.h"
+#include "iree/base/status.h"
+#include "iree/hal/driver_registry.h"
+#include "iree/hal/llvmjit/llvmjit_driver.h"
+
+namespace iree {
+namespace hal {
+namespace llvmjit {
+
+static StatusOr<ref_ptr<Driver>> CreateLLVMJITDriver() {
+ return make_ref<LLVMJITDriver>();
+}
+} // namespace llvmjit
+} // namespace hal
+} // namespace iree
+
+IREE_REGISTER_MODULE_INITIALIZER(iree_hal_llvm_driver, {
+ QCHECK_OK(::iree::hal::DriverRegistry::shared_registry()->Register(
+ "llvm", ::iree::hal::llvmjit::CreateLLVMJITDriver));
+});
+IREE_REGISTER_MODULE_INITIALIZER_SEQUENCE(iree_hal, iree_hal_llvm_driver);
diff --git a/iree/hal/llvmjit/llvmjit_executable.cc b/iree/hal/llvmjit/llvmjit_executable.cc
new file mode 100644
index 0000000..0ad88bf
--- /dev/null
+++ b/iree/hal/llvmjit/llvmjit_executable.cc
@@ -0,0 +1,51 @@
+// Copyright 2020 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/hal/llvmjit/llvmjit_executable.h"
+
+#include <iostream>
+
+namespace iree {
+namespace hal {
+namespace llvmjit {
+
+// static
+StatusOr<ref_ptr<LLVMJITExecutable>> LLVMJITExecutable::Load(
+ hal::Allocator* allocator, ExecutableSpec spec, bool allow_aliasing_data) {
+ // Allocate the executable now.
+ // We do this here so that if we need to clone the data we are passing that
+ // to the VM loader instead of the data we may not have access to later.
+
+ auto executable =
+ make_ref<LLVMJITExecutable>(allocator, spec, allow_aliasing_data);
+
+ return executable;
+}
+
+LLVMJITExecutable::LLVMJITExecutable(hal::Allocator* allocator,
+ ExecutableSpec spec,
+ bool allow_aliasing_data)
+ : spec_(spec) {
+ if (!allow_aliasing_data) {
+ // Clone data.
+ cloned_executable_data_ = {spec.executable_data.begin(),
+ spec.executable_data.end()};
+ spec_.executable_data = absl::MakeConstSpan(cloned_executable_data_);
+ }
+}
+
+LLVMJITExecutable::~LLVMJITExecutable() = default;
+} // namespace llvmjit
+} // namespace hal
+} // namespace iree
diff --git a/iree/hal/llvmjit/llvmjit_executable.h b/iree/hal/llvmjit/llvmjit_executable.h
new file mode 100644
index 0000000..d9be4b2
--- /dev/null
+++ b/iree/hal/llvmjit/llvmjit_executable.h
@@ -0,0 +1,49 @@
+// Copyright 2020 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_HAL_LLVMJIT_LLVMJIT_EXECUTABLE_H_
+#define IREE_HAL_LLVMJIT_LLVMJIT_EXECUTABLE_H_
+
+#include <vector>
+
+#include "absl/types/span.h"
+#include "iree/base/status.h"
+#include "iree/hal/allocator.h"
+#include "iree/hal/executable.h"
+#include "iree/hal/executable_spec.h"
+
+namespace iree {
+namespace hal {
+namespace llvmjit {
+
+class LLVMJITExecutable final : public Executable {
+ public:
+ static StatusOr<ref_ptr<LLVMJITExecutable>> Load(hal::Allocator* allocator,
+ ExecutableSpec spec,
+ bool allow_aliasing_data);
+ LLVMJITExecutable(hal::Allocator* allocator, ExecutableSpec spec,
+ bool allow_aliasing_data);
+ ~LLVMJITExecutable() override;
+
+ bool supports_debugging() const override { return false; }
+
+ private:
+ ExecutableSpec spec_;
+ std::vector<uint8_t> cloned_executable_data_;
+};
+} // namespace llvmjit
+} // namespace hal
+} // namespace iree
+
+#endif // IREE_HAL_LLVMJIT_LLVMJIT_EXECUTABLE_H_
diff --git a/iree/hal/llvmjit/llvmjit_executable_cache.cc b/iree/hal/llvmjit/llvmjit_executable_cache.cc
new file mode 100644
index 0000000..43d82d3
--- /dev/null
+++ b/iree/hal/llvmjit/llvmjit_executable_cache.cc
@@ -0,0 +1,55 @@
+// Copyright 2020 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/hal/llvmjit/llvmjit_executable_cache.h"
+
+#include "iree/base/source_location.h"
+#include "iree/base/status.h"
+#include "iree/base/tracing.h"
+#include "iree/hal/executable_format.h"
+#include "iree/hal/llvmjit/llvmjit_executable.h"
+
+namespace iree {
+namespace hal {
+namespace llvmjit {
+
+LLVMJITExecutableCache::LLVMJITExecutableCache(hal::Allocator* allocator)
+ : allocator_(allocator) {}
+
+LLVMJITExecutableCache::~LLVMJITExecutableCache() = default;
+
+bool LLVMJITExecutableCache::CanPrepareFormat(ExecutableFormat format) const {
+ return format == kExecutableFormatLLVM;
+}
+
+StatusOr<ref_ptr<Executable>> LLVMJITExecutableCache::PrepareExecutable(
+ ExecutableCachingModeBitfield mode, const ExecutableSpec& spec) {
+ IREE_TRACE_SCOPE0("LLVMJITExecutableCache::PrepareExecutable");
+ if (!CanPrepareFormat(spec.format)) {
+ return UnimplementedErrorBuilder(IREE_LOC)
+ << "Unsupported format: " << spec.format;
+ }
+
+ // Wrap the data (or copy it).
+ bool allow_aliasing_data =
+ AllBitsSet(mode, ExecutableCachingMode::kAliasProvidedData);
+ ASSIGN_OR_RETURN(
+ auto executable,
+ LLVMJITExecutable::Load(allocator_, spec, !allow_aliasing_data));
+
+ return executable;
+}
+} // namespace llvmjit
+} // namespace hal
+} // namespace iree
diff --git a/iree/hal/llvmjit/llvmjit_executable_cache.h b/iree/hal/llvmjit/llvmjit_executable_cache.h
new file mode 100644
index 0000000..a8315de
--- /dev/null
+++ b/iree/hal/llvmjit/llvmjit_executable_cache.h
@@ -0,0 +1,43 @@
+// Copyright 2020 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_HAL_LLVMJIT_EXECUTABLE_CACHE_H_
+#define IREE_HAL_LLVMJIT_EXECUTABLE_CACHE_H_
+
+#include "iree/hal/allocator.h"
+#include "iree/hal/executable.h"
+#include "iree/hal/executable_cache.h"
+
+namespace iree {
+namespace hal {
+namespace llvmjit {
+
+class LLVMJITExecutableCache final : public ExecutableCache {
+ public:
+ explicit LLVMJITExecutableCache(hal::Allocator* allocator);
+ ~LLVMJITExecutableCache() override;
+
+ bool CanPrepareFormat(ExecutableFormat format) const override;
+
+ StatusOr<ref_ptr<Executable>> PrepareExecutable(
+ ExecutableCachingModeBitfield mode, const ExecutableSpec& spec) override;
+
+ private:
+ hal::Allocator* allocator_;
+};
+} // namespace llvmjit
+} // namespace hal
+} // namespace iree
+
+#endif // IREE_HAL_LLVMJIT_EXECUTABLE_CACHE_H_
diff --git a/iree/tools/BUILD b/iree/tools/BUILD
index 36587ea..06eaee0 100644
--- a/iree/tools/BUILD
+++ b/iree/tools/BUILD
@@ -41,6 +41,7 @@
# "//iree/hal/dawn:dawn_driver_module",
"//iree/hal/vmla:vmla_driver_module",
"//iree/hal/vulkan:vulkan_driver_module",
+ "//iree/hal/llvmjit:llvmjit_driver_module",
]
cc_binary(
diff --git a/iree/tools/CMakeLists.txt b/iree/tools/CMakeLists.txt
index e8bd8db..546a670 100644
--- a/iree/tools/CMakeLists.txt
+++ b/iree/tools/CMakeLists.txt
@@ -55,6 +55,7 @@
# iree::hal::dawn::dawn_driver_module
iree::hal::vmla::vmla_driver_module
iree::hal::vulkan::vulkan_driver_module
+ iree::hal::llvmjit::llvmjit_driver_module
)
add_executable(iree-benchmark-module ALIAS iree_tools_iree-benchmark-module)