Separate HAL driver registration with the threading (#7184)

* Separate HAL driver registration with the threading

Have synced drivers for {Dylib, VMVX}, and the global flags of
`IREE_HAL_DRIVER_{DYLIB, VMVX}_SYNC`, so the HAL driver registration can be
done with threadless configuration.

Enable iree/runtime libraries to be built in threadless configuration.

Clean up the usage of IREE_ENABLE_THREADING flag in iree/hal and iree/samples

Part of the cleanup for https://github.com/google/iree/issues/4298

* Make `dylib-sync` driver embedded library compatible only

This allows iree/runtime can really built in the bare-metal config
without the dynamic_library dependency, and the `-ldl` linker option.

This also removes the driver dependency in iree/samples/{dynamic_shapes,
variable_and_state} examples.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6fd62be..ae4400c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -104,7 +104,9 @@
 set(IREE_ALL_HAL_DRIVERS
   Cuda
   DyLib
+  Dylib_Sync
   VMVX
+  VMVX_Sync
   Vulkan
 )
 
diff --git a/build_tools/benchmarks/common/benchmark_definition.py b/build_tools/benchmarks/common/benchmark_definition.py
index d6e9aa4..75c01a2 100644
--- a/build_tools/benchmarks/common/benchmark_definition.py
+++ b/build_tools/benchmarks/common/benchmark_definition.py
@@ -29,6 +29,7 @@
     "iree-dylib": "IREE-Dylib",
     "iree-dylib-sync": "IREE-Dylib-Sync",
     "iree-vmvx": "IREE-VMVX",
+    "iree-vmvx-sync": "IREE-VMVX-Sync",
     "iree-vulkan": "IREE-Vulkan",
 }
 
@@ -190,7 +191,7 @@
       target_arch = "GPU-" + self.device_info.gpu_name
       driver = IREE_DRIVER_NAME_MAP[self.runner]
     elif (self.runner == "iree-dylib" or self.runner == "iree-dylib-sync" or
-          self.runner == "iree-vmvx"):
+          self.runner == "iree-vmvx" or self.runner == "iree-vmvx-sync"):
       target_arch = "CPU-" + self.device_info.get_arm_arch_revision()
       driver = IREE_DRIVER_NAME_MAP[self.runner]
     else:
diff --git a/build_tools/cmake/iree_macros.cmake b/build_tools/cmake/iree_macros.cmake
index cb90828..3dccb5a 100644
--- a/build_tools/cmake/iree_macros.cmake
+++ b/build_tools/cmake/iree_macros.cmake
@@ -298,7 +298,8 @@
   if(NOT "${IREE_TARGET_BACKEND_VULKAN-SPIRV}" OR NOT "${IREE_HAL_DRIVER_VULKAN}")
     set_property(TEST ${TEST_NAME} APPEND PROPERTY ENVIRONMENT "IREE_VULKAN_DISABLE=1")
   endif()
-  if(NOT "${IREE_TARGET_BACKEND_DYLIB-LLVM-AOT}" OR NOT "${IREE_HAL_DRIVER_DYLIB}")
+  if(NOT "${IREE_TARGET_BACKEND_DYLIB-LLVM-AOT}" OR NOT "${IREE_HAL_DRIVER_DYLIB}"
+     OR NOT "${IREE_HAL_DRIVER_DYLIB_SYNC}")
     set_property(TEST ${TEST_NAME} APPEND PROPERTY ENVIRONMENT "IREE_LLVMAOT_DISABLE=1")
   endif()
 endfunction()
diff --git a/build_tools/cmake/riscv.toolchain.cmake b/build_tools/cmake/riscv.toolchain.cmake
index 3f6954e..4394e76 100644
--- a/build_tools/cmake/riscv.toolchain.cmake
+++ b/build_tools/cmake/riscv.toolchain.cmake
@@ -47,13 +47,12 @@
   set(CMAKE_C_EXTENSIONS OFF)     # Force the usage of _ISOC11_SOURCE
   set(IREE_BUILD_BINDINGS_TFLITE OFF CACHE BOOL "" FORCE)
   set(IREE_BUILD_BINDINGS_TFLITE_JAVA OFF CACHE BOOL "" FORCE)
-  set(IREE_HAL_DRIVERS_TO_BUILD "Dylib;VMVX" CACHE STRING "" FORCE)
-  set(IREE_TARGET_BACKENDS_TO_BUILD "DYLIB-LLVM-AOT;VMVX" CACHE STRING "" FORCE)
+  set(IREE_HAL_DRIVERS_TO_BUILD "Dylib_sync;VMVX_sync" CACHE STRING "" FORCE)
   set(CMAKE_SYSTEM_LIBRARY_PATH "${RISCV_TOOLCHAIN_ROOT}/riscv32-unknown-elf/lib")
   set(IREE_ENABLE_THREADING OFF CACHE BOOL "" FORCE)
   set(RISCV_COMPILER_FLAGS "${RISCV_COMPILER_FLAGS} -march=rv32imf -mabi=ilp32 -DIREE_PLATFORM_GENERIC=1 -DIREE_SYNCHRONIZATION_DISABLE_UNSAFE=1 \
       -DIREE_FILE_IO_ENABLE=0 -DIREE_TIME_NOW_FN=\"\{ return 0; \}\" -DIREE_DEVICE_SIZE_T=uint32_t -DPRIdsz=PRIu32")
-  set(RISCV_LINKER_FLAGS "${RISCV_LINKER_FLAGS} -lstdc++ -lm")
+  set(RISCV_LINKER_FLAGS "${RISCV_LINKER_FLAGS} -lm")
 endif()
 
 set(CMAKE_C_FLAGS             "${RISCV_COMPILER_FLAGS} ${CMAKE_C_FLAGS}")
diff --git a/docs/website/docs/deployment-configurations/bare-metal.md b/docs/website/docs/deployment-configurations/bare-metal.md
index d4a7342..0934807 100644
--- a/docs/website/docs/deployment-configurations/bare-metal.md
+++ b/docs/website/docs/deployment-configurations/bare-metal.md
@@ -84,8 +84,8 @@
 operating system
 * `set(IREE_BINDINGS_TFLITE OFF)`: Disable the TFLite binding support
 * `set(IREE_ENABLE_THREADING OFF)`: Disable multi-thread library support
-* `set(IREE_HAL_DRIVERS_TO_BUILD "Dylib;VMVX")`: Build only the dynamic library
-and VMVX runtime HAL drivers
+* `set(IREE_HAL_DRIVERS_TO_BUILD "Dylib_Sync;VMVX_Sync")`: Build only the
+dynamic library and VMVX runtime synchronous HAL drivers
 * `set(IREE_BUILD_TESTS OFF)`: Disable tests until IREE supports running them on
 bare-metal platforms
 * `set(IREE_BUILD_SAMPLES ON)`: Build
diff --git a/iree/hal/cts/command_buffer_test.cc b/iree/hal/cts/command_buffer_test.cc
index cad3ad0..e14ad6d 100644
--- a/iree/hal/cts/command_buffer_test.cc
+++ b/iree/hal/cts/command_buffer_test.cc
@@ -33,6 +33,7 @@
   CommandBufferTest() {
     // TODO(#4680): command buffer recording so that this can run on sync HAL.
     SkipUnavailableDriver("dylib-sync");
+    SkipUnavailableDriver("vmvx-sync");
   }
 
  protected:
diff --git a/iree/hal/cts/event_test.cc b/iree/hal/cts/event_test.cc
index 67b9920..5344215 100644
--- a/iree/hal/cts/event_test.cc
+++ b/iree/hal/cts/event_test.cc
@@ -25,6 +25,7 @@
   EventTest() {
     // TODO(#4680): command buffer recording so that this can run on sync HAL.
     SkipUnavailableDriver("dylib-sync");
+    SkipUnavailableDriver("vmvx-sync");
   }
 };
 
diff --git a/iree/hal/cts/semaphore_submission_test.cc b/iree/hal/cts/semaphore_submission_test.cc
index 0b2d426..b39d5b9 100644
--- a/iree/hal/cts/semaphore_submission_test.cc
+++ b/iree/hal/cts/semaphore_submission_test.cc
@@ -27,6 +27,7 @@
     SkipUnavailableDriver("cuda");
     // TODO(#4680): command buffer recording so that this can run on sync HAL.
     SkipUnavailableDriver("dylib-sync");
+    SkipUnavailableDriver("vmvx-sync");
   }
 };
 
diff --git a/iree/hal/drivers/BUILD b/iree/hal/drivers/BUILD
index b070f20..e383732 100644
--- a/iree/hal/drivers/BUILD
+++ b/iree/hal/drivers/BUILD
@@ -24,6 +24,7 @@
         "//iree/hal/dylib/registration",
         "//iree/hal/dylib/registration:sync",
         "//iree/hal/vmvx/registration",
+        "//iree/hal/vmvx/registration:sync",
         "//iree/hal/vulkan/registration",
     ] + IREE_CUDA_DEPS,
 )
diff --git a/iree/hal/drivers/CMakeLists.txt b/iree/hal/drivers/CMakeLists.txt
index aa5f92f..b7f7770 100644
--- a/iree/hal/drivers/CMakeLists.txt
+++ b/iree/hal/drivers/CMakeLists.txt
@@ -6,25 +6,22 @@
 
 # Doesn't use bazel_to_cmake because of custom configuration vars
 
-# Driver registration has implicit thread dependency from task executor.
-
-# TODO(#4298): Separate HAL driver registration from threading.
-if(NOT ${IREE_ENABLE_THREADING})
-  return()
-endif()
-
 set(IREE_HAL_DRIVER_MODULES)
 if(${IREE_HAL_DRIVER_CUDA})
   list(APPEND IREE_HAL_DRIVER_MODULES iree::hal::cuda::registration)
 endif()
 if(${IREE_HAL_DRIVER_DYLIB})
   list(APPEND IREE_HAL_DRIVER_MODULES iree::hal::dylib::registration)
-  # TODO(benvanik): add a IREE_HAL_DRIVER_DYLIB_SYNC or global flag.
+endif()
+if(${IREE_HAL_DRIVER_DYLIB_SYNC})
   list(APPEND IREE_HAL_DRIVER_MODULES iree::hal::dylib::registration::sync)
 endif()
 if(${IREE_HAL_DRIVER_VMVX})
   list(APPEND IREE_HAL_DRIVER_MODULES iree::hal::vmvx::registration)
 endif()
+if(${IREE_HAL_DRIVER_VMVX_SYNC})
+  list(APPEND IREE_HAL_DRIVER_MODULES iree::hal::vmvx::registration::sync)
+endif()
 if(${IREE_HAL_DRIVER_VULKAN})
   list(APPEND IREE_HAL_DRIVER_MODULES iree::hal::vulkan::registration)
 endif()
diff --git a/iree/hal/drivers/init.c b/iree/hal/drivers/init.c
index 552df62..dcd715b 100644
--- a/iree/hal/drivers/init.c
+++ b/iree/hal/drivers/init.c
@@ -24,6 +24,10 @@
 #include "iree/hal/vmvx/registration/driver_module.h"
 #endif  // IREE_HAL_HAVE_VMVX_DRIVER_MODULE
 
+#if defined(IREE_HAL_HAVE_VMVX_SYNC_DRIVER_MODULE)
+#include "iree/hal/vmvx/registration/driver_module_sync.h"
+#endif  // IREE_HAL_HAVE_VMVX_SYNC_DRIVER_MODULE
+
 #if defined(IREE_HAL_HAVE_VULKAN_DRIVER_MODULE)
 #include "iree/hal/vulkan/registration/driver_module.h"
 #endif  // IREE_HAL_HAVE_VULKAN_DRIVER_MODULE
@@ -56,6 +60,11 @@
       z0, iree_hal_vmvx_driver_module_register(registry));
 #endif  // IREE_HAL_HAVE_VMVX_DRIVER_MODULE
 
+#if defined(IREE_HAL_HAVE_VMVX_SYNC_DRIVER_MODULE)
+  IREE_RETURN_AND_END_ZONE_IF_ERROR(
+      z0, iree_hal_vmvx_sync_driver_module_register(registry));
+#endif  // IREE_HAL_HAVE_VMVX_SYNC_DRIVER_MODULE
+
 #if defined(IREE_HAL_HAVE_VULKAN_DRIVER_MODULE)
   IREE_RETURN_AND_END_ZONE_IF_ERROR(
       z0, iree_hal_vulkan_driver_module_register(registry));
diff --git a/iree/hal/dylib/registration/BUILD b/iree/hal/dylib/registration/BUILD
index 3c0dce7..4d68498 100644
--- a/iree/hal/dylib/registration/BUILD
+++ b/iree/hal/dylib/registration/BUILD
@@ -14,14 +14,7 @@
 
 iree_cmake_extra_content(
     content = """
-if(NOT ${IREE_HAL_DRIVER_DYLIB})
-  return()
-endif()
-
-# TODO(#4298): Separate HAL driver registration from threading.
-if(NOT ${IREE_ENABLE_THREADING})
-  return()
-endif()
+if(${IREE_HAL_DRIVER_DYLIB})
 """,
     inline = True,
 )
@@ -45,6 +38,15 @@
     ],
 )
 
+iree_cmake_extra_content(
+    content = """
+endif()
+
+if(${IREE_HAL_DRIVER_DYLIB_SYNC})
+""",
+    inline = True,
+)
+
 cc_library(
     name = "sync",
     srcs = ["driver_module_sync.c"],
@@ -57,6 +59,13 @@
         "//iree/hal",
         "//iree/hal/local",
         "//iree/hal/local:sync_driver",
-        "//iree/hal/local/loaders:system_library_loader",
+        "//iree/hal/local/loaders:embedded_library_loader",
     ],
 )
+
+iree_cmake_extra_content(
+    content = """
+endif()
+""",
+    inline = True,
+)
diff --git a/iree/hal/dylib/registration/CMakeLists.txt b/iree/hal/dylib/registration/CMakeLists.txt
index 03e3ea5..761607f 100644
--- a/iree/hal/dylib/registration/CMakeLists.txt
+++ b/iree/hal/dylib/registration/CMakeLists.txt
@@ -10,14 +10,7 @@
 
 iree_add_all_subdirs()
 
-if(NOT ${IREE_HAL_DRIVER_DYLIB})
-  return()
-endif()
-
-# TODO(#4298): Separate HAL driver registration from threading.
-if(NOT ${IREE_ENABLE_THREADING})
-  return()
-endif()
+if(${IREE_HAL_DRIVER_DYLIB})
 
 iree_cc_library(
   NAME
@@ -40,6 +33,10 @@
   PUBLIC
 )
 
+endif()
+
+if(${IREE_HAL_DRIVER_DYLIB_SYNC})
+
 iree_cc_library(
   NAME
     sync
@@ -51,11 +48,13 @@
     iree::base
     iree::hal
     iree::hal::local
-    iree::hal::local::loaders::system_library_loader
+    iree::hal::local::loaders::embedded_library_loader
     iree::hal::local::sync_driver
   DEFINES
     "IREE_HAL_HAVE_DYLIB_SYNC_DRIVER_MODULE=1"
   PUBLIC
 )
 
+endif()
+
 ### BAZEL_TO_CMAKE_PRESERVES_ALL_CONTENT_BELOW_THIS_LINE ###
diff --git a/iree/hal/dylib/registration/driver_module_sync.c b/iree/hal/dylib/registration/driver_module_sync.c
index 414a708..3407a61 100644
--- a/iree/hal/dylib/registration/driver_module_sync.c
+++ b/iree/hal/dylib/registration/driver_module_sync.c
@@ -11,7 +11,7 @@
 
 #include "iree/base/api.h"
 #include "iree/hal/local/executable_loader.h"
-#include "iree/hal/local/loaders/system_library_loader.h"
+#include "iree/hal/local/loaders/embedded_library_loader.h"
 #include "iree/hal/local/sync_device.h"
 #include "iree/hal/local/sync_driver.h"
 
@@ -28,7 +28,8 @@
   static const iree_hal_driver_info_t default_driver_info = {
       .driver_id = IREE_HAL_DYLIB_SYNC_DRIVER_ID,
       .driver_name = iree_string_view_literal("dylib-sync"),
-      .full_name = iree_string_view_literal("AOT compiled dynamic libraries"),
+      .full_name = iree_string_view_literal(
+          "synchronous AOT compiled dynamic embedded libraries"),
   };
   *out_driver_info_count = 1;
   *out_driver_infos = &default_driver_info;
@@ -48,10 +49,12 @@
   iree_hal_sync_device_params_t default_params;
   iree_hal_sync_device_params_initialize(&default_params);
 
-  iree_hal_executable_loader_t* dylib_loader = NULL;
-  iree_status_t status = iree_hal_system_library_loader_create(
-      iree_hal_executable_import_provider_null(), allocator, &dylib_loader);
-  iree_hal_executable_loader_t* loaders[1] = {dylib_loader};
+  iree_status_t status = iree_ok_status();
+  iree_hal_executable_loader_t* loaders[1] = {NULL};
+  if (iree_status_is_ok(status)) {
+    status = iree_hal_embedded_library_loader_create(
+        iree_hal_executable_import_provider_null(), allocator, &loaders[0]);
+  }
 
   if (iree_status_is_ok(status)) {
     status = iree_hal_sync_driver_create(
@@ -59,7 +62,7 @@
         loaders, allocator, out_driver);
   }
 
-  iree_hal_executable_loader_release(dylib_loader);
+  iree_hal_executable_loader_release(loaders[0]);
   return status;
 }
 
diff --git a/iree/hal/local/BUILD b/iree/hal/local/BUILD
index db652f7..2e94402 100644
--- a/iree/hal/local/BUILD
+++ b/iree/hal/local/BUILD
@@ -111,7 +111,8 @@
 
 iree_cmake_extra_content(
     content = """
-if(NOT ${IREE_ENABLE_THREADING})
+# task_driver is used by asynchronuous drivers.
+if(NOT (${IREE_HAL_DRIVER_DYLIB} OR ${IREE_HAL_DRIVER_VMVX}))
   return()
 endif()
 """,
diff --git a/iree/hal/local/CMakeLists.txt b/iree/hal/local/CMakeLists.txt
index 3fec374..4406b17 100644
--- a/iree/hal/local/CMakeLists.txt
+++ b/iree/hal/local/CMakeLists.txt
@@ -101,7 +101,8 @@
   PUBLIC
 )
 
-if(NOT ${IREE_ENABLE_THREADING})
+# task_driver is used by asynchronuous drivers.
+if(NOT (${IREE_HAL_DRIVER_DYLIB} OR ${IREE_HAL_DRIVER_VMVX}))
   return()
 endif()
 
diff --git a/iree/hal/local/loaders/BUILD b/iree/hal/local/loaders/BUILD
index 0f354e3..b902bde 100644
--- a/iree/hal/local/loaders/BUILD
+++ b/iree/hal/local/loaders/BUILD
@@ -71,7 +71,7 @@
 
 iree_cmake_extra_content(
     content = """
-if(${IREE_HAL_DRIVER_VMVX})
+if(${IREE_HAL_DRIVER_VMVX} OR ${IREE_HAL_DRIVER_VMVX_SYNC})
 """,
     inline = True,
 )
diff --git a/iree/hal/local/loaders/CMakeLists.txt b/iree/hal/local/loaders/CMakeLists.txt
index 62f5641..05d74b9 100644
--- a/iree/hal/local/loaders/CMakeLists.txt
+++ b/iree/hal/local/loaders/CMakeLists.txt
@@ -70,7 +70,7 @@
   PUBLIC
 )
 
-if(${IREE_HAL_DRIVER_VMVX})
+if(${IREE_HAL_DRIVER_VMVX} OR ${IREE_HAL_DRIVER_VMVX_SYNC})
 
 iree_cc_library(
   NAME
diff --git a/iree/hal/vmvx/registration/BUILD b/iree/hal/vmvx/registration/BUILD
index 52597e1..764022f 100644
--- a/iree/hal/vmvx/registration/BUILD
+++ b/iree/hal/vmvx/registration/BUILD
@@ -14,11 +14,6 @@
 
 iree_cmake_extra_content(
     content = """
-# TODO(#4298): Separate HAL driver registration from threading.
-if(NOT ${IREE_ENABLE_THREADING})
-  return()
-endif()
-
 if(${IREE_HAL_DRIVER_VMVX})
 """,
     inline = True,
@@ -45,6 +40,32 @@
 iree_cmake_extra_content(
     content = """
 endif()
+
+if(${IREE_HAL_DRIVER_VMVX_SYNC})
+""",
+    inline = True,
+)
+
+cc_library(
+    name = "sync",
+    srcs = ["driver_module_sync.c"],
+    hdrs = ["driver_module_sync.h"],
+    defines = [
+        "IREE_HAL_HAVE_VMVX_SYNC_DRIVER_MODULE=1",
+    ],
+    deps = [
+        "//iree/base",
+        "//iree/hal",
+        "//iree/hal/local",
+        "//iree/hal/local:sync_driver",
+        "//iree/hal/local/loaders:vmvx_module_loader",
+        "//iree/vm",
+    ],
+)
+
+iree_cmake_extra_content(
+    content = """
+endif()
 """,
     inline = True,
 )
diff --git a/iree/hal/vmvx/registration/CMakeLists.txt b/iree/hal/vmvx/registration/CMakeLists.txt
index 7dac5a2..0067ef0 100644
--- a/iree/hal/vmvx/registration/CMakeLists.txt
+++ b/iree/hal/vmvx/registration/CMakeLists.txt
@@ -10,11 +10,6 @@
 
 iree_add_all_subdirs()
 
-# TODO(#4298): Separate HAL driver registration from threading.
-if(NOT ${IREE_ENABLE_THREADING})
-  return()
-endif()
-
 if(${IREE_HAL_DRIVER_VMVX})
 
 iree_cc_library(
@@ -39,4 +34,27 @@
 
 endif()
 
+if(${IREE_HAL_DRIVER_VMVX_SYNC})
+
+iree_cc_library(
+  NAME
+    sync
+  HDRS
+    "driver_module_sync.h"
+  SRCS
+    "driver_module_sync.c"
+  DEPS
+    iree::base
+    iree::hal
+    iree::hal::local
+    iree::hal::local::loaders::vmvx_module_loader
+    iree::hal::local::sync_driver
+    iree::vm
+  DEFINES
+    "IREE_HAL_HAVE_VMVX_SYNC_DRIVER_MODULE=1"
+  PUBLIC
+)
+
+endif()
+
 ### BAZEL_TO_CMAKE_PRESERVES_ALL_CONTENT_BELOW_THIS_LINE ###
diff --git a/iree/hal/vmvx/registration/driver_module_sync.c b/iree/hal/vmvx/registration/driver_module_sync.c
new file mode 100644
index 0000000..5ab7e0b
--- /dev/null
+++ b/iree/hal/vmvx/registration/driver_module_sync.c
@@ -0,0 +1,82 @@
+// Copyright 2021 The IREE Authors
+//
+// Licensed under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#include "iree/hal/vmvx/registration/driver_module_sync.h"
+
+#include <inttypes.h>
+#include <stddef.h>
+
+#include "iree/base/api.h"
+#include "iree/hal/local/executable_loader.h"
+#include "iree/hal/local/loaders/vmvx_module_loader.h"
+#include "iree/hal/local/sync_device.h"
+#include "iree/hal/local/sync_driver.h"
+#include "iree/vm/api.h"
+
+// TODO(#4298): remove this driver registration and wrapper.
+
+// TODO(benvanik): replace with C flags.
+#define IREE_HAL_VMVX_WORKER_COUNT 0
+#define IREE_HAL_MAX_VMVX_WORKER_COUNT 16
+
+#define IREE_HAL_VMVX_SYNC_DRIVER_ID 0x53564D58u  // SVMX
+
+static iree_status_t iree_hal_vmvx_sync_driver_factory_enumerate(
+    void* self, const iree_hal_driver_info_t** out_driver_infos,
+    iree_host_size_t* out_driver_info_count) {
+  static const iree_hal_driver_info_t driver_infos[1] = {
+      {
+          .driver_id = IREE_HAL_VMVX_SYNC_DRIVER_ID,
+          .driver_name = iree_string_view_literal("vmvx-sync"),
+          .full_name = iree_string_view_literal(
+              "synchronous VM-based reference backend"),
+      },
+  };
+  *out_driver_info_count = IREE_ARRAYSIZE(driver_infos);
+  *out_driver_infos = driver_infos;
+  return iree_ok_status();
+}
+
+static iree_status_t iree_hal_vmvx_sync_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_VMVX_SYNC_DRIVER_ID) {
+    return iree_make_status(IREE_STATUS_UNAVAILABLE,
+                            "no driver with ID %016" PRIu64
+                            " is provided by this factory",
+                            driver_id);
+  }
+
+  iree_vm_instance_t* instance = NULL;
+  IREE_RETURN_IF_ERROR(iree_vm_instance_create(allocator, &instance));
+
+  iree_hal_executable_loader_t* vmvx_loader = NULL;
+  iree_status_t status =
+      iree_hal_vmvx_module_loader_create(instance, allocator, &vmvx_loader);
+  iree_hal_executable_loader_t* loaders[1] = {vmvx_loader};
+
+  // Set parameters for the device created in the next step.
+  iree_hal_sync_device_params_t default_params;
+  iree_hal_sync_device_params_initialize(&default_params);
+  if (iree_status_is_ok(status)) {
+    status = iree_hal_sync_driver_create(
+        iree_make_cstring_view("vmvx"), &default_params,
+        IREE_ARRAYSIZE(loaders), loaders, allocator, out_driver);
+  }
+  iree_hal_executable_loader_release(vmvx_loader);
+  iree_vm_instance_release(instance);
+  return status;
+}
+
+IREE_API_EXPORT iree_status_t iree_hal_vmvx_sync_driver_module_register(
+    iree_hal_driver_registry_t* registry) {
+  static const iree_hal_driver_factory_t factory = {
+      .self = NULL,
+      .enumerate = iree_hal_vmvx_sync_driver_factory_enumerate,
+      .try_create = iree_hal_vmvx_sync_driver_factory_try_create,
+  };
+  return iree_hal_driver_registry_register_factory(registry, &factory);
+}
diff --git a/iree/hal/vmvx/registration/driver_module_sync.h b/iree/hal/vmvx/registration/driver_module_sync.h
new file mode 100644
index 0000000..a73006d
--- /dev/null
+++ b/iree/hal/vmvx/registration/driver_module_sync.h
@@ -0,0 +1,26 @@
+// Copyright 2021 The IREE Authors
+//
+// Licensed under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef IREE_HAL_VMVX_REGISTRATION_DRIVER_MODULE_SYNC_H_
+#define IREE_HAL_VMVX_REGISTRATION_DRIVER_MODULE_SYNC_H_
+
+#include "iree/base/api.h"
+#include "iree/hal/api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+// DEPRECATED: this entire driver will be removed soon.
+// TODO(#3580): remove this entire driver w/ iree_hal_executable_library_t.
+IREE_API_EXPORT iree_status_t
+iree_hal_vmvx_sync_driver_module_register(iree_hal_driver_registry_t* registry);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif  // __cplusplus
+
+#endif  // IREE_HAL_VMVX_REGISTRATION_DRIVER_MODULE_SYNC_H_
diff --git a/iree/runtime/BUILD b/iree/runtime/BUILD
index 0a60db9..1fbfe4c 100644
--- a/iree/runtime/BUILD
+++ b/iree/runtime/BUILD
@@ -4,25 +4,12 @@
 # See https://llvm.org/LICENSE.txt for license information.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
-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 = """
-# iree::hal::drivers dependency requires threading
-# TODO(#4298): Separate HAL driver registration from threading.
-if(NOT ${IREE_ENABLE_THREADING})
-  return()
-endif()
-""",
-    inline = True,
-)
-
 #===------------------------------------------------------------------------===#
 # Public API
 #===------------------------------------------------------------------------===#
diff --git a/iree/runtime/CMakeLists.txt b/iree/runtime/CMakeLists.txt
index 25154e5..71f6556 100644
--- a/iree/runtime/CMakeLists.txt
+++ b/iree/runtime/CMakeLists.txt
@@ -10,12 +10,6 @@
 
 iree_add_all_subdirs()
 
-# iree::hal::drivers dependency requires threading
-# TODO(#4298): Separate HAL driver registration from threading.
-if(NOT ${IREE_ENABLE_THREADING})
-  return()
-endif()
-
 iree_cc_library(
   NAME
     runtime
diff --git a/iree/runtime/demo/BUILD b/iree/runtime/demo/BUILD
index cbf31fc..7d5861a 100644
--- a/iree/runtime/demo/BUILD
+++ b/iree/runtime/demo/BUILD
@@ -19,7 +19,7 @@
 
 iree_cmake_extra_content(
     content = """
-if (NOT ${IREE_BUILD_COMPILER} OR NOT ${IREE_BUILD_TESTS})
+if (NOT ${IREE_HAL_DRIVER_VMVX} OR NOT ${IREE_TARGET_BACKEND_VMVX})
   return()
 endif()
 """,
diff --git a/iree/runtime/demo/CMakeLists.txt b/iree/runtime/demo/CMakeLists.txt
index 0852fd3..e598af9 100644
--- a/iree/runtime/demo/CMakeLists.txt
+++ b/iree/runtime/demo/CMakeLists.txt
@@ -10,7 +10,7 @@
 
 iree_add_all_subdirs()
 
-if (NOT ${IREE_BUILD_COMPILER} OR NOT ${IREE_BUILD_TESTS})
+if (NOT ${IREE_HAL_DRIVER_VMVX} OR NOT ${IREE_TARGET_BACKEND_VMVX})
   return()
 endif()
 
diff --git a/iree/runtime/testdata/BUILD b/iree/runtime/testdata/BUILD
index 383b3ec..18fe363 100644
--- a/iree/runtime/testdata/BUILD
+++ b/iree/runtime/testdata/BUILD
@@ -15,7 +15,7 @@
 
 iree_cmake_extra_content(
     content = """
-if (NOT ${IREE_BUILD_COMPILER} OR NOT ${IREE_BUILD_TESTS})
+if (NOT ${IREE_HAL_DRIVER_VMVX} OR NOT ${IREE_TARGET_BACKEND_VMVX})
   return()
 endif()
 """,
diff --git a/iree/runtime/testdata/CMakeLists.txt b/iree/runtime/testdata/CMakeLists.txt
index da91d45..7090198 100644
--- a/iree/runtime/testdata/CMakeLists.txt
+++ b/iree/runtime/testdata/CMakeLists.txt
@@ -10,7 +10,7 @@
 
 iree_add_all_subdirs()
 
-if (NOT ${IREE_BUILD_COMPILER} OR NOT ${IREE_BUILD_TESTS})
+if (NOT ${IREE_HAL_DRIVER_VMVX} OR NOT ${IREE_TARGET_BACKEND_VMVX})
   return()
 endif()
 
diff --git a/iree/samples/dynamic_shapes/CMakeLists.txt b/iree/samples/dynamic_shapes/CMakeLists.txt
index 9452ead..deaaafd 100644
--- a/iree/samples/dynamic_shapes/CMakeLists.txt
+++ b/iree/samples/dynamic_shapes/CMakeLists.txt
@@ -4,12 +4,6 @@
 # See https://llvm.org/LICENSE.txt for license information.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
-# iree_runtime_runtime -> iree::hal::drivers dependency requires threading
-# TODO(#4298): Separate HAL driver registration from threading.
-if(NOT ${IREE_ENABLE_THREADING})
-  return()
-endif()
-
 set(_NAME "iree_samples_dynamic_shapes")
 add_executable(${_NAME} "")
 target_sources(${_NAME}
diff --git a/iree/samples/simple_embedding/BUILD b/iree/samples/simple_embedding/BUILD
index d6a535f..9688702 100644
--- a/iree/samples/simple_embedding/BUILD
+++ b/iree/samples/simple_embedding/BUILD
@@ -16,7 +16,8 @@
 
 iree_cmake_extra_content(
     content = """
-if(${IREE_HAL_DRIVER_VMVX} AND (${IREE_TARGET_BACKEND_VMVX} OR DEFINED IREE_HOST_BINARY_ROOT))
+if((${IREE_HAL_DRIVER_VMVX} OR ${IREE_HAL_DRIVER_VMVX_SYNC})
+   AND (${IREE_TARGET_BACKEND_VMVX} OR DEFINED IREE_HOST_BINARY_ROOT))
 """,
     inline = True,
 )
@@ -65,7 +66,8 @@
 
 iree_cmake_extra_content(
     content = """
-if(${IREE_HAL_DRIVER_DYLIB} AND (${IREE_TARGET_BACKEND_DYLIB-LLVM-AOT} OR DEFINED IREE_HOST_BINARY_ROOT))
+if((${IREE_HAL_DRIVER_DYLIB} OR ${IREE_HAL_DRIVER_DYLIB_SYNC})
+   AND (${IREE_TARGET_BACKEND_DYLIB-LLVM-AOT} OR DEFINED IREE_HOST_BINARY_ROOT))
 """,
     inline = True,
 )
@@ -187,7 +189,7 @@
 
 iree_cmake_extra_content(
     content = """
-if(${IREE_ENABLE_THREADING})
+if(${IREE_HAL_DRIVER_DYLIB})
 """,
     inline = True,
 )
diff --git a/iree/samples/simple_embedding/CMakeLists.txt b/iree/samples/simple_embedding/CMakeLists.txt
index ab60796..670169b 100644
--- a/iree/samples/simple_embedding/CMakeLists.txt
+++ b/iree/samples/simple_embedding/CMakeLists.txt
@@ -10,7 +10,8 @@
 
 iree_add_all_subdirs()
 
-if(${IREE_HAL_DRIVER_VMVX} AND (${IREE_TARGET_BACKEND_VMVX} OR DEFINED IREE_HOST_BINARY_ROOT))
+if((${IREE_HAL_DRIVER_VMVX} OR ${IREE_HAL_DRIVER_VMVX_SYNC})
+   AND (${IREE_TARGET_BACKEND_VMVX} OR DEFINED IREE_HOST_BINARY_ROOT))
 
 iree_cc_binary(
   NAME
@@ -53,7 +54,8 @@
 
 endif()
 
-if(${IREE_HAL_DRIVER_DYLIB} AND (${IREE_TARGET_BACKEND_DYLIB-LLVM-AOT} OR DEFINED IREE_HOST_BINARY_ROOT))
+if((${IREE_HAL_DRIVER_DYLIB} OR ${IREE_HAL_DRIVER_DYLIB_SYNC})
+   AND (${IREE_TARGET_BACKEND_DYLIB-LLVM-AOT} OR DEFINED IREE_HOST_BINARY_ROOT))
 
 iree_cc_binary(
   NAME
@@ -186,7 +188,7 @@
     ::simple_embedding_embedded_sync
 )
 
-if(${IREE_ENABLE_THREADING})
+if(${IREE_HAL_DRIVER_DYLIB})
 
 iree_cc_binary(
   NAME
diff --git a/iree/samples/variables_and_state/CMakeLists.txt b/iree/samples/variables_and_state/CMakeLists.txt
index e2bb4e5..e6244af 100644
--- a/iree/samples/variables_and_state/CMakeLists.txt
+++ b/iree/samples/variables_and_state/CMakeLists.txt
@@ -4,12 +4,6 @@
 # See https://llvm.org/LICENSE.txt for license information.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
-# iree_runtime_runtime -> iree::hal::drivers dependency requires threading
-# TODO(#4298): Separate HAL driver registration from threading.
-if(NOT ${IREE_ENABLE_THREADING})
-  return()
-endif()
-
 set(_NAME "iree_samples_variables_and_state")
 add_executable(${_NAME} "")
 target_sources(${_NAME}
diff --git a/iree/tools/CMakeLists.txt b/iree/tools/CMakeLists.txt
index 6502a13..6f6719e 100644
--- a/iree/tools/CMakeLists.txt
+++ b/iree/tools/CMakeLists.txt
@@ -6,7 +6,8 @@
 
 # Doesn't use bazel_to_cmake because of various special logic throughout.
 
-# Tools has thread dependency from iree::hal::drivers
+# TODO(#6353)Tools has thread dependency in gtest and benchmark; they should
+# be separated into the runtime tools and compiler tools.
 if(NOT ${IREE_ENABLE_THREADING})
   return()
 endif()