Removing Metal backend until it can be replaced.
This commit can be used to revive the configuration for the driver
and view a partially-ported version of it. The actual implementation
will need to be rebased onto the C type system and written in
Objective C. Note that the compiler backend has not been removed - we
can use that for verifying metal shader output.

Issue #4370 tracks reviving this.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 03a213b..287ccf5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -115,7 +115,6 @@
 # List of all HAL drivers to be built by default:
 set(IREE_ALL_HAL_DRIVERS
   DyLib
-  Metal
   VMLA
   Vulkan
 )
@@ -126,9 +125,6 @@
   # For Apple platforms we need to use Metal instead of Vulkan.
   if(APPLE)
     list(REMOVE_ITEM IREE_HAL_DRIVERS_TO_BUILD Vulkan)
-  else()
-    # And Metal isn't available on non-Apple platforms for sure.
-    list(REMOVE_ITEM IREE_HAL_DRIVERS_TO_BUILD Metal)
   endif()
 endif()
 message(STATUS "Building HAL drivers: ${IREE_HAL_DRIVERS_TO_BUILD}")
diff --git a/docs/design_docs/metal_hal_driver.md b/docs/design_docs/metal_hal_driver.md
deleted file mode 100644
index 064e2bb..0000000
--- a/docs/design_docs/metal_hal_driver.md
+++ /dev/null
@@ -1,371 +0,0 @@
-# Metal HAL Driver
-
-This document lists technical details regarding the Metal HAL driver. Note that
-the Metal HAL driver is working in progress; this document is expected to be
-updated along the way.
-
-IREE provides a [Hardware Abstraction Layer (HAL)][iree-hal] as a common
-interface to different compute accelerators. IREE HAL's design draws inspiration
-from modern GPU architecture and APIs; so implementing a HAL driver using modern
-GPU APIs is generally straightforward. This applies to the Metal HAL driver.
-
-## Overall Design Choices
-
-### Metal Versions
-
-The Metal HAL driver expects Metal 2+. Metal 2 introduces useful features like
-argument buffer, performance shaders, and others, that can improve performance
-and make IREE HAL implementation simpler. Metal 2 was released late 2017 and are
-supported since macOS High Sierra and iOS 11. It is already dominant
-([macOS][macos-version-share], [iOS][ios-version-share]) right now.
-
-### Programming Languages and Libraries
-
-The Metal HAL driver lives under the [`iree/hal/metal/`][iree-metal] directory.
-Header (`.h`) and implementation (`.mm`) files are put adjacent to each other.
-
-The Metal framework only exposes Objective-C or Swift programming language APIs.
-Metal HAL driver needs to inherit from common HAL abstraction classes, which are
-C++. So we use [Objective-C++][objcxx] for implementing the Metal HAL driver.
-The headers try to stay with pure C/C++ syntax when possible, except for
-`#import <Metal/Metal.h>` and using Metal `id` types.
-
-### Object Lifetime Management
-
-Objective-C uses refcount for tracking object lifetime and managing memory. This
-is traditionally done manually by sending `retain` and `release` messages to
-Objective-C objects. Modern Objective-C allows developers to opt in to use
-[Automatic Reference Counting][objc-arc] to let the compiler to automatically
-deduce and insert `retain`/`release` where possible to simplify the burdern of
-manual management.
-
-We don't use ARC in the Metal HAL driver given that IREE has its own object
-[refcount][iree-refptr] and lifetime management mechanism. Metal HAL GPU objects
-are tracked with that to be consistent with others. Each Metal HAL GPU object
-`retain`s the underlying Metal `id<MTL*>` object on construction and `release`s
-on destruction.
-
-## GPU Objects
-
-Metal is one of the main modern GPU APIs that provide more explicit control over
-the hardware. The mapping between IREE HAL classes and Metal protocols are
-relatively straightforward:
-
-IREE HAL Class                             | Metal Protocol
-:----------------------------------------: | :------------:
-[`hal::Driver`][hal-driver]                | N/A
-[`hal::Device`][hal-device]                | [`MTLDevice`][mtl-device]
-[`hal::CommandQueue`][hal-command-queue]   | [`MTLCommandQueue`][mtl-command-queue]
-[`hal::CommandBuffer`][hal-command-buffer] | [`MTLCommandBuffer`][mtl-command-buffer]
-[`hal::Semaphore`][hal-semaphore]          | [`MTLSharedEvent`][mtl-shared-event]
-[`hal::Allocator`][hal-allocator]          | N/A
-[`hal::Buffer`][hal-buffer]                | [`MTLBuffer`][mtl-buffer]
-[`hal::Executable`][hal-executable]        | [`MTLLibrary`][mtl-library]
-[`hal::ExecutableCache`][hal-executable-cache] | N/A
-[`hal::DescriptorSetLayout`][hal-descriptor-set-layout] | N/A
-[`hal::DescriptorSet`][hal-descriptor-set] | N/A
-[`hal::ExecutableLayout`][hal-executable-layout] | N/A
-
-In the following subsections, we go over each pair to provide more details.
-
-### Driver
-
-There is no native driver abstraction in Metal. IREE's Metal HAL driver still
-provides a [`hal::metal::MetalDriver`][metal-driver] subclass inheriting from
-common [`hal::Driver`][hal-driver] class. `hal::metal::MetalDriver` just
-`retain`s all available Metal devices in the system during its lifetime to
-provide similar interface as other HAL drivers.
-
-### Device
-
-[`hal::metal::MetalDevice`][metal-device] inherits [`hal::Device`][hal-device]
-to provide the interface to Metal GPU device by wrapping a `id<MTLDevice>`. Upon
-construction, `hal::metal::MetalDevice` creates and retains one queue for both
-dispatch and transfer during its lifetime.
-
-Metal requres command buffers to be created from a `MTLCommandQueue`. In IREE
-HAL, command buffers are directly created from the `hal::Device`.
-`hal::metal::MetalDevice` chooses the proper queue to create the command buffer
-under the hood.
-
-### Command queue
-
-IREE HAL command queue follows Vulkan for modelling submission. Specifically,
-`hal::CommandQueue::Submit()` takes a `SubmissionBatch`, which contains a list
-of waiting `hal::Semaphore`s, a list of command buffers, and a list signaling
-`hal::Semaphore`s. There is no direct mapping in Metal; so
-[`hal::metal::MetalCommandQueue`][metal-command-queue] performs the submission
-in three steps:
-
-1.  Create a new `MTLCommandBuffer` to `encodeWaitForEvent:value` for all
-    waiting `hal::Semaphore`s and commit this command buffer.
-1.  Commit all command buffers in the `SubmissionBatch`.
-1.  Create a new `MTLCommandBuffer` to `encodeSignalEvent:value` for all
-    signaling `hal::Semaphore`s and commit this command buffer.
-
-There is also no direct `WaitIdle()` for
-[`MTLCommandQueue`][mtl-command-queue]s. `hal::metal::MetalCommandQueue`
-implements `WaitIdle()` by committing an empty `MTLCommandBuffer` and
-registering a complete handler for it to signal a semaphore to wake the current
-thread, which is put into sleep by waiting on the semaphore.
-
-### Command buffer
-
-In Metal, commands are recorded into a command buffer with three different kinds
-of [command encoders][mtl-command-encoder]: `MTLRenderCommandEncoder`,
-`MTLComputeCommandEncoder`, `MTLBlitCommandEncoder`, and
-`MTLParallelRenderCommandEncoder`. Each encoder has its own create/end call.
-There is no overall begin/end call for the whold command buffer. So even
-[`hal::metal::MetalCommandBuffer`][metal-command-buffer] implements an overall
-`Begin()`/`End()` call, under the hood it may create a new command encoder for a
-specific API call.
-
-### Timeline semaphore
-
-[`hal::Semaphore`][hal-semaphore] allows host->device, device->host, host->host,
-and device->device synchronization. It maps to Vulkan timeline semaphore. In
-Metal world, the counterpart would be [`MTLSharedEvent`][mtl-shared-event]. Most
-of the `hal::Semaphore` APIs are simple to implement in
-[`MetalSharedEvent`][metal-shared-event], with `Wait()` as an exception. A
-listener is registered on the `MTLSharedEvent` with
-`notifyListener:atValue:block:` to singal a semaphore to wake the current
-thread, which is put into sleep by waiting on the semaphore.
-
-### Allocator
-
-At the moment the Metal HAL driver just has a very simple
-[`hal::Allocator`][hal-allocator] implementation. It just wraps a `MTLDevice`
-and redirects all allocation requests to the `MTLDevice`. No page/pool/slab or
-whatever. This is only meant to get started. In the future we should have a
-better memory allocation library, probably by layering the
-[Vulkan Memory Allocator][vma] on top of [`MTLHeap`][mtl-heap].
-
-### Buffer
-
-IREE [`hal::Buffer`][hal-buffer] maps Metal `MTLBuffer`. See
-[Memory Management](#memory-management) for more details.
-
-### Executable
-
-IREE [`hal::Executable`][hal-executable] represents a GPU program archive with
-a driver-defined format. It maps naturally to Metal [`MTLLibrary`][mtl-library].
-An entry point in a `MTLLibrary` is a [`MTLFunction`][mtl-function]. We define
-[`hal::metal::MetalKernelLibrary`][metal-kernel-library] to wrap around a
-`MTLLibrary`, its `MTLFunction`s, and also `MTLComputePipelineState` objects
-constructed from `MTLFunction`s.
-
-### Executable cache
-
-IREE [`hal::ExecutableCache`][hal-executable-cache] is modelling a cache of
-preprared GPU executables for a particular device. At the moment the Metal
-HAL driver does not peforming any cache on GPU programs; it simply reads the
-program from the FlatBuffer and hands it over to Metal driver.
-
-### DescriptorSetLayout, DescriptorSet, ExecutableLayout
-
-See [Resource descriptors](#resource-descriptors) for more details.
-
-## Compute Pipeline
-
-### Shader/kernel compilation
-
-Metal has [Metal Shading Language (MSL)][msl-spec] for authoring graphics
-shaders and compute kernels. MSL source code can be directly consumed by the
-Metal framework at run-time; it can also be compiled first into an opaque
-library using [command-line tools][msl-cl-library] at build-time.
-
-IREE uses compilers to compile ML models expressed with high-level op semantics
-down to GPU native source format. This is also the case for the Metal HAL
-driver. Metal does not provide an open intermediate language; we reuse the
-[SPIR-V code generation pipeline][spirv-codegen] and then cross compile the
-generated SPIR-V into MSL source with [SPIRV-Cross][spirv-cross]. This is
-actually a fair common practice for targeting multiple GPU APIs in graphics
-programming world. For example, the Vulkan implmenation in macOS/iOs,
-[MoltenVK][moltenvk], is also doing the same for shaders/kernels. The path
-is actually quite robust, as demonstrated by various games on top of MoltenVK.
-
-Therefore, in IREE, we have a [`MetalSPIRVTargetBackend`][metal-spirv-target],
-which pulls in the normal MHLO to Linalg and Linalg to SPIR-V passes to form
-the compilation pipeline. The difference would be to provide a suitable
-SPIR-V target environment to drive the compilation, which one can derive from
-the Metal GPU families to target. (Not implemented yet; TODO for the future.)
-The serialization step differs from
-[`VulkanSPIRVTargetBackend`][vulkan-spirv-target] too: following the normal
-SPIR-V serialization step, we additionally need to invoke SPRIV-Cross to
-cross compile the generated SPIR-V into MSL, and then compile and/or serialize
-the MSL source/library.
-
-IREE uses [FlatBuffer][flatbuffer] to encode the whole workload module,
-including both GPU shader/kernel (called executable in IREE terminology) and
-CPU scheduling logic. The GPU executables are embedded as part of the module's
-FlatBuffer, which are [`mmap`][mmap]ped when IREE runs.
-
-For the Metal HAL driver, it means we need to embed the MSL kernels inside the
-module FlatBuffer. Right now we just encode the MSL source strings and compile
-them at Metal run-time. In the future this should be changed to allow encoding
-the library instead.
-
-### Workgroup/threadgroup size
-
-When dispatching a compute kernel in Metal, we need to specify the number of
-thread groups in grid and the number of threads in thread group. Both are
-3-D vectors. IREE HAL, which follows Vulkan, calls them workgroup count and
-workgroup size, respectively.
-
-In Vulkan programming model, workgroup count and workgroup size are specified at
-different places: the former is given when invoking
-[`vkCmdDispatch()`][vulkan-cmd-dispatch], while the later is encoded in the
-dispatched SPIR-V code. This split does not match the Metal model, where we
-specify both in the API with `dispatchThreads:threadsPerThreadgroup:`.
-
-As said in [shader/kernel compilation](#shader-kernel-compilation), MSL kernels
-are cross compiled from SPIR-V code and then embeded in the module FlatBuffer.
-The module FlatBuffer provides us a way to convey the threadgroup/workgroup size
-information extracted from the SPIR-V code. We encode an additional 3-D vector
-for each entry point and use it as the threadgroup size when later dispatching
-the `MTLFunction` corresponding to the entry point.
-
-### Resource descriptors
-
-A descriptor is an opaque handle pointing to a resource that is accessed in
-the compute kernel. IREE's HAL is inspired by the Vulkan API; it models several
-concepts related to GPU resource management explicitly:
-
-* [`hal::DescriptorSetLayout`][hal-descriptor-set-layout]: a schema for
-  describing an array of descriptor bindings. Each descriptor binding specifies
-  the resource type, access mode and other information.
-* [`hal::DescriptorSet`][hal-descriptor-set]: a concrete set of resources that
-  gets bound to a compute pipeline in a batch. It must match the
-  `DescriptorSetLayout` describing its layout. `DescriptorSet` can be thought as
-  the "object" from the `DescriptorSetLayout` "class".
-* [`hal::ExecutableLayout`][hal-executable-layout]: a schema for describing all
-  the resources accessed by a compute pipeline. It includes zero or more
-  `DescriptorSetLayout`s and (optional) push constants.
-
-One can create `DescriptorSetLayout`, `DescriptorSet`, and `ExecutableLayout`
-objects beforehand to avoid incurring overhead during tight computing loops
-and also amortize costs by sharing these objects. However, this isn't totally
-matching Metal's paradigm.
-
-In the Metal framework, the closest concept to `DescriptorSet` would be [argument
-buffer][mtl-argument-buffer]. There is no direct correspondence to
-`DescriptorSetLayout` and `ExecutableLayout`. Rather, the layout is implicitly
-encoded in Metal shaders as MSL structs. The APIs for creating argument buffers
-do not encourage early creation without pipelines: one typically creates them
-for each `MTLFunction`. Besides, unlike Vulkan where different descriptor sets
-can have the same binding number, in Metal even if we have multiple argument
-buffers, the indices for resources are in the same namespace and are typically
-assigned sequentially. That means we need to remap `DescriptorSet`s with a set
-number greater than zero by applying an offset to each of its bindings.
-
-All of this means it's better to defer the creation of the argument buffer
-until the point of compute pipeline creation and dispatch. Therefore, although
-the Metal HAL driver provides the implementation for `DescriptorSet`
-(i.e., `hal::metal::MetalArgumentBuffer`), `DescriptorSetLayout` (i.e.,
-`hal::metal::MetalArgumentBufferLayout`), and `ExecutableLayout` (i.e.,
-`hal::metal::MetalPipelineArgumentBufferLayout`), they are just containers
-holding the information up until the [command buffer
-dispatch](#command-buffer-dispatch) time.
-
-With the above said, the overall idea is still to map one descriptor set to one
-argument buffer. It just means we need to condense and remap the bindings.
-
-### Command buffer dispatch
-
-`MetalCommandBuffer::Dispatch()` performs the following steps with the current
-active `MTLComputeCommandEncoder`:
-
-1. Bind the `MTLComputePipelineState` for the current entry function queried
-   from `MetalKernelLibrary`.
-1. For each bound descriptor set at set #`S`:
-   1. Create a [`MTLArgumentEncoder`][mtl-argument-encoder] for encoding an
-      associated argument `MTLBuffer`.
-   1. For each bound resource buffer at binding #`B` in this descriptor set,
-      encode it to the argument buffer index #`B` with
-      `setBuffer::offset::atIndex:` and inform the `MTLComputeCommandEncoder`
-      that the dispatch will use this resource with `useResource:usage:`.
-  1. Set the argument `MTLBuffer` to buffer index #`S`.
-1. Dispatch with `dispatchThreadgroups:threadsPerThreadgroup:`.
-
-(TODO: condense and remap bindings)
-
-## Memory Management
-
-### Storage type
-
-Metal provides four [`MTLStorageMode`][mtl-storage-mode] options:
-
-*   `MTLStorageModeShared`: The resource is stored in system memory and is
-    accessible to both the CPU and the GPU.
-*   `MTLStorageModeManaged`: The CPU and GPU may maintain separate copies of the
-    resource, and any changes must be explicitly synchronized.
-*   `MTLStorageModePrivate`: The resource can be accessed only by the GPU.
-*   `MTLStorageMemoryless`: The resource’s contents can be accessed only by the
-    GPU and only exist temporarily during a render pass.
-
-Among them, `MTLStorageModeManaged` is only available on macOS.
-
-IREE HAL defines serveral [`MemoryType`][hal-buffer]. They need to map to the
-above storage modes:
-
-*   If `kDeviceLocal` but not `kHostVisible`, `MTLStorageModePrivate` is chosen.
-*   If `kDeviceLocal` and `kHostVisible`:
-    *   If macOS, `MTLStorageModeManaged` can be chosen.
-    *   Otherwise, `MTLStorageModeShared` is chosen.
-*   If not `DeviceLocal` but `kDeviceVisible`, `MTLStorageModeShared` is chosen.
-*   If not `kDeviceLocal` and not `kDeviceVisible`, `MTLStorageModeShared` is
-    chosen. (TODO: We should probably use host buffer here.)
-
-IREE HAL also allows to create buffers with `kHostCoherent` bit. This may still
-be backed by `MTLStorageModeManaged` `MTLBuffer`s in macOS. To respect the
-`kHostCoherent` protocol, the Metal HAL driver will perform necessary
-`InValidate`/`Flush` operations automatically under the hood.
-
-[macos-version-share]: https://gs.statcounter.com/macos-version-market-share/desktop/worldwide
-[ios-version-share]: https://developer.apple.com/support/app-store/
-[iree-hal]: https://github.com/google/iree/tree/main/iree/hal
-[iree-metal]: https://github.com/google/iree/tree/main/iree/hal/metal
-[iree-refptr]: https://github.com/google/iree/blob/main/iree/base/ref_ptr.h
-[hal-allocator]: https://github.com/google/iree/blob/main/iree/hal/allocator.h
-[hal-buffer]: https://github.com/google/iree/blob/main/iree/hal/buffer.h
-[hal-command-queue]: https://github.com/google/iree/blob/main/iree/hal/command_queue.h
-[hal-command-buffer]: https://github.com/google/iree/blob/main/iree/hal/command_buffer.h
-[hal-descriptor-set]: https://github.com/google/iree/blob/main/iree/hal/descriptor_set.h
-[hal-descriptor-set-layout]: https://github.com/google/iree/blob/main/iree/hal/descriptor_set_layout.h
-[hal-executable-layout]: https://github.com/google/iree/blob/main/iree/hal/executable_layout.h
-[hal-device]: https://github.com/google/iree/blob/main/iree/hal/device.h
-[hal-driver]: https://github.com/google/iree/blob/main/iree/hal/driver.h
-[hal-executable]: https://github.com/google/iree/blob/main/iree/hal/executable.h
-[hal-executable-cache]: https://github.com/google/iree/blob/main/iree/hal/executable_cache.h
-[hal-semaphore]: https://github.com/google/iree/blob/main/iree/hal/semaphore.h
-[metal-command-queue]: https://github.com/google/iree/blob/main/iree/hal/metal/metal_command_queue.h
-[metal-command-buffer]: https://github.com/google/iree/blob/main/iree/hal/metal/metal_command_buffer.h
-[metal-device]: https://github.com/google/iree/blob/main/iree/hal/metal/metal_device.h
-[metal-driver]: https://github.com/google/iree/blob/main/iree/hal/metal/metal_driver.h
-[metal-kernel-library]: https://github.com/google/iree/blob/main/iree/hal/metal/metal_kernel_library.h
-[metal-shared-event]: https://github.com/google/iree/blob/main/iree/hal/metal/metal_shared_event.h
-[metal-spirv-target]: https://github.com/google/iree/tree/hal-metal/iree/compiler/Dialect/HAL/Target/MetalSPIRV
-[mtl-argument-buffer]: https://developer.apple.com/documentation/metal/buffers/about_argument_buffers?language=objc
-[mtl-argument-encoder]: https://developer.apple.com/documentation/metal/mtlargumentencoder?language=objc
-[mtl-buffer]: https://developer.apple.com/documentation/metal/mtlbuffer?language=objc
-[mtl-command-buffer]: https://developer.apple.com/documentation/metal/mtlcommandbuffer?language=objc
-[mtl-command-encoder]: https://developer.apple.com/documentation/metal/mtlcommandencoder?language=objc
-[mtl-command-queue]: https://developer.apple.com/documentation/metal/mtlcommandqueue?language=objc
-[mtl-device]: https://developer.apple.com/documentation/metal/mtldevice?language=objc
-[mtl-function]: https://developer.apple.com/documentation/metal/mtlfunction?language=objc
-[mtl-heap]: https://developer.apple.com/documentation/metal/mtlheap?language=objc
-[mtl-library]: https://developer.apple.com/documentation/metal/mtllibrary?language=objc
-[mtl-shared-event]: https://developer.apple.com/documentation/metal/mtlsharedevent?language=objc
-[mtl-storage-mode]: https://developer.apple.com/documentation/metal/mtlstoragemode?language=objc
-[msl-spec]: https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf
-[msl-cl-library]: https://developer.apple.com/documentation/metal/libraries/building_a_library_with_metal_s_command-line_tools?language=objc
-[objc-arc]: https://en.wikipedia.org/wiki/Automatic_Reference_Counting
-[objcxx]: https://en.wikipedia.org/wiki/Objective-C#Objective-C++
-[flatbuffer]: https://google.github.io/flatbuffers/
-[mmap]: https://en.wikipedia.org/wiki/Mmap
-[moltenvk]: https://github.com/KhronosGroup/MoltenVK
-[spirv-codegen]: https://google.github.io/iree/design-docs/codegen-passes
-[spirv-cross]: https://github.com/KhronosGroup/SPIRV-Cross
-[vma]: https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
-[vulkan-spirv-target]: https://github.com/google/iree/tree/hal-metal/iree/compiler/Dialect/HAL/Target/VulkanSPIRV
-[vulkan-cmd-dispatch]: https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCmdDispatch.html
diff --git a/iree/hal/drivers/BUILD b/iree/hal/drivers/BUILD
index 4bf772b..8c421d7 100644
--- a/iree/hal/drivers/BUILD
+++ b/iree/hal/drivers/BUILD
@@ -30,8 +30,5 @@
         "//iree/hal/dylib/registration",
         "//iree/hal/vmla/registration",
         "//iree/hal/vulkan/registration",
-    ] + select({
-        "@bazel_tools//src/conditions:darwin": ["//iree/hal/metal/registration"],
-        "//conditions:default": [],
-    }),
+    ],
 )
diff --git a/iree/hal/drivers/CMakeLists.txt b/iree/hal/drivers/CMakeLists.txt
index 3671c84..305bcb5 100644
--- a/iree/hal/drivers/CMakeLists.txt
+++ b/iree/hal/drivers/CMakeLists.txt
@@ -18,9 +18,6 @@
 if(${IREE_HAL_DRIVER_DYLIB})
   list(APPEND IREE_HAL_DRIVER_MODULES iree::hal::dylib::registration)
 endif()
-if(${IREE_HAL_DRIVER_METAL})
-  list(APPEND IREE_HAL_DRIVER_MODULES iree::hal::metal::registration)
-endif()
 if(${IREE_HAL_DRIVER_VMLA})
   list(APPEND IREE_HAL_DRIVER_MODULES iree::hal::vmla::registration)
 endif()
diff --git a/iree/hal/drivers/init.c b/iree/hal/drivers/init.c
index 2b9a2b9..bb36616 100644
--- a/iree/hal/drivers/init.c
+++ b/iree/hal/drivers/init.c
@@ -20,10 +20,6 @@
 #include "iree/hal/dylib/registration/driver_module.h"
 #endif  // IREE_HAL_HAVE_DYLIB_DRIVER_MODULE
 
-#if defined(IREE_HAL_HAVE_METAL_DRIVER_MODULE)
-#include "iree/hal/metal/registration/driver_module.h"
-#endif  // IREE_HAL_HAVE_METAL_DRIVER_MODULE
-
 #if defined(IREE_HAL_HAVE_VMLA_DRIVER_MODULE)
 #include "iree/hal/vmla/registration/driver_module.h"
 #endif  // IREE_HAL_HAVE_VMLA_DRIVER_MODULE
@@ -41,11 +37,6 @@
       z0, iree_hal_dylib_driver_module_register(registry));
 #endif  // IREE_HAL_HAVE_DYLIB_DRIVER_MODULE
 
-#if defined(IREE_HAL_HAVE_METAL_DRIVER_MODULE)
-  IREE_RETURN_AND_END_ZONE_IF_ERROR(
-      z0, iree_hal_metal_driver_module_register(registry));
-#endif  // IREE_HAL_HAVE_METAL_DRIVER_MODULE
-
 #if defined(IREE_HAL_HAVE_VMLA_DRIVER_MODULE)
   IREE_RETURN_AND_END_ZONE_IF_ERROR(
       z0, iree_hal_vmla_driver_module_register(registry));
diff --git a/iree/hal/metal/BUILD.bazel b/iree/hal/metal/BUILD.bazel
deleted file mode 100644
index 388b824..0000000
--- a/iree/hal/metal/BUILD.bazel
+++ /dev/null
@@ -1,70 +0,0 @@
-# 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.
-
-package(
-    default_visibility = ["//visibility:public"],
-    features = ["layering_check"],
-    licenses = ["notice"],  # Apache 2.0
-)
-
-objc_library(
-    name = "metal",
-    srcs = [
-        "metal_pipeline_argument_buffer.cc",
-    ],
-    hdrs = [
-        "dispatch_time_util.h",
-        "metal_buffer.h",
-        "metal_capture_manager.h",
-        "metal_command_buffer.h",
-        "metal_command_queue.h",
-        "metal_device.h",
-        "metal_direct_allocator.h",
-        "metal_driver.h",
-        "metal_kernel_library.h",
-        "metal_pipeline_argument_buffer.h",
-        "metal_pipeline_cache.h",
-        "metal_shared_event.h",
-    ],
-    copts = ["-std=c++14"],
-    non_arc_srcs = [
-        "metal_buffer.mm",
-        "metal_capture_manager.mm",
-        "metal_command_buffer.mm",
-        "metal_command_queue.mm",
-        "metal_device.mm",
-        "metal_direct_allocator.mm",
-        "metal_driver.mm",
-        "metal_kernel_library.mm",
-        "metal_pipeline_cache.mm",
-        "metal_shared_event.mm",
-    ],
-    sdk_frameworks = [
-        "Foundation",
-        "Metal",
-    ],
-    deps = [
-        "//iree/base:arena",
-        "//iree/base:file_io",
-        "//iree/base:flatcc",
-        "//iree/base:logging",
-        "//iree/base:status",
-        "//iree/base:tracing",
-        "//iree/hal",
-        "//iree/hal:command_buffer_validation",
-        "//iree/schemas:metal_executable_def_c_fbs",
-        "@com_google_absl//absl/container:flat_hash_map",
-        "@com_google_absl//absl/container:inlined_vector",
-    ],
-)
diff --git a/iree/hal/metal/CMakeLists.txt b/iree/hal/metal/CMakeLists.txt
deleted file mode 100644
index 7106f07..0000000
--- a/iree/hal/metal/CMakeLists.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-# 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.
-
-if(NOT ${IREE_HAL_DRIVER_METAL})
-  return()
-endif()
-
-iree_add_all_subdirs()
-
-iree_cc_library(
-  NAME
-    metal
-  HDRS
-    "metal_buffer.h"
-    "metal_capture_manager.h"
-    "metal_command_buffer.h"
-    "metal_command_queue.h"
-    "metal_device.h"
-    "metal_direct_allocator.h"
-    "metal_driver.h"
-    "metal_kernel_library.h"
-    "metal_pipeline_argument_buffer.h"
-    "metal_pipeline_cache.h"
-    "metal_shared_event.h"
-  SRCS
-    "metal_buffer.mm"
-    "metal_capture_manager.mm"
-    "metal_command_buffer.mm"
-    "metal_command_queue.mm"
-    "metal_device.mm"
-    "metal_direct_allocator.mm"
-    "metal_driver.mm"
-    "metal_kernel_library.mm"
-    "metal_pipeline_argument_buffer.cc"
-    "metal_pipeline_cache.mm"
-    "metal_shared_event.mm"
-  DEPS
-    absl::flat_hash_map
-    absl::inlined_vector
-    absl::memory
-    absl::span
-    absl::strings
-    iree::base::flatcc
-    iree::base::file_io
-    iree::base::logging
-    iree::base::status
-    iree::base::time
-    iree::base::tracing
-    iree::hal::cc
-    iree::schemas::metal_executable_def_c_fbs
-  LINKOPTS
-    "-framework Foundation"
-    "-framework Metal"
-  PUBLIC
-)
diff --git a/iree/hal/metal/README.md b/iree/hal/metal/README.md
deleted file mode 100644
index d0bbc85..0000000
--- a/iree/hal/metal/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Metal HAL Driver
-
-**TODO(antiagainst)**: move the docs here - having them separate is suboptimal.
-
-This directory contains the source code for the Metal HAL driver. See the
-[design doc](https://google.github.io/iree/design-docs/metal-hal-driver) for
-more details.
diff --git a/iree/hal/metal/dispatch_time_util.h b/iree/hal/metal/dispatch_time_util.h
deleted file mode 100644
index 6023d38..0000000
--- a/iree/hal/metal/dispatch_time_util.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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_METAL_APPLE_TIME_UTIL_H_
-#define IREE_HAL_METAL_APPLE_TIME_UTIL_H_
-
-#include <dispatch/dispatch.h>
-
-#include "iree/base/time.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-// Converts a relative iree::Duration against the currrent time to the
-// corresponding dispatch_time_t value.
-static inline dispatch_time_t DurationToDispatchTime(Duration duration_ns) {
-  if (duration_ns == InfiniteDuration()) return DISPATCH_TIME_FOREVER;
-  if (duration_ns == ZeroDuration()) return DISPATCH_TIME_NOW;
-  return dispatch_time(DISPATCH_TIME_NOW, static_cast<uint64_t>(duration_ns));
-}
-
-// Converts an absolute iree::Time time to the corresponding dispatch_time_t
-// value.
-static inline dispatch_time_t DeadlineToDispatchTime(Time deadline_ns) {
-  return DurationToDispatchTime(DeadlineToRelativeTimeoutNanos(deadline_ns));
-}
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
-
-#endif  // IREE_HAL_METAL_APPLE_TIME_UTIL_H_
diff --git a/iree/hal/metal/metal_buffer.h b/iree/hal/metal/metal_buffer.h
deleted file mode 100644
index 4238d51..0000000
--- a/iree/hal/metal/metal_buffer.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// 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_METAL_METAL_BUFFER_H_
-#define IREE_HAL_METAL_METAL_BUFFER_H_
-
-#import <Metal/Metal.h>
-
-#include "iree/hal/api.h"
-
-id<MTLBuffer> iree_hal_metal_buffer_handle(iree_hal_buffer_t* base_buffer);
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-class MetalDirectAllocator;
-
-// A buffer implementation for Metal that directly wraps a MTLBuffer.
-class MetalBuffer final : public Buffer {
- public:
-  // Creates a MetalBuffer instance with retaining the given id<MTLBuffer>.
-  static StatusOr<ref_ptr<MetalBuffer>> Create(
-      MetalDirectAllocator* allocator, iree_hal_memory_type_t memory_type,
-      iree_hal_memory_access_t allowed_access, iree_hal_buffer_usage_t usage,
-      iree_device_size_t allocation_size, iree_device_size_t byte_offset,
-      iree_device_size_t byte_length, id<MTLBuffer> buffer,
-      id<MTLCommandQueue> transfer_queue);
-
-  ~MetalBuffer() override;
-
-  id<MTLBuffer> handle() const { return metal_handle_; }
-
- private:
-  // Creates a MetalBuffer instance without retaining the given id<MTLBuffer>.
-  MetalBuffer(MetalDirectAllocator* allocator,
-              iree_hal_memory_type_t memory_type,
-              iree_hal_memory_access_t allowed_access,
-              iree_hal_buffer_usage_t usage, iree_device_size_t allocation_size,
-              iree_device_size_t byte_offset, iree_device_size_t byte_length,
-              id<MTLBuffer> buffer, id<MTLCommandQueue> transfer_queue);
-
-  Status FillImpl(iree_device_size_t byte_offset,
-                  iree_device_size_t byte_length, const void* pattern,
-                  iree_device_size_t pattern_length) override;
-  Status ReadDataImpl(iree_device_size_t source_offset, void* data,
-                      iree_device_size_t data_length) override;
-  Status WriteDataImpl(iree_device_size_t target_offset, const void* data,
-                       iree_device_size_t data_length) override;
-  Status CopyDataImpl(iree_device_size_t target_offset, Buffer* source_buffer,
-                      iree_device_size_t source_offset,
-                      iree_device_size_t data_length) override;
-
-  Status MapMemoryImpl(MappingMode mapping_mode,
-                       iree_hal_memory_access_t memory_access,
-                       iree_device_size_t local_byte_offset,
-                       iree_device_size_t local_byte_length,
-                       void** out_data) override;
-  Status UnmapMemoryImpl(iree_device_size_t local_byte_offset,
-                         iree_device_size_t local_byte_length,
-                         void* data) override;
-  Status InvalidateMappedMemoryImpl(
-      iree_device_size_t local_byte_offset,
-      iree_device_size_t local_byte_length) override;
-  Status FlushMappedMemoryImpl(iree_device_size_t local_byte_offset,
-                               iree_device_size_t local_byte_length) override;
-
-  // Returns true if we need to automatically invaliate/flush CPU caches to keep
-  // memory hierarchy consistent.
-  //
-  // Note: this is needed when the buffer is requested with
-  // IREE_HAL_MEMORY_TYPE_HOST_COHERENT bit but under the hood we are using
-  // memory types that does not have that property natively, e.g.,
-  // MTLStorageModeManaged. Under such circumstances, we need to perform the
-  // invalidate/flush operation "automatically" for users.
-  bool requires_autosync() const;
-
-  // We need to hold an reference to the queue so that we can encode
-  // synchronizeResource commands for synchronizing the buffer with
-  // MTLResourceStorageModeManaged.
-  id<MTLCommandQueue> metal_transfer_queue_;
-
-  id<MTLBuffer> metal_handle_;
-};
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
-
-#endif  // IREE_HAL_METAL_METAL_BUFFER_H_
diff --git a/iree/hal/metal/metal_buffer.mm b/iree/hal/metal/metal_buffer.mm
deleted file mode 100644
index a6cb965..0000000
--- a/iree/hal/metal/metal_buffer.mm
+++ /dev/null
@@ -1,194 +0,0 @@
-// 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/metal/metal_buffer.h"
-
-#include "iree/base/status.h"
-#include "iree/base/tracing.h"
-#include "iree/hal/metal/metal_direct_allocator.h"
-
-id<MTLBuffer> iree_hal_metal_buffer_handle(iree_hal_buffer_t* base_buffer);
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-// static
-StatusOr<ref_ptr<MetalBuffer>> MetalBuffer::Create(
-    MetalDirectAllocator* allocator, iree_hal_memory_type_t memory_type,
-    iree_hal_memory_access_t allowed_access, iree_hal_buffer_usage_t usage, iree_device_size_t allocation_size,
-    iree_device_size_t byte_offset, iree_device_size_t byte_length, id<MTLBuffer> buffer,
-    id<MTLCommandQueue> transfer_queue) {
-  IREE_TRACE_SCOPE0("MetalBuffer::Create");
-  return assign_ref(new MetalBuffer(allocator, memory_type, allowed_access, usage, allocation_size,
-                                    byte_offset, byte_length, buffer, transfer_queue));
-}
-
-MetalBuffer::MetalBuffer(MetalDirectAllocator* allocator, iree_hal_memory_type_t memory_type,
-                         iree_hal_memory_access_t allowed_access, iree_hal_buffer_usage_t usage,
-                         iree_device_size_t allocation_size, iree_device_size_t byte_offset,
-                         iree_device_size_t byte_length, id<MTLBuffer> buffer,
-                         id<MTLCommandQueue> transfer_queue)
-    : Buffer(allocator, memory_type, allowed_access, usage, allocation_size, byte_offset,
-             byte_length),
-      metal_transfer_queue_([transfer_queue retain]),
-      metal_handle_(buffer) {}
-
-MetalBuffer::~MetalBuffer() {
-  IREE_TRACE_SCOPE0("MetalBuffer::dtor");
-  [metal_handle_ release];
-  [metal_transfer_queue_ release];
-}
-
-Status MetalBuffer::FillImpl(iree_device_size_t byte_offset, iree_device_size_t byte_length,
-                             const void* pattern, iree_device_size_t pattern_length) {
-  IREE_ASSIGN_OR_RETURN(auto mapping,
-                        MapMemory<uint8_t>(IREE_HAL_MEMORY_ACCESS_DISCARD_WRITE, byte_offset, byte_length));
-  void* data_ptr = static_cast<void*>(mapping.mutable_data());
-  switch (pattern_length) {
-    case 1: {
-      uint8_t* data = static_cast<uint8_t*>(data_ptr);
-      uint8_t value_bits = *static_cast<const uint8_t*>(pattern);
-      std::fill_n(data, byte_length, value_bits);
-      break;
-    }
-    case 2: {
-      uint16_t* data = static_cast<uint16_t*>(data_ptr);
-      uint16_t value_bits = *static_cast<const uint16_t*>(pattern);
-      std::fill_n(data, byte_length / sizeof(uint16_t), value_bits);
-      break;
-    }
-    case 4: {
-      uint32_t* data = static_cast<uint32_t*>(data_ptr);
-      uint32_t value_bits = *static_cast<const uint32_t*>(pattern);
-      std::fill_n(data, byte_length / sizeof(uint32_t), value_bits);
-      break;
-    }
-    default:
-      return InvalidArgumentErrorBuilder(IREE_LOC)
-             << "Unsupported scalar data size: " << pattern_length;
-  }
-  return OkStatus();
-}
-
-Status MetalBuffer::ReadDataImpl(iree_device_size_t source_offset, void* data,
-                                 iree_device_size_t data_length) {
-  IREE_ASSIGN_OR_RETURN(auto mapping,
-                        MapMemory<uint8_t>(IREE_HAL_MEMORY_ACCESS_READ, source_offset, data_length));
-  std::memcpy(data, mapping.data(), mapping.byte_length());
-  return OkStatus();
-}
-
-Status MetalBuffer::WriteDataImpl(iree_device_size_t target_offset, const void* data,
-                                  iree_device_size_t data_length) {
-  IREE_ASSIGN_OR_RETURN(
-      auto mapping, MapMemory<uint8_t>(IREE_HAL_MEMORY_ACCESS_DISCARD_WRITE, target_offset, data_length));
-  std::memcpy(mapping.mutable_data(), data, mapping.byte_length());
-  return OkStatus();
-}
-
-Status MetalBuffer::CopyDataImpl(iree_device_size_t target_offset, Buffer* source_buffer,
-                                 iree_device_size_t source_offset, iree_device_size_t data_length) {
-  // This is pretty terrible. Let's not do this.
-  // TODO(benvanik): a way for allocators to indicate transfer compat.
-  IREE_ASSIGN_OR_RETURN(auto source_mapping, source_buffer->MapMemory<uint8_t>(
-                                                 IREE_HAL_MEMORY_ACCESS_READ, source_offset, data_length));
-  IREE_CHECK_EQ(data_length, source_mapping.size());
-  IREE_ASSIGN_OR_RETURN(auto target_mapping, MapMemory<uint8_t>(IREE_HAL_MEMORY_ACCESS_DISCARD_WRITE,
-                                                                target_offset, data_length));
-  IREE_CHECK_EQ(data_length, target_mapping.size());
-  std::memcpy(target_mapping.mutable_data(), source_mapping.data(), data_length);
-  return OkStatus();
-}
-
-Status MetalBuffer::MapMemoryImpl(MappingMode mapping_mode, iree_hal_memory_access_t memory_access,
-                                  iree_device_size_t local_byte_offset, iree_device_size_t local_byte_length,
-                                  void** out_data) {
-  uint8_t* data_ptr = reinterpret_cast<uint8_t*>([metal_handle_ contents]);
-  *out_data = data_ptr + local_byte_offset;
-
-  // If we mapped for discard scribble over the bytes. This is not a mandated
-  // behavior but it will make debugging issues easier. Alternatively for
-  // heap buffers we could reallocate them such that ASAN yells, but that
-  // would only work if the entire buffer was discarded.
-#ifndef NDEBUG
-  if (iree_any_bit_set(memory_access, IREE_HAL_MEMORY_ACCESS_DISCARD)) {
-    std::memset(data_ptr + local_byte_offset, 0xCD, local_byte_length);
-  }
-#endif  // !NDEBUG
-
-  if (requires_autosync()) {
-    IREE_RETURN_IF_ERROR(InvalidateMappedMemoryImpl(local_byte_offset, local_byte_length));
-  }
-
-  return OkStatus();
-}
-
-Status MetalBuffer::UnmapMemoryImpl(iree_device_size_t local_byte_offset,
-                                    iree_device_size_t local_byte_length, void* data) {
-  if (requires_autosync()) {
-    IREE_RETURN_IF_ERROR(FlushMappedMemoryImpl(local_byte_offset, local_byte_length));
-  }
-
-  return OkStatus();
-}
-
-Status MetalBuffer::InvalidateMappedMemoryImpl(iree_device_size_t local_byte_offset,
-                                               iree_device_size_t local_byte_length) {
-#ifdef IREE_PLATFORM_MACOS
-  // The following is only necessary for MTLStorageManaged.
-  if (metal_handle_.storageMode == MTLStorageModeManaged) {
-    @autoreleasepool {
-      id<MTLCommandBuffer> command_buffer =
-          [metal_transfer_queue_ commandBufferWithUnretainedReferences];
-
-      id<MTLBlitCommandEncoder> blit_encoder = [command_buffer blitCommandEncoder];
-      [blit_encoder synchronizeResource:metal_handle_];
-      [blit_encoder endEncoding];
-
-      [command_buffer commit];
-      [command_buffer waitUntilCompleted];
-    }
-  }
-#endif
-
-  return OkStatus();
-}
-
-Status MetalBuffer::FlushMappedMemoryImpl(iree_device_size_t local_byte_offset,
-                                          iree_device_size_t local_byte_length) {
-#ifdef IREE_PLATFORM_MACOS
-  // The following is only necessary for MTLStorageManaged.
-  if (metal_handle_.storageMode == MTLStorageModeManaged) {
-    [metal_handle_ didModifyRange:NSMakeRange(local_byte_offset, local_byte_length)];
-  }
-#endif
-
-  return OkStatus();
-}
-
-bool MetalBuffer::requires_autosync() const {
-  // We only need to perform "automatic" resource synchronization if it's MTLStorageModeManaged,
-  // which is only available on macOS.
-#ifdef IREE_PLATFORM_MACOS
-  return iree_all_bits_set(memory_type(), IREE_HAL_MEMORY_TYPE_HOST_COHERENT) &&
-         metal_handle_.storageMode == MTLStorageModeManaged;
-#else
-  return false;
-#endif
-}
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
diff --git a/iree/hal/metal/metal_capture_manager.h b/iree/hal/metal/metal_capture_manager.h
deleted file mode 100644
index 22d17dd..0000000
--- a/iree/hal/metal/metal_capture_manager.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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_METAL_METAL_CAPTURE_MANAGER_H_
-#define IREE_HAL_METAL_METAL_CAPTURE_MANAGER_H_
-
-#include <memory>
-
-#import <Metal/Metal.h>
-
-#include "iree/base/status.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-// A DebugCaptureManager implementation for Metal that directly wraps a
-// MTLCaptureManager.
-class MetalCaptureManager final : public DebugCaptureManager {
- public:
-  // Creates a capture manager that captures Metal commands to the given |capture_file| if not
-  // empty. Capture to Xcode otherwise.
-  static StatusOr<std::unique_ptr<MetalCaptureManager>> Create(const std::string& capture_file);
-  ~MetalCaptureManager() override;
-
-  Status Connect() override;
-
-  void Disconnect() override;
-
-  bool is_connected() const override;
-
-  void SetCaptureObject(id object);
-
-  void StartCapture() override;
-
-  void StopCapture() override;
-
-  bool is_capturing() const override;
-
- private:
-  explicit MetalCaptureManager(NSURL* capture_file);
-
-  MTLCaptureManager* metal_handle_ = nil;
-  // The path for storing the .gputrace file. Empty means capturing to Xcode.
-  NSURL* capture_file_ = nil;
-  id capture_object_ = nil;
-};
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
-
-#endif  // IREE_HAL_METAL_METAL_CAPTURE_MANAGER_H_
diff --git a/iree/hal/metal/metal_capture_manager.mm b/iree/hal/metal/metal_capture_manager.mm
deleted file mode 100644
index 4437951..0000000
--- a/iree/hal/metal/metal_capture_manager.mm
+++ /dev/null
@@ -1,128 +0,0 @@
-// 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/metal/metal_capture_manager.h"
-
-#include <string>
-
-#include "absl/memory/memory.h"
-#include "iree/base/file_io.h"
-#include "iree/base/logging.h"
-#include "iree/base/tracing.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-// static
-StatusOr<std::unique_ptr<MetalCaptureManager>> MetalCaptureManager::Create(
-    const std::string& capture_file) {
-  IREE_TRACE_SCOPE0("MetalCaptureManager::Create");
-  @autoreleasepool {
-    NSURL* capture_url = nil;
-    if (!capture_file.empty()) {
-      NSString* ns_string = [NSString stringWithCString:capture_file.c_str()
-                                               encoding:[NSString defaultCStringEncoding]];
-      NSString* capture_path = ns_string.stringByStandardizingPath;
-      capture_url = [[NSURL fileURLWithPath:capture_path isDirectory:false] retain];
-    }
-    return absl::WrapUnique(new MetalCaptureManager(capture_url));
-  }
-}
-
-MetalCaptureManager::MetalCaptureManager(NSURL* capture_file) : capture_file_(capture_file) {}
-
-MetalCaptureManager::~MetalCaptureManager() {
-  IREE_TRACE_SCOPE0("MetalCaptureManager::dtor");
-  Disconnect();
-  if (capture_file_) [capture_file_ release];
-}
-
-Status MetalCaptureManager::Connect() {
-  IREE_TRACE_SCOPE0("MetalCaptureManager::Connect");
-
-  if (metal_handle_) return OkStatus();
-
-  @autoreleasepool {
-    metal_handle_ = [[MTLCaptureManager sharedCaptureManager] retain];
-
-    if (capture_file_ &&
-        [metal_handle_ supportsDestination:MTLCaptureDestinationGPUTraceDocument]) {
-      IREE_LOG(INFO) << "Connected to shared Metal capture manager; writing capture to "
-                     << std::string([capture_file_.absoluteString UTF8String]);
-    } else {
-      IREE_LOG(INFO) << "Connected to shared Metal capture manager; capturing to Xcode";
-    }
-  }
-
-  return OkStatus();
-}
-
-void MetalCaptureManager::Disconnect() {
-  IREE_TRACE_SCOPE0("MetalCaptureManager::Disconnect");
-
-  if (!metal_handle_) return;
-
-  if (is_capturing()) StopCapture();
-
-  [metal_handle_ release];
-  metal_handle_ = nil;
-}
-
-bool MetalCaptureManager::is_connected() const { return metal_handle_ != nil; }
-
-void MetalCaptureManager::SetCaptureObject(id object) { capture_object_ = object; }
-
-void MetalCaptureManager::StartCapture() {
-  IREE_TRACE_SCOPE0("MetalCaptureManager::StartCapture");
-
-  IREE_CHECK(is_connected()) << "Can't start capture when not connected";
-  IREE_CHECK(!is_capturing()) << "Capture is already started";
-  IREE_CHECK(capture_object_) << "Must set capture object before starting";
-
-  IREE_LOG(INFO) << "Starting Metal capture";
-  @autoreleasepool {
-    MTLCaptureDescriptor* capture_descriptor = [[[MTLCaptureDescriptor alloc] init] autorelease];
-    capture_descriptor.captureObject = capture_object_;
-    if (capture_file_) {
-      capture_descriptor.destination = MTLCaptureDestinationGPUTraceDocument;
-      capture_descriptor.outputURL = capture_file_;
-    } else {
-      capture_descriptor.destination = MTLCaptureDestinationDeveloperTools;
-    }
-
-    NSError* error;
-    if (![metal_handle_ startCaptureWithDescriptor:capture_descriptor error:&error]) {
-      NSLog(@"Failed to start capture, error %@", error);
-    }
-  }
-}
-
-void MetalCaptureManager::StopCapture() {
-  IREE_TRACE_SCOPE0("MetalCaptureManager::StopCapture");
-
-  IREE_CHECK(is_capturing()) << "Can't stop capture when not capturing";
-
-  IREE_LOG(INFO) << "Ending Metal capture";
-  [metal_handle_ stopCapture];
-}
-
-bool MetalCaptureManager::is_capturing() const {
-  if (!is_connected()) return false;
-  return metal_handle_.isCapturing;
-}
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
diff --git a/iree/hal/metal/metal_command_buffer.h b/iree/hal/metal/metal_command_buffer.h
deleted file mode 100644
index d9b4321..0000000
--- a/iree/hal/metal/metal_command_buffer.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// 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_METAL_METAL_COMMAND_BUFFER_H_
-#define IREE_HAL_METAL_METAL_COMMAND_BUFFER_H_
-
-#import <Metal/Metal.h>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/container/inlined_vector.h"
-#include "iree/hal/metal/metal_buffer.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-// A command buffer implementation for Metal that directly wraps a
-// MTLCommandBuffer.
-//
-// Objects of this class are not expected to be accessed by multiple threads.
-class MetalCommandBuffer final : public CommandBuffer {
- public:
-  static StatusOr<ref_ptr<CommandBuffer>> Create(
-      iree_hal_command_buffer_mode_t mode,
-      iree_hal_command_category_t command_categories,
-      id<MTLCommandBuffer> command_buffer);
-  ~MetalCommandBuffer() override;
-
-  id<MTLCommandBuffer> handle() const { return metal_handle_; }
-
-  Status Begin() override;
-  Status End() override;
-
-  Status ExecutionBarrier(
-      iree_hal_execution_stage_t source_stage_mask,
-      iree_hal_execution_stage_t target_stage_mask,
-      absl::Span<const iree_hal_memory_barrier_t> memory_barriers,
-      absl::Span<const iree_hal_buffer_barrier_t> buffer_barriers) override;
-
-  Status SignalEvent(iree_hal_event_t* event,
-                     iree_hal_execution_stage_t source_stage_mask) override;
-  Status ResetEvent(iree_hal_event_t* event,
-                    iree_hal_execution_stage_t source_stage_mask) override;
-  Status WaitEvents(
-      absl::Span<iree_hal_event_t*> events,
-      iree_hal_execution_stage_t source_stage_mask,
-      iree_hal_execution_stage_t target_stage_mask,
-      absl::Span<const iree_hal_memory_barrier_t> memory_barriers,
-      absl::Span<const iree_hal_buffer_barrier_t> buffer_barriers) override;
-
-  Status FillBuffer(iree_hal_buffer_t* target_buffer,
-                    iree_device_size_t target_offset, iree_device_size_t length,
-                    const void* pattern, size_t pattern_length) override;
-  Status DiscardBuffer(iree_hal_buffer_t* buffer) override;
-  Status UpdateBuffer(const void* source_buffer,
-                      iree_device_size_t source_offset,
-                      iree_hal_buffer_t* target_buffer,
-                      iree_device_size_t target_offset,
-                      iree_device_size_t length) override;
-  Status CopyBuffer(iree_hal_buffer_t* source_buffer,
-                    iree_device_size_t source_offset,
-                    iree_hal_buffer_t* target_buffer,
-                    iree_device_size_t target_offset,
-                    iree_device_size_t length) override;
-
-  Status PushConstants(iree_hal_executable_layout_t* executable_layout,
-                       size_t offset,
-                       absl::Span<const uint32_t> values) override;
-
-  Status PushDescriptorSet(
-      iree_hal_executable_layout_t* executable_layout, uint32_t set,
-      absl::Span<const iree_hal_descriptor_set_binding_t> bindings) override;
-  Status BindDescriptorSet(
-      iree_hal_executable_layout_t* executable_layout, uint32_t set,
-      iree_hal_descriptor_set_t* descriptor_set,
-      absl::Span<const iree_device_size_t> dynamic_offsets) override;
-
-  Status Dispatch(iree_hal_executable_t* executable, int32_t entry_point,
-                  std::array<uint32_t, 3> workgroups) override;
-  Status DispatchIndirect(iree_hal_executable_t* executable,
-                          int32_t entry_point,
-                          iree_hal_buffer_t* workgroups_buffer,
-                          iree_device_size_t workgroups_offset) override;
-
- private:
-  // A struct containing all resources states of the current pipeline.
-  struct PipelineStateObject {
-    struct PushState {
-      absl::InlinedVector<iree_hal_descriptor_set_binding_t, 8>
-          resource_bindings;
-    };
-    // Map from set number to push descriptor states
-    absl::flat_hash_map<int32_t, PushState> push_states;
-
-    struct BindState {
-      DescriptorSet* descriptor_set;
-    };
-    // Map from set number to bind descriptor states
-    absl::flat_hash_map<int32_t, BindState> bind_states;
-
-    struct ConstantState {
-      absl::InlinedVector<uint32_t, 16> values;
-    };
-    // Map from set number to push constant states
-    absl::flat_hash_map<uint32_t, ConstantState> constant_states;
-  };
-
-  MetalCommandBuffer(iree_hal_command_buffer_mode_t mode,
-                     iree_hal_command_category_t command_categories,
-                     id<MTLCommandBuffer> command_buffer);
-
-  // Gets or begins an active MTLBlitCommandEncoder. This also ends all previous
-  // encoded compute commands if any.
-  id<MTLBlitCommandEncoder> GetOrBeginBlitEncoder();
-  void EndBlitEncoder();
-
-  // Gets or begins a new MTLComputeCommandEncoder. This also ends all previous
-  // encoded blit commands if any.
-  id<MTLComputeCommandEncoder> GetOrBeginComputeEncoder();
-  void EndComputeEncoder();
-
- private:
-  bool is_recording_ = false;
-  id<MTLCommandBuffer> metal_handle_;
-
-  id<MTLComputeCommandEncoder> current_compute_encoder_ = nil;
-  id<MTLBlitCommandEncoder> current_blit_encoder_ = nil;
-
-  absl::flat_hash_map<iree_hal_executable_layout_t*, PipelineStateObject>
-      pipeline_state_objects_;
-};
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
-
-#endif  // IREE_HAL_METAL_METAL_COMMAND_BUFFER_H_
diff --git a/iree/hal/metal/metal_command_buffer.mm b/iree/hal/metal/metal_command_buffer.mm
deleted file mode 100644
index 46607f6..0000000
--- a/iree/hal/metal/metal_command_buffer.mm
+++ /dev/null
@@ -1,380 +0,0 @@
-// 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/metal/metal_command_buffer.h"
-
-#include "iree/base/logging.h"
-#include "iree/base/status.h"
-#include "iree/base/tracing.h"
-#include "iree/hal/metal/metal_kernel_library.h"
-#include "iree/hal/metal/metal_pipeline_argument_buffer.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-namespace {
-
-MTLResourceUsage ConvertResourceUsage(iree_hal_memory_access_t memory_access) {
-  MTLResourceUsage usage = 0;
-  if (iree_all_bits_set(memory_access, IREE_HAL_MEMORY_ACCESS_READ)) usage |= MTLResourceUsageRead;
-  if (iree_all_bits_set(memory_access, IREE_HAL_MEMORY_ACCESS_WRITE)) usage |= MTLResourceUsageWrite;
-  return usage;
-}
-
-}  // namespace
-
-// static
-StatusOr<ref_ptr<CommandBuffer>> MetalCommandBuffer::Create(
-    iree_hal_command_buffer_mode_t mode, iree_hal_command_category_t command_categories,
-    id<MTLCommandBuffer> command_buffer) {
-  return assign_ref(new MetalCommandBuffer(mode, command_categories, command_buffer));
-}
-
-MetalCommandBuffer::MetalCommandBuffer(iree_hal_command_buffer_mode_t mode,
-                                       iree_hal_command_category_t command_categories,
-                                       id<MTLCommandBuffer> command_buffer)
-    : CommandBuffer(mode, command_categories), metal_handle_([command_buffer retain]) {
-  metal_handle_.label = @"IREE MetalCommandBuffer";
-}
-
-MetalCommandBuffer::~MetalCommandBuffer() {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::dtor");
-  [metal_handle_ release];
-}
-
-id<MTLBlitCommandEncoder> MetalCommandBuffer::GetOrBeginBlitEncoder() {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::GetOrBeginBlitEncoder");
-
-  if (current_compute_encoder_) EndComputeEncoder();
-
-  @autoreleasepool {
-    if (!current_blit_encoder_) {
-      current_blit_encoder_ = [[metal_handle_ blitCommandEncoder] retain];
-    }
-  }
-
-  return current_blit_encoder_;
-}
-
-void MetalCommandBuffer::EndBlitEncoder() {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::EndBlitEncoder");
-  if (current_blit_encoder_) {
-    [current_blit_encoder_ endEncoding];
-    [current_blit_encoder_ release];
-    current_blit_encoder_ = nil;
-  }
-}
-
-id<MTLComputeCommandEncoder> MetalCommandBuffer::GetOrBeginComputeEncoder() {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::GetOrBeginComputeEncoder");
-
-  if (current_blit_encoder_) EndBlitEncoder();
-
-  @autoreleasepool {
-    if (!current_compute_encoder_) {
-      current_compute_encoder_ = [[metal_handle_ computeCommandEncoder] retain];
-    }
-  }
-
-  return current_compute_encoder_;
-}
-
-void MetalCommandBuffer::EndComputeEncoder() {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::EndComputeEncoder");
-  if (current_compute_encoder_) {
-    [current_compute_encoder_ endEncoding];
-    [current_compute_encoder_ release];
-    current_compute_encoder_ = nil;
-  }
-}
-
-Status MetalCommandBuffer::Begin() {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::Begin");
-  is_recording_ = true;
-  return OkStatus();
-}
-
-Status MetalCommandBuffer::End() {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::End");
-  EndBlitEncoder();
-  EndComputeEncoder();
-  is_recording_ = false;
-  return OkStatus();
-}
-
-Status MetalCommandBuffer::ExecutionBarrier(iree_hal_execution_stage_t source_stage_mask,
-                                            iree_hal_execution_stage_t target_stage_mask,
-                                            absl::Span<const iree_hal_memory_barrier_t> memory_barriers,
-                                            absl::Span<const iree_hal_buffer_barrier_t> buffer_barriers) {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::ExecutionBarrier");
-
-  if (iree_all_bits_set(source_stage_mask, IREE_HAL_EXECUTION_STAGE_HOST) ||
-      iree_all_bits_set(target_stage_mask, IREE_HAL_EXECUTION_STAGE_HOST)) {
-    return UnimplementedErrorBuilder(IREE_LOC)
-           << "MetalCommandBuffer::ExecutionBarrier with host bit set";
-  }
-
-  // If there is a memory barrier specified, we have to place a catch-all barrier for all buffers.
-  // Metal does not provide a more fine-grained control here. But we do have the option to specify a
-  // list of buffers to synchronize if only buffer barriers are specified.
-  if (!memory_barriers.empty()) {
-    [GetOrBeginComputeEncoder() memoryBarrierWithScope:MTLBarrierScopeBuffers];
-  } else if (!buffer_barriers.empty()) {
-    std::vector<id<MTLResource>> buffers;
-    buffers.reserve(buffer_barriers.size());
-    for (const auto& barrier : buffer_barriers) {
-      buffers.push_back(static_cast<MetalBuffer*>(barrier.buffer)->handle());
-    }
-    [GetOrBeginComputeEncoder() memoryBarrierWithResources:buffers.data() count:buffers.size()];
-  }
-
-  return OkStatus();
-}
-
-Status MetalCommandBuffer::SignalEvent(iree_hal_event_t* event, iree_hal_execution_stage_t source_stage_mask) {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::SignalEvent");
-  return UnimplementedErrorBuilder(IREE_LOC) << "MetalCommandBuffer::SignalEvent";
-}
-
-Status MetalCommandBuffer::ResetEvent(iree_hal_event_t* event, iree_hal_execution_stage_t source_stage_mask) {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::ResetEvent");
-  return UnimplementedErrorBuilder(IREE_LOC) << "MetalCommandBuffer::ResetEvent";
-}
-
-Status MetalCommandBuffer::WaitEvents(absl::Span<iree_hal_event_t*> events,
-                                      iree_hal_execution_stage_t source_stage_mask,
-                                      iree_hal_execution_stage_t target_stage_mask,
-                                      absl::Span<const iree_hal_memory_barrier_t> memory_barriers,
-                                      absl::Span<const iree_hal_buffer_barrier_t> buffer_barriers) {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::WaitEvents");
-  return UnimplementedErrorBuilder(IREE_LOC) << "MetalCommandBuffer::WaitEvents";
-}
-
-Status MetalCommandBuffer::FillBuffer(iree_hal_buffer_t* target_buffer, iree_device_size_t target_offset,
-                                      iree_device_size_t length, const void* pattern,
-                                      size_t pattern_length) {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::FillBuffer");
-  id<MTLBuffer> target_device_buffer = iree_hal_metal_buffer_handle(iree_hal_buffer_allocated_buffer(target_buffer));
-
-  target_offset += iree_hal_buffer_byte_offset(target_buffer);
-
-  // Per the spec for fillBuffer:range:value: "The alignment and length of the range must both be a
-  // multiple of 4 bytes in macOS, and 1 byte in iOS and tvOS." Although iOS/tvOS is more relaxed on
-  // this front, we still require 4-byte alignment for uniformity across IREE.
-  if (target_offset % 4 != 0) {
-    return UnimplementedErrorBuilder(IREE_LOC)
-           << "MetalCommandBuffer::FillBuffer with offset that is not a multiple of 4 bytes";
-  }
-
-  // Note that fillBuffer:range:value: only accepts a single byte as the pattern but FillBuffer
-  // can accept 1/2/4 bytes. If the pattern itself contains repeated bytes, we can call into
-  // fillBuffer:range:value:. Otherwise we may need to find another way. Just implement the case
-  // where we have a single byte to fill for now.
-  if (pattern_length != 1) {
-    return UnimplementedErrorBuilder(IREE_LOC)
-           << "MetalCommandBuffer::FillBuffer with non-1-byte pattern";
-  }
-  uint8_t byte_pattern = *reinterpret_cast<const uint8_t*>(pattern);
-
-  [GetOrBeginBlitEncoder() fillBuffer:target_device_buffer->handle()
-                                range:NSMakeRange(target_offset, length)
-                                value:byte_pattern];
-
-  return OkStatus();
-}
-
-Status MetalCommandBuffer::DiscardBuffer(iree_hal_buffer_t* buffer) {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::DiscardBuffer");
-  // This is a hint. Nothing to do for Metal.
-  return OkStatus();
-}
-
-Status MetalCommandBuffer::UpdateBuffer(const void* source_buffer, iree_device_size_t source_offset,
-                                        iree_hal_buffer_t* target_buffer, iree_device_size_t target_offset,
-                                        iree_device_size_t length) {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::UpdateBuffer");
-  return UnimplementedErrorBuilder(IREE_LOC) << "MetalCommandBuffer::UpdateBuffer";
-}
-
-Status MetalCommandBuffer::CopyBuffer(iree_hal_buffer_t* source_buffer, iree_device_size_t source_offset,
-                                      iree_hal_buffer_t* target_buffer, iree_device_size_t target_offset,
-                                      iree_device_size_t length) {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::CopyBuffer");
-
-  id<MTLBuffer> source_device_buffer = iree_hal_metal_buffer_handle(iree_hal_buffer_allocated_buffer(source_buffer));
-  id<MTLBuffer> target_device_buffer = iree_hal_metal_buffer_handle(iree_hal_buffer_allocated_buffer(target_buffer));
-
-  source_offset += iree_hal_buffer_byte_offset(source_buffer);
-  target_offset += iree_hal_buffer_byte_offset(target_buffer);
-
-  // Per the spec for copyFromBuffer:sourceOffset:toBuffer:destinationOffset:size, the source/target
-  // offset must be a multiple of 4 bytes in macOS, and 1 byte in iOS and tvOS. Although iOS/tvOS
-  // is more relaxed on this front, we still require 4-byte alignment for uniformity across IREE.
-  if (source_offset % 4 != 0 || target_offset % 4 != 0) {
-    return UnimplementedErrorBuilder(IREE_LOC)
-           << "MetalCommandBuffer::CopyBuffer with offset that is not a multiple of 4 bytes";
-  }
-
-  [GetOrBeginBlitEncoder() copyFromBuffer:source_device_buffer->handle()
-                             sourceOffset:source_offset
-                                 toBuffer:target_device_buffer->handle()
-                        destinationOffset:target_offset
-                                     size:length];
-
-  return OkStatus();
-}
-
-Status MetalCommandBuffer::PushConstants(iree_hal_executable_layout_t* executable_layout, size_t offset,
-                                         absl::Span<const uint32_t> values) {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::PushConstants");
-  return UnimplementedErrorBuilder(IREE_LOC) << "MetalCommandBuffer::PushConstants";
-}
-
-Status MetalCommandBuffer::PushDescriptorSet(iree_hal_executable_layout_t* executable_layout, int32_t set,
-                                             absl::Span<const iree_hal_descriptor_set_binding_t> bindings) {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::PushDescriptorSet");
-  if (set != 0) {
-    return UnimplementedErrorBuilder(IREE_LOC)
-           << "MetalCommandBuffer::PushDescriptorSet with set number > 0";
-  }
-  auto& push_state = pipeline_state_objects_[executable_layout].push_states[set];
-  push_state.resource_bindings.assign(bindings.begin(), bindings.end());
-  return OkStatus();
-}
-
-Status MetalCommandBuffer::BindDescriptorSet(iree_hal_executable_layout_t* executable_layout, int32_t set,
-                                             iree_hal_descriptor_set_t* descriptor_set,
-                                             absl::Span<const iree_device_size_t> dynamic_offsets) {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::BindDescriptorSet");
-  if (set != 0) {
-    return UnimplementedErrorBuilder(IREE_LOC)
-           << "MetalCommandBuffer::BindDescriptorSet with set number > 0";
-  }
-  if (!dynamic_offsets.empty()) {
-    return UnimplementedErrorBuilder(IREE_LOC)
-           << "MetalCommandBuffer::BindDescriptorSet with dynamic offsets";
-  }
-  pipeline_state_objects_[executable_layout].bind_states[set].descriptor_set = descriptor_set;
-  return OkStatus();
-}
-
-Status MetalCommandBuffer::Dispatch(iree_hal_executable_t* executable, int32_t entry_point,
-                                    std::array<uint32_t, 3> workgroups) {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::Dispatch");
-  IREE_DVLOG(2) << "MetalCommandBuffer::Dispatch";
-
-  auto* kernel_library = static_cast<MetalKernelLibrary*>(executable);
-  IREE_ASSIGN_OR_RETURN(auto metal_kernel, kernel_library->GetKernelForEntryPoint(entry_point));
-  IREE_ASSIGN_OR_RETURN(auto metal_pso, kernel_library->GetPipelineStateForEntryPoint(entry_point));
-  IREE_ASSIGN_OR_RETURN(auto workgroup_size,
-                        kernel_library->GetThreadgroupSizeForEntryPoint(entry_point));
-
-  id<MTLComputeCommandEncoder> compute_encoder = GetOrBeginComputeEncoder();
-  [compute_encoder setComputePipelineState:metal_pso];
-
-  // TODO(antiagainst): only update the PSO for the current executable.
-  for (const auto& pso_kv : pipeline_state_objects_) {
-    const auto* pipeline_layout = static_cast<MetalPipelineArgumentBufferLayout*>(pso_kv.first);
-
-    const auto& pso = pso_kv.second;
-    if (pso.push_states.size() > 1) {
-      return UnimplementedErrorBuilder(IREE_LOC)
-             << "MetalCommandBuffer::Dispatch with more than one push descriptor sets";
-    }
-    if (!pso.bind_states.empty()) {
-      return UnimplementedErrorBuilder(IREE_LOC)
-             << "MetalCommandBuffer::Dispatch with bound descriptor sets";
-    }
-    if (!pso.constant_states.empty()) {
-      return UnimplementedErrorBuilder(IREE_LOC)
-             << "MetalCommandBuffer::Dispatch with push constants";
-    }
-
-    IREE_DVLOG(3) << "Encoding push descriptors..";
-    for (const auto& push_kv : pso.push_states) {
-      uint32_t set_number = push_kv.first;
-      const PipelineStateObject::PushState& push_state = push_kv.second;
-      IREE_DVLOG(3) << " For set #" << set_number;
-
-      id<MTLArgumentEncoder> argument_encoder =
-          [metal_kernel newArgumentEncoderWithBufferIndex:set_number];  // retained
-      argument_encoder.label = @"IREE MetalCommandBuffer::Dispatch ArgumentEncoder";
-      if (!argument_encoder) {
-        return InvalidArgumentErrorBuilder(IREE_LOC)
-               << "Buffer index #" << set_number << " is not an argument buffer";
-      }
-
-      __block id<MTLBuffer> argument_buffer =
-          [metal_handle_.device newBufferWithLength:argument_encoder.encodedLength
-                                            options:MTLResourceStorageModeShared];  // retained
-      argument_encoder.label = @"IREE MetalCommandBuffer::Dispatch ArgumentBuffer";
-      if (!argument_buffer) {
-        return InternalErrorBuilder(IREE_LOC)
-               << "Failed to create argument buffer with length=" << argument_encoder.encodedLength;
-      }
-      [metal_handle_ addCompletedHandler:^(id<MTLCommandBuffer>) {
-        [argument_buffer release];
-        [argument_encoder release];
-      }];
-
-      [argument_encoder setArgumentBuffer:argument_buffer offset:0];
-
-      for (const auto& resource_binding : push_state.resource_bindings) {
-
-        if (resource_binding.length != IREE_WHOLE_BUFFER &&
-            resource_binding.length != resource_binding.buffer->allocation_size()) {
-          return UnimplementedErrorBuilder(IREE_LOC)
-                 << "MetalCommandBuffer::Dispatch with sub-buffer";
-        }
-
-        [argument_encoder setBuffer:iree_hal_metal_buffer_handle(iree_hal_buffer_allocated_buffer(resource_binding.buffer))
-                             offset:resource_binding.offset
-                            atIndex:resource_binding.binding];
-
-        const auto* set_layout = pipeline_layout->set_layouts()[set_number];
-        const auto* layout_binding = set_layout->GetBindingForIndex(resource_binding.binding);
-        if (!layout_binding) {
-          return InvalidArgumentErrorBuilder(IREE_LOC)
-                 << "Cannot find binding #" << resource_binding.binding
-                 << " in argument buffer layout";
-        }
-        [compute_encoder useResource:buffer->handle()
-                               usage:ConvertResourceUsage(layout_binding->access)];
-      }
-
-      [compute_encoder setBuffer:argument_buffer offset:0 atIndex:set_number];
-    }
-  }
-
-  IREE_DVLOG(2) << "Dispatch workgroup count: (" << workgroups[0] << ", " << workgroups[1] << ", "
-                << workgroups[2] << "), workgroup size: (" << workgroup_size.x << ", "
-                << workgroup_size.y << ", " << workgroup_size.z << ")";
-  [compute_encoder
-       dispatchThreadgroups:MTLSizeMake(workgroups[0], workgroups[1], workgroups[2])
-      threadsPerThreadgroup:MTLSizeMake(workgroup_size.x, workgroup_size.y, workgroup_size.z)];
-
-  return OkStatus();
-}
-
-Status MetalCommandBuffer::DispatchIndirect(iree_hal_executable_t* executable, int32_t entry_point,
-                                            iree_hal_buffer_t* workgroups_buffer,
-                                            iree_device_size_t workgroups_offset) {
-  IREE_TRACE_SCOPE0("MetalCommandBuffer::DispatchIndirect");
-  return UnimplementedErrorBuilder(IREE_LOC) << "MetalCommandBuffer::DispatchIndirect";
-}
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
diff --git a/iree/hal/metal/metal_command_queue.h b/iree/hal/metal/metal_command_queue.h
deleted file mode 100644
index ef4d64c..0000000
--- a/iree/hal/metal/metal_command_queue.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// 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_METAL_METAL_COMMAND_QUEUE_H_
-#define IREE_HAL_METAL_METAL_COMMAND_QUEUE_H_
-
-#import <Metal/Metal.h>
-
-#include "iree/base/arena.h"
-#include "iree/base/status.h"
-#include "iree/base/time.h"
-#include "iree/hal/api.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-// A command queue implementation for Metal that directly wraps a
-// MTLCommandQueue.
-//
-// Thread-safe.
-class MetalCommandQueue final : public CommandQueue {
- public:
-  MetalCommandQueue(std::string name,
-                    iree_hal_command_category_t supported_categories,
-                    id<MTLCommandQueue> queue);
-  ~MetalCommandQueue() override;
-
-  id<MTLCommandQueue> handle() const { return metal_handle_; }
-
-  Status Submit(absl::Span<const SubmissionBatch> batches) override;
-
-  Status WaitIdle(Time deadline_ns) override;
-
- private:
-  id<MTLCommandQueue> metal_handle_;
-};
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
-
-#endif  // IREE_HAL_METAL_METAL_COMMAND_QUEUE_H_
diff --git a/iree/hal/metal/metal_command_queue.mm b/iree/hal/metal/metal_command_queue.mm
deleted file mode 100644
index eaf29fb..0000000
--- a/iree/hal/metal/metal_command_queue.mm
+++ /dev/null
@@ -1,100 +0,0 @@
-// 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/metal/metal_command_queue.h"
-
-#include "iree/base/status.h"
-#include "iree/base/tracing.h"
-#include "iree/hal/metal/dispatch_time_util.h"
-#include "iree/hal/metal/metal_command_buffer.h"
-#include "iree/hal/metal/metal_shared_event.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-MetalCommandQueue::MetalCommandQueue(std::string name, iree_hal_command_category_t supported_categories,
-                                     id<MTLCommandQueue> queue)
-    : CommandQueue(std::move(name), supported_categories), metal_handle_([queue retain]) {
-  metal_handle_.label = @"IREE MetalQueue";
-}
-
-MetalCommandQueue::~MetalCommandQueue() { [metal_handle_ release]; }
-
-Status MetalCommandQueue::Submit(absl::Span<const SubmissionBatch> batches) {
-  IREE_TRACE_SCOPE0("MetalCommandQueue::Submit");
-  for (const auto& batch : batches) {
-    @autoreleasepool {
-      // Wait for semaphores blocking this batch.
-      if (!batch.wait_semaphores.empty()) {
-        id<MTLCommandBuffer> wait_buffer = [metal_handle_ commandBufferWithUnretainedReferences];
-        wait_buffer.label = @"IREE MetalCommandQueue::Submit Wait Semaphore CommandBuffer";
-
-        for (const auto& semaphore : batch.wait_semaphores) {
-          auto* event = static_cast<MetalSharedEvent*>(semaphore.semaphore);
-          [wait_buffer encodeWaitForEvent:event->handle() value:semaphore.value];
-        }
-        [wait_buffer commit];
-      }
-
-      // Commit command buffers to the queue.
-      for (const auto* command_buffer : batch.command_buffers) {
-        const auto* cmdbuf = static_cast<const MetalCommandBuffer*>(command_buffer);
-        [cmdbuf->handle() commit];
-      }
-
-      // Signal semaphores advanced by this batch.
-      if (!batch.signal_semaphores.empty()) {
-        id<MTLCommandBuffer> signal_buffer = [metal_handle_ commandBufferWithUnretainedReferences];
-        signal_buffer.label = @"IREE MetalCommandQueue::Submit Signal Semaphore CommandBuffer";
-
-        for (const auto& semaphore : batch.signal_semaphores) {
-          auto* event = static_cast<MetalSharedEvent*>(semaphore.semaphore);
-          [signal_buffer encodeSignalEvent:event->handle() value:semaphore.value];
-        }
-        [signal_buffer commit];
-      }
-    }
-  }
-  return OkStatus();
-}
-
-Status MetalCommandQueue::WaitIdle(Time deadline_ns) {
-  IREE_TRACE_SCOPE0("MetalCommandQueue::WaitIdle");
-
-  dispatch_time_t timeout = DeadlineToDispatchTime(deadline_ns);
-
-  // Submit an empty command buffer and wait for it to complete. That will indicate all previous
-  // work has completed too.
-  @autoreleasepool {
-    id<MTLCommandBuffer> comand_buffer = [metal_handle_ commandBufferWithUnretainedReferences];
-    comand_buffer.label = @"IREE MetalCommandQueue::WaitIdle Command Buffer";
-    __block dispatch_semaphore_t work_done = dispatch_semaphore_create(0);
-    [comand_buffer addCompletedHandler:^(id<MTLCommandBuffer>) {
-      dispatch_semaphore_signal(work_done);
-    }];
-    [comand_buffer commit];
-    long timed_out = dispatch_semaphore_wait(work_done, timeout);
-    dispatch_release(work_done);
-    if (timed_out) {
-      return DeadlineExceededErrorBuilder(IREE_LOC)
-             << "Deadline exceeded waiting for dispatch_semaphore_t";
-    }
-    return OkStatus();
-  }
-}
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
diff --git a/iree/hal/metal/metal_device.h b/iree/hal/metal/metal_device.h
deleted file mode 100644
index aea32ce..0000000
--- a/iree/hal/metal/metal_device.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// 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_METAL_METAL_DEVICE_H_
-#define IREE_HAL_METAL_METAL_DEVICE_H_
-
-#import <Metal/Metal.h>
-
-#include <memory>
-
-#include "absl/types/span.h"
-#include "iree/base/memory.h"
-#include "iree/hal/cc/device.h"
-#include "iree/hal/cc/driver.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-// A device implementation for Metal that directly wraps a MTLDevice.
-class MetalDevice final : public Device {
- public:
-  // Creates a device that retains the underlying Metal GPU device.
-  // The iree_hal_device_id_t in |device_info| is expected to be an
-  // id<MTLDevice>.
-  static StatusOr<ref_ptr<MetalDevice>> Create(ref_ptr<Driver> driver,
-                                               const DeviceInfo& device_info);
-
-  ~MetalDevice() override;
-
-  Allocator* allocator() const override { return allocator_.get(); }
-
-  Status CreateExecutableCache(
-      iree_string_view_t identifier,
-      iree_hal_executable_cache_t** out_executable_cache) override;
-
-  Status CreateDescriptorSetLayout(
-      iree_hal_descriptor_set_layout_usage_type_t usage_type,
-      absl::Span<const iree_hal_descriptor_set_layout_binding_t> bindings,
-      iree_hal_descriptor_set_layout_t** out_descriptor_set_layout) override;
-
-  Status CreateExecutableLayout(
-      absl::Span<iree_hal_descriptor_set_layout_t*> set_layouts,
-      size_t push_constants,
-      iree_hal_executable_layout_t** out_executable_layout) override;
-
-  Status CreateDescriptorSet(
-      iree_hal_descriptor_set_layout_t* set_layout,
-      absl::Span<const iree_hal_descriptor_set_binding_t> bindings,
-      iree_hal_descriptor_set_t** out_descriptor_set) override;
-
-  Status CreateCommandBuffer(
-      iree_hal_command_buffer_mode_t mode,
-      iree_hal_command_category_t command_categories,
-      iree_hal_command_buffer_t** out_command_buffer) override;
-
-  Status CreateEvent(iree_hal_event_t** out_event) override;
-
-  Status CreateSemaphore(uint64_t initial_value,
-                         iree_hal_semaphore_t** out_semaphore) override;
-  Status WaitAllSemaphores(const iree_hal_semaphore_list_t* semaphore_list,
-                           iree_time_t deadline_ns) override;
-  StatusOr<int> WaitAnySemaphore(
-      const iree_hal_semaphore_list_t* semaphore_list,
-      iree_time_t deadline_ns) override;
-
-  Status WaitIdle(iree_time_t deadline_ns) override;
-
- private:
-  MetalDevice(ref_ptr<Driver> driver, const DeviceInfo& device_info);
-
-  ref_ptr<Driver> driver_;
-  id<MTLDevice> metal_handle_;
-
-  std::unique_ptr<Allocator> allocator_;
-
-  // Metal does not have clear graphics/dispatch/transfer queue distinction like
-  // Vulkan; one just use the same newCommandQueue() API call on MTLDevice to
-  // get command queues. Command encoders differ for different categories of
-  // commands though. We expose one queue here for everything. This can be
-  // changed later if more queues prove to be useful.
-
-  std::unique_ptr<CommandQueue> command_queue_;
-  mutable CommandQueue* common_queue_ = nullptr;
-
-  // A dispatch queue and associated event listener for running Objective-C
-  // blocks. This is typically used to wake up threads waiting on some HAL
-  // semaphore.
-  dispatch_queue_t wait_notifier_;
-  MTLSharedEventListener* event_listener_;
-};
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
-
-#endif  // IREE_HAL_METAL_METAL_DEVICE_H_
diff --git a/iree/hal/metal/metal_device.mm b/iree/hal/metal/metal_device.mm
deleted file mode 100644
index 58e0000..0000000
--- a/iree/hal/metal/metal_device.mm
+++ /dev/null
@@ -1,210 +0,0 @@
-// 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/metal/metal_device.h"
-
-#include "absl/memory/memory.h"
-#include "absl/strings/str_cat.h"
-#include "iree/base/status.h"
-#include "iree/base/time.h"
-#include "iree/base/tracing.h"
-#include "iree/hal/metal/dispatch_time_util.h"
-#include "iree/hal/metal/metal_capture_manager.h"
-#include "iree/hal/metal/metal_command_buffer.h"
-#include "iree/hal/metal/metal_command_queue.h"
-#include "iree/hal/metal/metal_direct_allocator.h"
-#include "iree/hal/metal/metal_pipeline_argument_buffer.h"
-#include "iree/hal/metal/metal_pipeline_cache.h"
-#include "iree/hal/metal/metal_shared_event.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-// static
-StatusOr<ref_ptr<MetalDevice>> MetalDevice::Create(ref_ptr<Driver> driver,
-                                                   const DeviceInfo& device_info,
-                                                   DebugCaptureManager* debug_capture_manager) {
-  return assign_ref(new MetalDevice(std::move(driver), device_info, debug_capture_manager));
-}
-
-MetalDevice::MetalDevice(ref_ptr<Driver> driver, const DeviceInfo& device_info,
-                         DebugCaptureManager* debug_capture_manager)
-    : Device(device_info),
-      driver_(std::move(driver)),
-      metal_handle_([(__bridge id<MTLDevice>)device_info.device_id() retain]),
-      debug_capture_manager_(debug_capture_manager) {
-  IREE_TRACE_SCOPE0("MetalDevice::ctor");
-
-  // Grab one queue for dispatch and transfer.
-  std::string name = absl::StrCat(device_info.name(), ":queue");
-  id<MTLCommandQueue> metal_queue = [metal_handle_ newCommandQueue];  // retained
-
-  allocator_ = MetalDirectAllocator::Create(metal_handle_, metal_queue);
-
-  if (debug_capture_manager_ && debug_capture_manager_->is_connected()) {
-    // Record a capture covering the duration of this device lifetime.
-    static_cast<MetalCaptureManager*>(debug_capture_manager_)->SetCaptureObject(metal_handle_);
-    debug_capture_manager_->StartCapture();
-  }
-
-  command_queue_ = absl::make_unique<MetalCommandQueue>(
-      name, IREE_HAL_COMMAND_CATEGORY_ANY, metal_queue);
-  common_queue_ = command_queue_.get();
-  // MetalCommandQueue retains by itself. Release here to avoid leaking.
-  [metal_queue release];
-
-  wait_notifier_ = dispatch_queue_create("com.google.iree.semaphore_wait_notifier", NULL);
-  event_listener_ = [[MTLSharedEventListener alloc] initWithDispatchQueue:wait_notifier_];
-}
-
-MetalDevice::~MetalDevice() {
-  IREE_TRACE_SCOPE0("MetalDevice::dtor");
-
-  if (debug_capture_manager_ && debug_capture_manager_->is_capturing()) {
-    debug_capture_manager_->StopCapture();
-  }
-
-  [event_listener_ release];
-  dispatch_release(wait_notifier_);
-
-  [metal_handle_ release];
-}
-
-Status MetalDevice::CreateExecutableCache(iree_string_view_t identifier,
-      iree_hal_executable_cache_t** out_executable_cache) {
-  IREE_TRACE_SCOPE0("MetalDevice::CreateExecutableCache");
-  return make_ref<MetalPipelineCache>(metal_handle_);
-}
-
-Status MetalDevice::CreateDescriptorSetLayout(
-    iree_hal_descriptor_set_layout_usage_type_t usage_type,
-    absl::Span<const iree_hal_descriptor_set_layout_binding_t> bindings,
-    iree_hal_descriptor_set_layout_t** out_descriptor_set_layout) {
-  IREE_TRACE_SCOPE0("MetalDevice::CreateDescriptorSetLayout");
-  return make_ref<MetalArgumentBufferLayout>(usage_type, bindings);
-}
-
-Status MetalDevice::CreateExecutableLayout(
-    absl::Span<iree_hal_descriptor_set_layout_t*> set_layouts, size_t push_constants, iree_hal_executable_layout_t** out_executable_layout) {
-  IREE_TRACE_SCOPE0("MetalDevice::CreateExecutableLayout");
-  return make_ref<MetalPipelineArgumentBufferLayout>(set_layouts, push_constants);
-}
-
-Status MetalDevice::CreateDescriptorSet(
-    iree_hal_descriptor_set_layout_t* set_layout, absl::Span<const iree_hal_descriptor_set_binding_t> bindings,
-    iree_hal_descriptor_set_t** out_descriptor_set) {
-  IREE_TRACE_SCOPE0("MetalDevice::CreateDescriptorSet");
-  return make_ref<MetalArgumentBuffer>(static_cast<MetalArgumentBufferLayout*>(set_layout),
-                                       bindings);
-}
-
-Status MetalDevice::CreateCommandBuffer(
-    iree_hal_command_buffer_mode_t mode, iree_hal_command_category_t command_categories,
-      iree_hal_command_buffer_t** out_command_buffer) {
-  IREE_TRACE_SCOPE0("MetalDevice::CreateCommandBuffer");
-  @autoreleasepool {
-    StatusOr<ref_ptr<CommandBuffer>> command_buffer;
-    // We use commandBufferWithUnretainedReferences here to be performant. This is okay becasue
-    // IREE tracks the lifetime of various objects with the help from compilers.
-    id<MTLCommandBuffer> cmdbuf = [static_cast<MetalCommandQueue*>(common_queue_)->handle()
-        commandBufferWithUnretainedReferences];
-    command_buffer = MetalCommandBuffer::Create(mode, command_categories, cmdbuf);
-    return command_buffer;
-  }
-}
-
-Status MetalDevice::CreateEvent(iree_hal_event_t** out_event) {
-  IREE_TRACE_SCOPE0("MetalDevice::CreateEvent");
-  return UnimplementedErrorBuilder(IREE_LOC) << "MetalDevice::CreateEvent";
-}
-
-Status MetalDevice::CreateSemaphore(uint64_t initial_value, iree_hal_semaphore_t** out_semaphore) {
-  IREE_TRACE_SCOPE0("MetalDevice::CreateSemaphore");
-  return MetalSharedEvent::Create(metal_handle_, event_listener_, initial_value);
-}
-
-Status MetalDevice::WaitAllSemaphores(const iree_hal_semaphore_list_t* semaphore_list,
-                                      iree_time_t deadline_ns) {
-  IREE_TRACE_SCOPE0("MetalDevice::WaitAllSemaphores");
-  // Go through all MetalSharedEvents and wait on each of them given we need all of them to be
-  // signaled anyway.
-  for (int i = 0; i < semaphores.size(); ++i) {
-    auto* semaphore = static_cast<MetalSharedEvent*>(semaphores[i].semaphore);
-    IREE_RETURN_IF_ERROR(semaphore->Wait(semaphores[i].value, deadline_ns));
-  }
-  return OkStatus();
-}
-
-StatusOr<int> MetalDevice::WaitAnySemaphore(const iree_hal_semaphore_list_t* semaphore_list,
-                                            iree_time_t deadline_ns) {
-  IREE_TRACE_SCOPE0("MetalDevice::WaitAnySemaphore");
-
-  if (semaphores.empty()) {
-    return InvalidArgumentErrorBuilder(IREE_LOC) << "expected to have at least one semaphore";
-  }
-
-  // If there is just one semaphore, just wait on it.
-  if (semaphores.size() == 1) {
-    auto* semaphore = static_cast<MetalSharedEvent*>(semaphores[0].semaphore);
-    IREE_RETURN_IF_ERROR(semaphore->Wait(semaphores[0].value, deadline_ns));
-    return 0;
-  }
-
-  // Otherwise, we need to go down a more complicated path by registering listeners to all
-  // MTLSharedEvents to notify us when at least one of them has done the work on GPU by signaling a
-  // semaphore. The signaling will happen in a new dispatch queue; the current thread will wait on
-  // the semaphore.
-
-  dispatch_time_t timeout = DeadlineToDispatchTime(deadline_ns);
-
-  // Store the handle as a __block variable to allow blocks accessing the same copy for the
-  // semaphore handle on heap.
-  // Use an initial value of zero so that any semaphore signal will unblock the wait.
-  __block dispatch_semaphore_t work_done = dispatch_semaphore_create(0);
-  // Also create a __block variable to store the index for the signaled semaphore.
-  __block int signaled_index = 0;
-
-  // The dispatch queue created in the above is a serial one. So even if multiple semaphores signal,
-  // the semaphore signaling should be serialized.
-  for (int i = 0; i < semaphores.size(); ++i) {
-    auto* semaphore = static_cast<MetalSharedEvent*>(semaphores[i].semaphore);
-    [semaphore->handle() notifyListener:event_listener_
-                                atValue:semaphores[i].value
-                                  block:^(id<MTLSharedEvent>, uint64_t) {
-                                    dispatch_semaphore_signal(work_done);
-                                    // This should capture the *current* index for each semaphore.
-                                    signaled_index = i;
-                                  }];
-  }
-
-  long timed_out = dispatch_semaphore_wait(work_done, timeout);
-
-  dispatch_release(work_done);
-
-  if (timed_out) {
-    return DeadlineExceededErrorBuilder(IREE_LOC)
-           << "Deadline exceeded waiting for dispatch_semaphore_t";
-  }
-  return signaled_index;
-}
-
-Status MetalDevice::WaitIdle(iree_time_t deadline_ns) {
-  IREE_TRACE_SCOPE0("MetalDevice::WaitIdle");
-  return UnimplementedErrorBuilder(IREE_LOC) << "MetalDevice::WaitIdle";
-}
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
diff --git a/iree/hal/metal/metal_direct_allocator.h b/iree/hal/metal/metal_direct_allocator.h
deleted file mode 100644
index 117d358..0000000
--- a/iree/hal/metal/metal_direct_allocator.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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_METAL_METAL_DIRECT_ALLOCATOR_H_
-#define IREE_HAL_METAL_METAL_DIRECT_ALLOCATOR_H_
-
-#import <Metal/Metal.h>
-
-#include <memory>
-
-#include "iree/base/status.h"
-#include "iree/hal/api.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-class MetalBuffer;
-
-// An allocator implementation for Metal that directly wraps a MTLDevice and
-// requests all allocations on the device. This is not of great performance,
-// but good for start.
-class MetalDirectAllocator final : public Allocator {
- public:
-  static std::unique_ptr<MetalDirectAllocator> Create(
-      id<MTLDevice> device, id<MTLCommandQueue> transfer_queue);
-
-  ~MetalDirectAllocator() override;
-
-  bool CanUseBufferLike(Allocator* source_allocator,
-                        iree_hal_memory_type_t memory_type,
-                        iree_hal_buffer_usage_t buffer_usage,
-                        iree_hal_buffer_usage_t intended_usage) const override;
-
-  StatusOr<ref_ptr<Buffer>> Allocate(iree_hal_memory_type_t memory_type,
-                                     iree_hal_buffer_usage_t buffer_usage,
-                                     size_t allocation_size) override;
-
- private:
-  explicit MetalDirectAllocator(id<MTLDevice> device,
-                                id<MTLCommandQueue> transfer_queue);
-
-  StatusOr<ref_ptr<MetalBuffer>> AllocateInternal(
-      iree_hal_memory_type_t memory_type, iree_hal_buffer_usage_t buffer_usage,
-      iree_hal_memory_access_t allowed_access, size_t allocation_size);
-
-  id<MTLDevice> metal_device_;
-  id<MTLCommandQueue> metal_transfer_queue_;
-};
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
-
-#endif  // IREE_HAL_METAL_METAL_DIRECT_ALLOCATOR_H_
diff --git a/iree/hal/metal/metal_direct_allocator.mm b/iree/hal/metal/metal_direct_allocator.mm
deleted file mode 100644
index 833006d..0000000
--- a/iree/hal/metal/metal_direct_allocator.mm
+++ /dev/null
@@ -1,124 +0,0 @@
-// 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/metal/metal_direct_allocator.h"
-
-#include "absl/memory/memory.h"
-#include "iree/base/status.h"
-#include "iree/base/tracing.h"
-#include "iree/hal/metal/metal_buffer.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-namespace {
-
-// Returns the proper Metal resource storage mode given the specific MemoryType.
-MTLResourceOptions SelectMTLResourceStorageMode(MemoryType memory_type) {
-  // There are four MTLStorageMode:
-  // * Managed: The CPU and GPU may maintain separate copies of the resource, and any changes
-  //   must be explicitly synchronized.
-  // * Shared: The resource is stored in system memory and is accessible to both the CPU and
-  //   the GPU.
-  // * Private: The resource can be accessed only by the GPU.
-  // * Memoryless: The resource’s contents can be accessed only by the GPU and only exist
-  //   temporarily during a render pass.
-  // macOS has all of the above; MTLStorageModeManaged is not available on iOS.
-  //
-  // The IREE HAL is modeled after Vulkan so it's quite explicit. For buffers visible to both
-  // the host and the device, we would like to opt in with the explicit version
-  // (MTLStorageManaged) when possible because it should be more performant: "In macOS,
-  // there’s no difference in GPU performance between managed and private buffers." But for
-  // iOS, MTLStorageShared should be good given we have a unified memory model there.
-
-  if (iree_all_bits_set(memory_type, IREE_HAL_MEMORY_TYPE_DEVICE_LOCAL)) {
-    if (iree_all_bits_set(memory_type, IREE_HAL_MEMORY_TYPE_HOST_VISIBLE)) {
-      // Device-local, host-visible.
-      // TODO(antiagainst): Enable using MTLResourceStorageModeManaged on macOS once we have
-      // defined invalidate/flush C APIs and wired up their usage through the stack. At the
-      // moment if we use MTLResourceStorageModeManaged, due to no proper invlidate/flush
-      // actions, the kernel invocations' data read/write will not be properly synchronized.
-      return MTLResourceStorageModeShared;
-    } else {
-      // Device-local only.
-      return MTLResourceStorageModePrivate;
-    }
-  } else {
-    if (iree_all_bits_set(memory_type, IREE_HAL_MEMORY_TYPE_DEVICE_VISIBLE)) {
-      // Host-local, device-visible.
-      return MTLResourceStorageModeShared;
-    } else {
-      // Host-local only.
-      // TODO(antiagainst): we probably want to just use HostBuffer here.
-      return MTLResourceStorageModeShared;
-    }
-  }
-}
-
-}  // namespace
-
-// static
-std::unique_ptr<MetalDirectAllocator> MetalDirectAllocator::Create(
-    id<MTLDevice> device, id<MTLCommandQueue> transfer_queue) {
-  IREE_TRACE_SCOPE0("MetalDirectAllocator::Create");
-  return absl::WrapUnique(new MetalDirectAllocator(device, transfer_queue));
-}
-
-MetalDirectAllocator::MetalDirectAllocator(id<MTLDevice> device, id<MTLCommandQueue> transfer_queue)
-    : metal_device_([device retain]), metal_transfer_queue_([transfer_queue retain]) {}
-
-MetalDirectAllocator::~MetalDirectAllocator() {
-  IREE_TRACE_SCOPE0("MetalDirectAllocator::dtor");
-  [metal_transfer_queue_ release];
-  [metal_device_ release];
-}
-
-bool MetalDirectAllocator::CanUseBufferLike(Allocator* source_allocator,
-                                            iree_hal_memory_type_t memory_type,
-                                            iree_hal_buffer_usage_t buffer_usage,
-                                            iree_hal_buffer_usage_t intended_usage) const {
-  // TODO(benvanik): ensure there is a memory type that can satisfy the request.
-  return source_allocator == this;
-}
-
-StatusOr<ref_ptr<MetalBuffer>> MetalDirectAllocator::AllocateInternal(
-    iree_hal_memory_type_t memory_type, iree_hal_buffer_usage_t buffer_usage,
-    iree_hal_memory_access_t allowed_access, size_t allocation_size) {
-  IREE_TRACE_SCOPE0("MetalDirectAllocator::AllocateInternal");
-
-  MTLResourceOptions resource_options = SelectMTLResourceStorageMode(memory_type);
-
-  // IREE is more explicit than Metal: it tracks various state by itself. There is no need
-  // to incur Metal runtime overhead for hazard tracking.
-  resource_options |= MTLResourceHazardTrackingModeUntracked;
-
-  id<MTLBuffer> metal_buffer = [metal_device_ newBufferWithLength:allocation_size
-                                                          options:resource_options];  // retained
-
-  return MetalBuffer::Create(
-      this, memory_type, allowed_access, buffer_usage, allocation_size, /*byte_offset=*/0,
-      /*byte_length=*/allocation_size, metal_buffer, metal_transfer_queue_);
-}
-
-StatusOr<ref_ptr<Buffer>> MetalDirectAllocator::Allocate(iree_hal_memory_type_t memory_type,
-                                                         iree_hal_buffer_usage_t buffer_usage,
-                                                         size_t allocation_size) {
-  IREE_TRACE_SCOPE0("MetalDirectAllocator::Allocate");
-  return AllocateInternal(memory_type, buffer_usage, IREE_HAL_MEMORY_ACCESS_ALL, allocation_size);
-}
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
diff --git a/iree/hal/metal/metal_driver.h b/iree/hal/metal/metal_driver.h
deleted file mode 100644
index bb2603e..0000000
--- a/iree/hal/metal/metal_driver.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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_METAL_METAL_DRIVER_H_
-#define IREE_HAL_METAL_METAL_DRIVER_H_
-
-#include <memory>
-#include <string>
-
-#include "iree/hal/cc/driver.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-struct MetalDriverOptions {
-  // Whether to enable Metal command capture.
-  bool enable_capture;
-  // The file to contain the Metal capture. Empty means capturing to Xcode.
-  std::string capture_file;
-};
-
-// A pseudo Metal GPU driver which retains all available Metal GPU devices
-// during its lifetime.
-//
-// It uses the iree_hal_device_id_t to store the underlying id<MTLDevice>.
-class MetalDriver final : public Driver {
- public:
-  static StatusOr<ref_ptr<MetalDriver>> Create(
-      const MetalDriverOptions& options);
-
-  ~MetalDriver() override;
-
-  StatusOr<std::vector<DeviceInfo>> EnumerateAvailableDevices() override;
-
-  StatusOr<ref_ptr<Device>> CreateDefaultDevice() override;
-
-  StatusOr<ref_ptr<Device>> CreateDevice(
-      iree_hal_device_id_t device_id) override;
-
- private:
-  MetalDriver(std::vector<DeviceInfo> devices);
-
-  std::vector<DeviceInfo> devices_;
-};
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
-
-#endif  // IREE_HAL_METAL_METAL_DRIVER_H_
diff --git a/iree/hal/metal/metal_driver.mm b/iree/hal/metal/metal_driver.mm
deleted file mode 100644
index b561a31..0000000
--- a/iree/hal/metal/metal_driver.mm
+++ /dev/null
@@ -1,118 +0,0 @@
-// 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/metal/metal_driver.h"
-
-#import <Metal/Metal.h>
-
-#include "iree/base/status.h"
-#include "iree/base/tracing.h"
-#include "iree/hal/metal/metal_capture_manager.h"
-#include "iree/hal/metal/metal_device.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-namespace {
-
-// Returns an autoreleased array of available Metal GPU devices.
-NSArray<id<MTLDevice>>* GetAvailableMetalDevices() {
-#if defined(IREE_PLATFORM_MACOS)
-  // For macOS, we might have more than one GPU devices.
-  return [MTLCopyAllDevices() autorelease];
-#else
-  // For other Apple platforms, we only have one GPU device.
-  id<MTLDevice> device = [MTLCreateSystemDefaultDevice() autorelease];
-  return [NSArray arrayWithObject:device];
-#endif
-}
-
-}  // namespace
-
-// static
-StatusOr<ref_ptr<MetalDriver>> MetalDriver::Create(const MetalDriverOptions& options) {
-  IREE_TRACE_SCOPE0("MetalDriver::Create");
-
-  @autoreleasepool {
-    NSArray<id<MTLDevice>>* devices = GetAvailableMetalDevices();
-    if (devices == nil) {
-      return UnavailableErrorBuilder(IREE_LOC) << "no Metal GPU devices available";
-    }
-
-    std::unique_ptr<MetalCaptureManager> metal_capture_manager;
-    if (options.enable_capture) {
-      IREE_ASSIGN_OR_RETURN(metal_capture_manager,
-                            MetalCaptureManager::Create(options.capture_file));
-      IREE_RETURN_IF_ERROR(metal_capture_manager->Connect());
-    }
-
-    std::vector<DeviceInfo> device_infos;
-    for (id<MTLDevice> device in devices) {
-      std::string name = std::string([device.name UTF8String]);
-      iree_hal_device_feature_t supported_features = IREE_HAL_DEVICE_FEATURE_NONE;
-      iree_hal_device_id_t device_id = reinterpret_cast<iree_hal_device_id_t>((__bridge void*)device);
-      device_infos.emplace_back("metal", std::move(name), supported_features, device_id);
-    }
-    return assign_ref(new MetalDriver(std::move(device_infos), std::move(metal_capture_manager)));
-  }
-}
-
-MetalDriver::MetalDriver(std::vector<DeviceInfo> devices)
-    : Driver("metal"),
-      devices_(std::move(devices)) {
-  // Retain all the retained Metal GPU devices.
-  for (const auto& device : devices_) {
-    [(__bridge id<MTLDevice>)device.device_id() retain];
-  }
-}
-
-MetalDriver::~MetalDriver() {
-  IREE_TRACE_SCOPE0("MetalDriver::dtor");
-
-  // Release all the retained Metal GPU devices.
-  for (const auto& device : devices_) {
-    [(__bridge id<MTLDevice>)device.device_id() release];
-  }
-}
-
-StatusOr<std::vector<DeviceInfo>> MetalDriver::EnumerateAvailableDevices() {
-  IREE_TRACE_SCOPE0("MetalDriver::EnumerateAvailableDevices");
-
-  return devices_;
-}
-
-StatusOr<ref_ptr<Device>> MetalDriver::CreateDefaultDevice() {
-  IREE_TRACE_SCOPE0("MetalDriver::CreateDefaultDevice");
-
-  if (devices_.empty()) {
-    return UnavailableErrorBuilder(IREE_LOC) << "no Metal GPU devices available";
-  }
-  return CreateDevice(devices_.front().device_id());
-}
-
-StatusOr<ref_ptr<Device>> MetalDriver::CreateDevice(iree_hal_device_id_t device_id) {
-  IREE_TRACE_SCOPE0("MetalDriver::CreateDevice");
-
-  for (const DeviceInfo& info : devices_) {
-    if (info.device_id() == device_id) {
-      return MetalDevice::Create(add_ref(this), info);
-    }
-  }
-  return InvalidArgumentErrorBuilder(IREE_LOC) << "unknown driver device id: " << device_id;
-}
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
diff --git a/iree/hal/metal/metal_kernel_library.h b/iree/hal/metal/metal_kernel_library.h
deleted file mode 100644
index 6916ddc..0000000
--- a/iree/hal/metal/metal_kernel_library.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// 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_METAL_METAL_KERNEL_LIBRARY_H_
-#define IREE_HAL_METAL_METAL_KERNEL_LIBRARY_H_
-
-#import <Metal/Metal.h>
-
-#include <string>
-
-#include "absl/container/inlined_vector.h"
-#include "iree/base/status.h"
-#include "iree/hal/cc/executable_cache.h"
-
-// flatcc schemas:
-#include "iree/base/flatcc.h"
-#include "iree/schemas/metal_executable_def_builder.h"
-#include "iree/schemas/metal_executable_def_reader.h"
-#include "iree/schemas/metal_executable_def_verifier.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-// An executable implementation for Metal that wraps MTLLibrary and MTLFunction.
-//
-// Metal represents compute kernels as MTLFunctions. MTLLibrary is just an
-// allocation of MTLFunctions. One creates a MTLComputePipelineState from a
-// MTLFunction and uses the pipeline state for creating compute pipelines.
-// This class bundles all the necesary Metal objects for getting pipeline state
-// objects for a compute kernel.
-class MetalKernelLibrary final : public Executable {
- public:
-  static StatusOr<ref_ptr<MetalKernelLibrary>> Create(
-      id<MTLDevice> device, iree_hal_executable_caching_mode_t mode,
-      iree_const_byte_span_t executable_data);
-  ~MetalKernelLibrary() override;
-
-  // Returns the MTLFunction for the entry point with the given |ordinal|.
-  StatusOr<id<MTLFunction>> GetKernelForEntryPoint(int ordinal) const;
-
-  // Returns the threadgroup size for the entry point with the given |ordinal|.
-  StatusOr<iree_MetalThreadgroupSize_t> GetThreadgroupSizeForEntryPoint(
-      int ordinal) const;
-
-  // Returns the pipeline state object for the entry point with the given
-  // |ordinal|.
-  StatusOr<id<MTLComputePipelineState>> GetPipelineStateForEntryPoint(
-      int ordinal) const;
-
- private:
-  struct KernelObjects {
-    id<MTLFunction> function;
-    iree_MetalThreadgroupSize_t threadgroup_size;
-    // Baked pipeline state object.
-    id<MTLComputePipelineState> pipeline_state;
-  };
-
-  // Creates a MetalKernelLibrary assuming all Metal objects are already
-  // retained before passing in.
-  MetalKernelLibrary(id<MTLDevice> device,
-                     absl::InlinedVector<id<MTLLibrary>, 4> libraries,
-                     absl::InlinedVector<KernelObjects, 4> kernel_objects);
-
-  id<MTLDevice> device_;
-
-  absl::InlinedVector<id<MTLLibrary>, 4> libraries_;
-  absl::InlinedVector<KernelObjects, 4> kernel_objects_;
-};
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
-
-#endif  // IREE_HAL_METAL_METAL_KERNEL_LIBRARY_H_
diff --git a/iree/hal/metal/metal_kernel_library.mm b/iree/hal/metal/metal_kernel_library.mm
deleted file mode 100644
index dc1f733..0000000
--- a/iree/hal/metal/metal_kernel_library.mm
+++ /dev/null
@@ -1,225 +0,0 @@
-// 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/metal/metal_kernel_library.h"
-
-#include "iree/base/memory.h"
-#include "iree/base/status.h"
-#include "iree/base/tracing.h"
-
-// NOTE: starting to port this to ObjC.
-
-// Verifies the structure of the flatbuffer so that we can avoid doing so during
-// runtime. There are still some conditions we must be aware of (such as omitted
-// names on functions with internal linkage), however we shouldn't need to
-// bounds check anything within the flatbuffer after this succeeds.
-static iree_status_t iree_hal_metal_executable_flatbuffer_verify(
-    iree_const_byte_span_t flatbuffer_data) {
-  if (!flatbuffer_data.data || flatbuffer_data.data_length < 16) {
-    return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
-                            "flatbuffer data is not present or less than 16 bytes (%zu total)",
-                            flatbuffer_data.data_length);
-  }
-
-  // Run flatcc generated verification. This ensures all pointers are in-bounds
-  // and that we can safely walk the file, but not that the actual contents of
-  // the flatbuffer meet our expectations.
-  int verify_ret =
-      iree_MetalExecutableDef_verify_as_root(flatbuffer_data.data, flatbuffer_data.data_length);
-  if (verify_ret != flatcc_verify_ok) {
-    return iree_make_status(IREE_STATUS_INVALID_ARGUMENT, "flatbuffer verification failed: %s",
-                            flatcc_verify_error_string(verify_ret));
-  }
-
-  iree_MetalExecutableDef_table_t executable_def =
-      iree_MetalExecutableDef_as_root(flatbuffer_data.data);
-
-  flatbuffers_string_vec_t entry_points_vec =
-      iree_MetalExecutableDef_entry_points_get(executable_def);
-  size_t entry_point_count = flatbuffers_string_vec_len(entry_points_vec);
-  for (size_t i = 0; i < entry_point_count; ++i) {
-    if (!flatbuffers_string_len(flatbuffers_string_vec_at(entry_points_vec, i))) {
-      return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
-                              "executable entry point %zu has no name", i);
-    }
-  }
-
-  iree_MetalThreadgroupSize_vec_t threadgroup_sizes_vec =
-      iree_MetalExecutableDef_threadgroup_sizes(executable_def);
-  size_t threadgroup_size_count = iree_MetalThreadgroupSize_vec_len(threadgroup_sizes_vec);
-  if (!threadgroup_size_count) {
-    return InvalidArgumentErrorBuilder(IREE_LOC) << "No threadgroup sizes present";
-  }
-
-  flatbuffers_string_vec_t shader_sources_vec =
-      iree_MetalExecutableDef_shader_sources_get(executable_def);
-  size_t shader_source_count = flatbuffers_string_vec_len(shader_sources_vec);
-  for (size_t i = 0; i < shader_source_count; ++i) {
-    if (!flatbuffers_string_len(flatbuffers_string_vec_at(shader_sources_vec, i))) {
-      return iree_make_status(IREE_STATUS_INVALID_ARGUMENT, "executable shader source %zu is empty",
-                              i);
-    }
-  }
-
-  if (entry_point_count != threadgroup_size_count || entry_point_count != shader_source_count) {
-    return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
-                            "mismatch among the numbers of entry points (%zu), thread group sizes "
-                            "(%zu), and source strings (%zu)",
-                            entry_point_count, threadgroup_size_count, shader_source_count);
-  }
-
-  return iree_ok_status();
-}
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-// static
-StatusOr<ref_ptr<MetalKernelLibrary>> MetalKernelLibrary::Create(id<MTLDevice> device,
-                                                                 iree_hal_executable_caching_mode_t mode,
-                                                                 iree_const_byte_span_t executable_data) {
-  IREE_TRACE_SCOPE0("MetalKernelLibrary::Create");
-
-  // Verify and fetch the executable flatbuffer wrapper.
-  iree_const_byte_span_t executable_data =
-      iree_make_const_byte_span(spec.executable_data.data(), spec.executable_data.size());
-  IREE_RETURN_IF_ERROR(iree_hal_metal_executable_flatbuffer_verify(executable_data));
-  iree_MetalExecutableDef_table_t executable_def =
-      iree_MetalExecutableDef_as_root(executable_data.data);
-
-  flatbuffers_string_vec_t entry_points_vec =
-      iree_MetalExecutableDef_entry_points_get(executable_def);
-  iree_MetalThreadgroupSize_vec_t threadgroup_sizes_vec =
-      iree_MetalExecutableDef_threadgroup_sizes(executable_def);
-  flatbuffers_string_vec_t shader_sources_vec =
-      iree_MetalExecutableDef_shader_sources_get(executable_def);
-
-  // Compile each MSL source string into a MTLLibrary and get the MTLFunction for the entry point to
-  // build the pipeline state object.
-
-  absl::InlinedVector<id<MTLLibrary>, 4> libraries;
-  absl::InlinedVector<KernelObjects, 4> kernel_objects;
-
-  MTLCompileOptions* msl_compile_options = [MTLCompileOptions new];
-  msl_compile_options.languageVersion = MTLLanguageVersion2_0;
-
-  auto cleanup = MakeCleanup([&]() {
-    for (const auto& kernel : kernel_objects) {
-      [kernel.pipeline_state release];
-      [kernel.function release];
-    }
-    for (id<MTLLibrary> library : libraries) [library release];
-    [msl_compile_options release];
-  });
-
-  // TODO(antiagainst): We are performing synchronous compilation at runtime here. This is good for
-  // debugging purposes but bad for performance. Enable offline compilation and make that as the
-  // default.
-
-  for (size_t entry_ordinal = 0; entry_ordinal < flatbuffers_string_vec_len(shader_sources_vec);
-       ++entry_ordinal) {
-    flatbuffers_string_t entry_point = flatbuffers_string_vec_at(entry_points_vec, entry_ordinal);
-    @autoreleasepool {
-      NSError* error = nil;
-
-      NSString* shader_source =
-          [NSString stringWithCString:flatbuffers_string_vec_at(shader_sources_vec, entry_ordinal)
-                             encoding:[NSString defaultCStringEncoding]];
-      id<MTLLibrary> library = [device newLibraryWithSource:shader_source
-                                                    options:msl_compile_options
-                                                      error:&error];
-      if (!library) {
-        NSLog(@"Failed to create MTLLibrary: %@", error);
-#ifndef NDEBUG
-        NSLog(@"Original MSL source: %@", shader_source);
-#endif
-        return InvalidArgumentErrorBuilder(IREE_LOC) << "Invalid MSL source";
-      }
-      libraries.push_back(library);
-
-      id<MTLFunction> function = [library
-          newFunctionWithName:[NSString stringWithCString:entry_point
-                                                 encoding:[NSString defaultCStringEncoding]]];
-      if (!function) {
-        NSLog(@"Failed to create MTLFunction");
-#ifndef NDEBUG
-        NSLog(@"Original MSL source: %@", shader_source);
-#endif
-        return InvalidArgumentErrorBuilder(IREE_LOC)
-               << "Cannot find entry point '" << entry_point << "' in shader source index "
-               << entry_ordinal;
-      }
-
-      id<MTLComputePipelineState> pso = [device newComputePipelineStateWithFunction:function
-                                                                              error:&error];
-      if (!pso) {
-        NSLog(@"Failed to create MTLComputePipelineState: %@", error);
-#ifndef NDEBUG
-        NSLog(@"Original MSL source: %@", shader_source);
-#endif
-        return InvalidArgumentErrorBuilder(IREE_LOC) << "Invalid MSL source";
-      }
-
-      kernel_objects.push_back(
-          KernelObjects{function, {static_cast<uint32_t>(iree_MetalThreadgroupSize__size())}, pso});
-    }
-  }
-
-  return assign_ref(
-      new MetalKernelLibrary([device retain], std::move(libraries), std::move(kernel_objects)));
-}
-
-MetalKernelLibrary::MetalKernelLibrary(id<MTLDevice> device,
-                                       absl::InlinedVector<id<MTLLibrary>, 4> libraries,
-                                       absl::InlinedVector<KernelObjects, 4> kernel_objects)
-    : device_(device),
-      libraries_(std::move(libraries)),
-      kernel_objects_(std::move(kernel_objects)) {}
-
-MetalKernelLibrary::~MetalKernelLibrary() {
-  IREE_TRACE_SCOPE0("MetalKernelLibrary::dtor");
-  for (const auto& kernel : kernel_objects_) {
-    [kernel.pipeline_state release];
-    [kernel.function release];
-  }
-  for (id<MTLLibrary> library : libraries_) [library release];
-}
-
-StatusOr<id<MTLFunction>> MetalKernelLibrary::GetKernelForEntryPoint(int ordinal) const {
-  if (ordinal < 0 || ordinal >= kernel_objects_.size()) {
-    return OutOfRangeErrorBuilder(IREE_LOC) << "Invalid entry point ordinal: " << ordinal;
-  }
-  return kernel_objects_[ordinal].function;
-}
-
-StatusOr<iree_MetalThreadgroupSize_t> MetalKernelLibrary::GetThreadgroupSizeForEntryPoint(
-    int ordinal) const {
-  if (ordinal < 0 || ordinal >= kernel_objects_.size()) {
-    return OutOfRangeErrorBuilder(IREE_LOC) << "Invalid entry point ordinal: " << ordinal;
-  }
-  return kernel_objects_[ordinal].threadgroup_size;
-}
-
-StatusOr<id<MTLComputePipelineState>> MetalKernelLibrary::GetPipelineStateForEntryPoint(
-    int ordinal) const {
-  if (ordinal < 0 || ordinal >= kernel_objects_.size()) {
-    return OutOfRangeErrorBuilder(IREE_LOC) << "Invalid entry point ordinal: " << ordinal;
-  }
-  return kernel_objects_[ordinal].pipeline_state;
-}
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
diff --git a/iree/hal/metal/metal_pipeline_argument_buffer.cc b/iree/hal/metal/metal_pipeline_argument_buffer.cc
deleted file mode 100644
index 1879a81..0000000
--- a/iree/hal/metal/metal_pipeline_argument_buffer.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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/metal/metal_pipeline_argument_buffer.h"
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_join.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-MetalArgumentBufferLayout::MetalArgumentBufferLayout(
-    iree_hal_descriptor_set_layout_usage_type_t usage_type,
-    absl::Span<const iree_hal_descriptor_set_layout_binding_t> bindings)
-    : usage_type_(usage_type), bindings_(bindings.begin(), bindings.end()) {}
-
-const iree_hal_descriptor_set_layout_binding_t*
-MetalArgumentBufferLayout::GetBindingForIndex(int index) const {
-  for (const auto& binding : bindings_) {
-    if (binding.binding == index) return &binding;
-  }
-  return nullptr;
-}
-
-MetalPipelineArgumentBufferLayout::MetalPipelineArgumentBufferLayout(
-    absl::Span<DescriptorSetLayout* const> set_layouts, size_t push_constants)
-    : set_layouts_(set_layouts.size()), push_constants_(push_constants) {
-  for (int i = 0; i < set_layouts.size(); ++i) {
-    set_layouts_[i] = static_cast<MetalArgumentBufferLayout*>(set_layouts[i]);
-    set_layouts_[i]->AddReference();
-  }
-}
-
-MetalPipelineArgumentBufferLayout::~MetalPipelineArgumentBufferLayout() {
-  for (auto* layout : set_layouts_) layout->ReleaseReference();
-}
-
-MetalArgumentBuffer::MetalArgumentBuffer(
-    MetalArgumentBufferLayout* layout,
-    absl::Span<const iree_hal_descriptor_set_binding_t> resources)
-    : layout_(layout), resources_(resources.begin(), resources.end()) {
-  layout_->AddReference();
-}
-
-MetalArgumentBuffer::~MetalArgumentBuffer() { layout_->ReleaseReference(); }
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
diff --git a/iree/hal/metal/metal_pipeline_argument_buffer.h b/iree/hal/metal/metal_pipeline_argument_buffer.h
deleted file mode 100644
index 0d5456a..0000000
--- a/iree/hal/metal/metal_pipeline_argument_buffer.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// 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_METAL_METAL_PIPELINE_ARGUMENT_BUFFER_H_
-#define IREE_HAL_METAL_METAL_PIPELINE_ARGUMENT_BUFFER_H_
-
-#include <string>
-
-#include "absl/container/inlined_vector.h"
-#include "absl/types/span.h"
-#include "iree/hal/cc/descriptor_set.h"
-#include "iree/hal/cc/descriptor_set_layout.h"
-#include "iree/hal/cc/executable_layout.h"
-
-// Metal implementaion classes for resource descriptor related interfaces.
-//
-// See docs/design_docs/metal_hal_driver.md#resource-descriptors for more
-// details.
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-class MetalArgumentBufferLayout final : public DescriptorSetLayout {
- public:
-  MetalArgumentBufferLayout(UsageType usage_type,
-                            absl::Span<const Binding> bindings);
-  ~MetalArgumentBufferLayout() override = default;
-
-  absl::Span<const Binding> bindings() const { return bindings_; }
-  const Binding* GetBindingForIndex(int index) const;
-
- private:
-  UsageType usage_type_;
-  absl::InlinedVector<Binding, 8> bindings_;
-};
-
-class MetalPipelineArgumentBufferLayout final : public ExecutableLayout {
- public:
-  MetalPipelineArgumentBufferLayout(
-      absl::Span<DescriptorSetLayout* const> set_layouts,
-      size_t push_constants);
-  ~MetalPipelineArgumentBufferLayout() override;
-
-  absl::Span<MetalArgumentBufferLayout* const> set_layouts() const {
-    return set_layouts_;
-  }
-
- private:
-  absl::InlinedVector<MetalArgumentBufferLayout*, 2> set_layouts_;
-  size_t push_constants_;
-};
-
-class MetalArgumentBuffer final : public DescriptorSet {
- public:
-  MetalArgumentBuffer(MetalArgumentBufferLayout* layout,
-                      absl::Span<const Binding> resources);
-  ~MetalArgumentBuffer() override;
-
- private:
-  MetalArgumentBufferLayout* layout_;
-  absl::InlinedVector<Binding, 8> resources_;
-};
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
-
-#endif  // IREE_HAL_METAL_METAL_PIPELINE_ARGUMENT_BUFFER_H_
diff --git a/iree/hal/metal/metal_pipeline_cache.h b/iree/hal/metal/metal_pipeline_cache.h
deleted file mode 100644
index 7b74909..0000000
--- a/iree/hal/metal/metal_pipeline_cache.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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_METAL_METAL_PIPELINE_CACHE_H_
-#define IREE_HAL_METAL_METAL_PIPELINE_CACHE_H_
-
-#import <Metal/Metal.h>
-
-#include "iree/hal/cc/executable_cache.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-// An ExecutableCache implementation for Metal.
-class MetalPipelineCache final : public ExecutableCache {
- public:
-  explicit MetalPipelineCache(id<MTLDevice> device);
-  ~MetalPipelineCache() override;
-
-  bool CanPrepareFormat(iree_hal_executable_format_t format) const override;
-
-  StatusOr<ref_ptr<Executable>> PrepareExecutable(
-      ExecutableLayout* executable_layout,
-      iree_hal_executable_caching_mode_t mode,
-      iree_const_byte_span_t executable_data) override;
-
- private:
-  id<MTLDevice> metal_device_;
-};
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
-
-#endif  // IREE_HAL_METAL_METAL_PIPELINE_CACHE_H_
diff --git a/iree/hal/metal/metal_pipeline_cache.mm b/iree/hal/metal/metal_pipeline_cache.mm
deleted file mode 100644
index ec328e4..0000000
--- a/iree/hal/metal/metal_pipeline_cache.mm
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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/metal/metal_pipeline_cache.h"
-
-#include "iree/base/status.h"
-#include "iree/base/tracing.h"
-#include "iree/hal/api.h"
-#include "iree/hal/metal/metal_kernel_library.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-static const iree_hal_executable_format_t kExecutableFormatMetal =
-    iree_hal_make_executable_format("MTLE");
-
-MetalPipelineCache::MetalPipelineCache(id<MTLDevice> device) : metal_device_([device retain]) {}
-
-MetalPipelineCache::~MetalPipelineCache() { [metal_device_ release]; }
-
-bool MetalPipelineCache::CanPrepareFormat(iree_hal_executable_format_t format) const {
-  return format == kExecutableFormatMetal;
-}
-
-StatusOr<ref_ptr<Executable>> MetalPipelineCache::PrepareExecutable(
-    ExecutableLayout* executable_layout, iree_hal_executable_caching_mode_t mode,
-    iree_const_byte_span_t executable_data) {
-  IREE_TRACE_SCOPE0("MetalPipelineCache::PrepareExecutable");
-
-  // Create the Metal library (which may itself own many pipeline states).
-  IREE_ASSIGN_OR_RETURN(auto executable, MetalKernelLibrary::Create(metal_device_, mode, executable_data));
-
-  return executable;
-}
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
diff --git a/iree/hal/metal/metal_shared_event.h b/iree/hal/metal/metal_shared_event.h
deleted file mode 100644
index 35c4926..0000000
--- a/iree/hal/metal/metal_shared_event.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// 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_METAL_METAL_SHARED_EVENT_H_
-#define IREE_HAL_METAL_METAL_SHARED_EVENT_H_
-
-#import <Metal/Metal.h>
-
-#include "absl/synchronization/mutex.h"
-#include "iree/hal/cc/semaphore.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-// A semaphore implementation for Metal that directly wraps a MTLSharedEvent.
-class MetalSharedEvent final : public Semaphore {
- public:
-  // Creates a MetalSharedEvent with the given |initial_value|.
-  static StatusOr<ref_ptr<Semaphore>> Create(
-      id<MTLDevice> device, MTLSharedEventListener* event_listener,
-      uint64_t initial_value);
-
-  ~MetalSharedEvent() override;
-
-  id<MTLSharedEvent> handle() const { return metal_handle_; }
-
-  StatusOr<uint64_t> Query() override;
-
-  Status Signal(uint64_t value) override;
-
-  void Fail(Status status) override;
-
-  Status Wait(uint64_t value, Time deadline_ns) override;
-
- private:
-  MetalSharedEvent(id<MTLDevice> device, MTLSharedEventListener* event_listener,
-                   uint64_t initial_value);
-
-  id<MTLSharedEvent> metal_handle_;
-
-  // An event listener for waiting and signaling. Its lifetime is managed by
-  // the parent device.
-  MTLSharedEventListener* event_listener_;
-
-  // NOTE: the MTLSharedEvent is the source of truth. We only need to access
-  // this status (and thus take the lock) when we want to either signal failure
-  // or query the status in the case of the semaphore being set to UINT64_MAX.
-  mutable absl::Mutex status_mutex_;
-  Status status_ ABSL_GUARDED_BY(status_mutex_);
-};
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
-
-#endif  // IREE_HAL_METAL_METAL_SHARED_EVENT_H_
diff --git a/iree/hal/metal/metal_shared_event.mm b/iree/hal/metal/metal_shared_event.mm
deleted file mode 100644
index 325c30a..0000000
--- a/iree/hal/metal/metal_shared_event.mm
+++ /dev/null
@@ -1,108 +0,0 @@
-// 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/metal/metal_shared_event.h"
-
-#include "iree/base/status.h"
-#include "iree/base/tracing.h"
-#include "iree/hal/metal/dispatch_time_util.h"
-
-namespace iree {
-namespace hal {
-namespace metal {
-
-// static
-StatusOr<ref_ptr<Semaphore>> MetalSharedEvent::Create(id<MTLDevice> device,
-                                                      MTLSharedEventListener* event_listener,
-                                                      uint64_t initial_value) {
-  return assign_ref(new MetalSharedEvent(device, event_listener, initial_value));
-}
-
-MetalSharedEvent::MetalSharedEvent(id<MTLDevice> device, MTLSharedEventListener* event_listener,
-                                   uint64_t initial_value)
-    : metal_handle_([device newSharedEvent]), event_listener_(event_listener) {
-  IREE_TRACE_SCOPE0("MetalSharedEvent::ctor");
-  metal_handle_.signaledValue = initial_value;
-}
-
-MetalSharedEvent::~MetalSharedEvent() {
-  IREE_TRACE_SCOPE0("MetalSharedEvent::dtor");
-  [metal_handle_ release];
-}
-
-StatusOr<uint64_t> MetalSharedEvent::Query() {
-  IREE_TRACE_SCOPE0("MetalSharedEvent::Query");
-  uint64_t value = metal_handle_.signaledValue;
-  if (value == UINT64_MAX) {
-    absl::MutexLock lock(&status_mutex_);
-    return status_;
-  }
-  return value;
-}
-
-Status MetalSharedEvent::Signal(uint64_t value) {
-  IREE_TRACE_SCOPE0("MetalSharedEvent::Signal");
-  metal_handle_.signaledValue = value;
-  return OkStatus();
-}
-
-void MetalSharedEvent::Fail(Status status) {
-  IREE_TRACE_SCOPE0("MetalSharedEvent::Fail");
-  absl::MutexLock lock(&status_mutex_);
-  status_ = std::move(status);
-  metal_handle_.signaledValue = UINT64_MAX;
-}
-
-Status MetalSharedEvent::Wait(uint64_t value, Time deadline_ns) {
-  IREE_TRACE_SCOPE0("MetalSharedEvent::Wait");
-
-  Duration duration_ns = DeadlineToRelativeTimeoutNanos(deadline_ns);
-  dispatch_time_t timeout = DurationToDispatchTime(duration_ns);
-
-  // Quick path for impatient waiting to avoid all the overhead of dispatch queues and semaphores.
-  if (duration_ns == ZeroDuration()) {
-    if (metal_handle_.signaledValue < value) {
-      return DeadlineExceededErrorBuilder(IREE_LOC) << "Deadline exceeded waiting for semaphores";
-    }
-    return OkStatus();
-  }
-
-  // Theoretically we don't really need to mark the semaphore handle as __block given that the
-  // handle itself is not modified and there is only one block and it will copy the handle.
-  // But marking it as __block serves as good documentation purpose.
-  __block dispatch_semaphore_t work_done = dispatch_semaphore_create(0);
-
-  // Use a listener to the MTLSharedEvent to notify us when the work is done on GPU by signaling a
-  // semaphore. The signaling will happen in a new dispatch queue; the current thread will wait on
-  // the semaphore.
-  [metal_handle_ notifyListener:event_listener_
-                        atValue:value
-                          block:^(id<MTLSharedEvent>, uint64_t) {
-                            dispatch_semaphore_signal(work_done);
-                          }];
-
-  long timed_out = dispatch_semaphore_wait(work_done, timeout);
-
-  dispatch_release(work_done);
-
-  if (timed_out) {
-    return DeadlineExceededErrorBuilder(IREE_LOC)
-           << "Deadline exceeded waiting for dispatch_semaphore_t";
-  }
-  return OkStatus();
-}
-
-}  // namespace metal
-}  // namespace hal
-}  // namespace iree
diff --git a/iree/hal/metal/registration/BUILD.bazel b/iree/hal/metal/registration/BUILD.bazel
deleted file mode 100644
index 6a87e62..0000000
--- a/iree/hal/metal/registration/BUILD.bazel
+++ /dev/null
@@ -1,52 +0,0 @@
-# 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.
-
-load("//iree:build_defs.oss.bzl", "iree_cmake_extra_content")
-
-package(
-    default_visibility = ["//visibility:public"],
-    features = ["layering_check"],
-    licenses = ["notice"],  # Apache 2.0
-)
-
-iree_cmake_extra_content(
-    content = """
-if(${IREE_HAL_DRIVER_METAL})
-""",
-    inline = True,
-)
-
-cc_library(
-    name = "registration",
-    srcs = ["driver_module.cc"],
-    hdrs = ["driver_module.h"],
-    defines = [
-        "IREE_HAL_HAVE_METAL_DRIVER_MODULE=1",
-    ],
-    deps = [
-        "//iree/base:flags",
-        "//iree/base:status",
-        "//iree/base:tracing",
-        "//iree/hal:api",
-        "//iree/hal/metal",
-        "@com_google_absl//absl/flags:flag",
-    ],
-)
-
-iree_cmake_extra_content(
-    content = """
-endif()
-""",
-    inline = True,
-)
diff --git a/iree/hal/metal/registration/CMakeLists.txt b/iree/hal/metal/registration/CMakeLists.txt
deleted file mode 100644
index 90033d6..0000000
--- a/iree/hal/metal/registration/CMakeLists.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-# 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_add_all_subdirs()
-
-if(${IREE_HAL_DRIVER_METAL})
-
-iree_cc_library(
-  NAME
-    registration
-  HDRS
-    "driver_module.h"
-  SRCS
-    "driver_module.cc"
-  DEPS
-    absl::flags
-    iree::base::flags
-    iree::base::status
-    iree::base::tracing
-    iree::hal::api
-    iree::hal::metal
-  DEFINES
-    "IREE_HAL_HAVE_METAL_DRIVER_MODULE=1"
-  PUBLIC
-)
-
-endif()
diff --git a/iree/hal/metal/registration/driver_module.cc b/iree/hal/metal/registration/driver_module.cc
deleted file mode 100644
index 1a9da7d..0000000
--- a/iree/hal/metal/registration/driver_module.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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/metal/registration/driver_module.h"
-
-#include <inttypes.h>
-
-#include "absl/flags/flag.h"
-#include "iree/base/flags.h"
-#include "iree/hal/metal/metal_driver.h"
-
-ABSL_FLAG(bool, metal_capture, false, "Enables capturing Metal commands.");
-ABSL_FLAG(
-    std::string, metal_capture_to_file, "",
-    "Full path to store the GPU trace file (empty means capture to Xcode)");
-
-#define IREE_HAL_METAL_DRIVER_ID 0x4D544C31u  // MTL1
-
-static iree_status_t iree_hal_metal_driver_factory_enumerate(
-    void* self, const iree_hal_driver_info_t** out_driver_infos,
-    iree_host_size_t* out_driver_info_count) {
-  // NOTE: we could query supported metal versions or featuresets here.
-  static const iree_hal_driver_info_t driver_infos[1] = {{
-      /*driver_id=*/IREE_HAL_METAL_DRIVER_ID,
-      /*driver_name=*/iree_make_cstring_view("metal"),
-      /*full_name=*/iree_make_cstring_view("Apple Metal GPU"),
-  }};
-  *out_driver_info_count = IREE_ARRAYSIZE(driver_infos);
-  *out_driver_infos = driver_infos;
-  return iree_ok_status();
-}
-
-static iree_status_t iree_hal_metal_driver_factory_try_create(
-    void* self, iree_hal_driver_id_t driver_id, iree_allocator_t allocator,
-    iree_hal_driver_t** out_driver) {
-  if (driver_id != IREE_HAL_METAL_DRIVER_ID) {
-    return iree_make_status(IREE_STATUS_UNAVAILABLE,
-                            "no driver with ID %016" PRIu64
-                            " is provided by this factory",
-                            driver_id);
-  }
-  iree::hal::metal::MetalDriverOptions options;
-  options.enable_capture = absl::GetFlag(FLAGS_metal_capture);
-  options.capture_file = absl::GetFlag(FLAGS_metal_capture_to_file);
-  IREE_ASSIGN_OR_RETURN(auto driver,
-                        iree::hal::metal::MetalDriver::Create(options));
-  *out_driver = reinterpret_cast<iree_hal_driver_t*>(driver.release());
-  return iree_ok_status();
-}
-
-IREE_API_EXPORT iree_status_t IREE_API_CALL
-iree_hal_metal_driver_module_register(iree_hal_driver_registry_t* registry) {
-  static const iree_hal_driver_factory_t factory = {
-      /*self=*/NULL,
-      iree_hal_metal_driver_factory_enumerate,
-      iree_hal_metal_driver_factory_try_create,
-  };
-  return iree_hal_driver_registry_register_factory(registry, &factory);
-}
diff --git a/iree/hal/metal/registration/driver_module.h b/iree/hal/metal/registration/driver_module.h
deleted file mode 100644
index edb6c05..0000000
--- a/iree/hal/metal/registration/driver_module.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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_METAL_REGISTRATION_DRIVER_MODULE_H_
-#define IREE_HAL_METAL_REGISTRATION_DRIVER_MODULE_H_
-
-#include "iree/hal/api.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif  // __cplusplus
-
-IREE_API_EXPORT iree_status_t IREE_API_CALL
-iree_hal_metal_driver_module_register(iree_hal_driver_registry_t* registry);
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif  // __cplusplus
-
-#endif  // IREE_HAL_METAL_REGISTRATION_DRIVER_MODULE_H_
diff --git a/iree/test/e2e/xla_ops/BUILD b/iree/test/e2e/xla_ops/BUILD
index a4abcb5..2693834 100644
--- a/iree/test/e2e/xla_ops/BUILD
+++ b/iree/test/e2e/xla_ops/BUILD
@@ -34,45 +34,6 @@
 )
 
 iree_check_single_backend_test_suite(
-    name = "check_metal-spirv_metal",
-    srcs = [
-        "abs.mlir",
-        "add.mlir",
-        "broadcast.mlir",
-        "broadcast_add.mlir",
-        "broadcast_in_dim.mlir",
-        "clamp.mlir",
-        "compare.mlir",
-        "constant.mlir",
-        "convert.mlir",
-        "cosine.mlir",
-        "divide.mlir",
-        "exponential.mlir",
-        "gather.mlir",
-        "log.mlir",
-        "log_plus_one.mlir",
-        "maximum.mlir",
-        "minimum.mlir",
-        "multiply.mlir",
-        "negate.mlir",
-        "remainder.mlir",
-        "reshape.mlir",
-        "rsqrt.mlir",
-        "select.mlir",
-        "sine.mlir",
-        "slice.mlir",
-        "sqrt.mlir",
-        "subtract.mlir",
-        "tanh.mlir",
-        "torch_index_select.mlir",
-        "transpose.mlir",
-        "while.mlir",
-    ],
-    driver = "metal",
-    target_backend = "metal-spirv",
-)
-
-iree_check_single_backend_test_suite(
     name = "check_vulkan-spirv_vulkan",
     srcs = [
         "abs.mlir",
@@ -177,7 +138,6 @@
     name = "check",
     tests = [
         ":check_dylib-llvm-aot_dylib",
-        ":check_metal-spirv_metal",
         ":check_vmla_vmla",
         ":check_vulkan-spirv_vulkan",
     ],
diff --git a/iree/test/e2e/xla_ops/CMakeLists.txt b/iree/test/e2e/xla_ops/CMakeLists.txt
index 0c8978d..65c4d93 100644
--- a/iree/test/e2e/xla_ops/CMakeLists.txt
+++ b/iree/test/e2e/xla_ops/CMakeLists.txt
@@ -28,47 +28,6 @@
 
 iree_check_single_backend_test_suite(
   NAME
-    check_metal-spirv_metal
-  SRCS
-    "abs.mlir"
-    "add.mlir"
-    "broadcast.mlir"
-    "broadcast_add.mlir"
-    "broadcast_in_dim.mlir"
-    "clamp.mlir"
-    "compare.mlir"
-    "constant.mlir"
-    "convert.mlir"
-    "cosine.mlir"
-    "divide.mlir"
-    "exponential.mlir"
-    "gather.mlir"
-    "log.mlir"
-    "log_plus_one.mlir"
-    "maximum.mlir"
-    "minimum.mlir"
-    "multiply.mlir"
-    "negate.mlir"
-    "remainder.mlir"
-    "reshape.mlir"
-    "rsqrt.mlir"
-    "select.mlir"
-    "sine.mlir"
-    "slice.mlir"
-    "sqrt.mlir"
-    "subtract.mlir"
-    "tanh.mlir"
-    "torch_index_select.mlir"
-    "transpose.mlir"
-    "while.mlir"
-  TARGET_BACKEND
-    "metal-spirv"
-  DRIVER
-    "metal"
-)
-
-iree_check_single_backend_test_suite(
-  NAME
     check_vulkan-spirv_vulkan
   SRCS
     "abs.mlir"
diff --git a/iree/test/e2e/xla_ops/partial/BUILD b/iree/test/e2e/xla_ops/partial/BUILD
index 9adea0c..3228fcd 100644
--- a/iree/test/e2e/xla_ops/partial/BUILD
+++ b/iree/test/e2e/xla_ops/partial/BUILD
@@ -39,14 +39,6 @@
 )
 
 iree_check_single_backend_test_suite(
-    name = "check_metal-spirv_metal",
-    srcs = [
-    ],
-    driver = "metal",
-    target_backend = "metal-spirv",
-)
-
-iree_check_single_backend_test_suite(
     name = "check_vulkan-spirv_vulkan",
     srcs = [
     ],
@@ -66,7 +58,6 @@
     name = "check",
     tests = [
         ":check_dylib-llvm-aot_dylib",
-        ":check_metal-spirv_metal",
         ":check_vmla_vmla",
         ":check_vulkan-spirv_vulkan",
     ],
diff --git a/iree/test/e2e/xla_ops/partial/CMakeLists.txt b/iree/test/e2e/xla_ops/partial/CMakeLists.txt
index 7cc0f00..43b2bba 100644
--- a/iree/test/e2e/xla_ops/partial/CMakeLists.txt
+++ b/iree/test/e2e/xla_ops/partial/CMakeLists.txt
@@ -28,15 +28,6 @@
 
 iree_check_single_backend_test_suite(
   NAME
-    check_metal-spirv_metal
-  TARGET_BACKEND
-    "metal-spirv"
-  DRIVER
-    "metal"
-)
-
-iree_check_single_backend_test_suite(
-  NAME
     check_vulkan-spirv_vulkan
   TARGET_BACKEND
     "vulkan-spirv"