Includes the iree-dialects project in the main IREE build. (#6687)

* Adds a cmake dep on the IREE dialect, which is enough to make sure it is building. Can't actually use it until I also do bazel nonsense.
* Reworks all of IREE to use a unified mechanism for building LLVM external projects (mlir-hlo and iree-dialects).
* Requires mlir-hlo bump to include: https://github.com/tensorflow/mlir-hlo/commit/392824379d2120460be19647952df3866efddd84
* More include hacking. Really needs to be fixed upstream and annoying until then.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d281b8a..e2ea669 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -347,6 +347,10 @@
   # Stash cmake build type in case LLVM messes with it.
   set(_CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}")
 
+  # Add default external projects.
+  iree_add_llvm_external_project(mlir-iree-dialects MLIR_IREE_DIALECTS ${CMAKE_CURRENT_SOURCE_DIR}/llvm-projects/iree-dialects)
+  iree_add_llvm_external_project(mlir-hlo MLIR_HLO ${CMAKE_CURRENT_SOURCE_DIR}/third_party/mlir-hlo)
+
   add_subdirectory("third_party/llvm-project/llvm" EXCLUDE_FROM_ALL)
 
   # Reset CMAKE_BUILD_TYPE to its previous setting.
@@ -366,28 +370,20 @@
     ${CMAKE_CURRENT_BINARY_DIR}/third_party/llvm-project/llvm/tools/mlir/include
   )
 
-  # Avoid globally modifying paths by instead adding the include paths to the
-  # rules that really should have them in the first place.
-  target_include_directories(LLVMSupport PUBLIC
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/third_party/llvm-project/llvm/include>
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/third_party/llvm-project/llvm/include>
-  )
-  target_include_directories(MLIRSupport PUBLIC
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/third_party/llvm-project/mlir/include>
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/third_party/llvm-project/llvm/tools/mlir/include>
-  )
-endif()
-
-# Add bundled mlir-hlo project unless if already provided.
-if(IREE_BUILD_COMPILER)
-  if(TARGET MLIRMhloUtils)
-    message(STATUS "Not adding IREE bundled mlir-hlo project because it is already present")
-  else()
-    message(STATUS "Adding IREE bundled mlir-hlo project")
-    # TODO: Have better sub project detection upstream.
-    set(MHLO_BUILD_EMBEDDED ON)
-    add_subdirectory(third_party/mlir-hlo EXCLUDE_FROM_ALL)
-  endif()
+  function(_hack_llvm_include_paths)
+    set(_common_include_dirs
+      $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/third_party/llvm-project/llvm/include>
+      $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/third_party/llvm-project/llvm/include>
+      $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/third_party/llvm-project/mlir/include>
+      $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/third_party/llvm-project/llvm/tools/mlir/include>
+      $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/third_party/llvm-project/llvm/tools/mlir-hlo/include>
+    )
+    # Avoid globally modifying paths by instead adding the include paths to the
+    # rules that really should have them in the first place.
+    target_include_directories(LLVMSupport PUBLIC ${_common_include_dirs})
+    target_include_directories(MLIRSupport PUBLIC ${_common_include_dirs})
+  endfunction()
+  _hack_llvm_include_paths()
 endif()
 
 #-------------------------------------------------------------------------------
diff --git a/build_tools/cmake/iree_third_party_cmake_options.cmake b/build_tools/cmake/iree_third_party_cmake_options.cmake
index e960589..2efba4e 100644
--- a/build_tools/cmake/iree_third_party_cmake_options.cmake
+++ b/build_tools/cmake/iree_third_party_cmake_options.cmake
@@ -50,6 +50,17 @@
   set(LLVM_ENABLE_BINDINGS OFF CACHE BOOL "" FORCE)
 endmacro()
 
+macro(iree_add_llvm_external_project name identifier location)
+  message(STATUS "Adding LLVM external project ${name} (${identifier}) -> ${location}")
+  if(NOT EXISTS "${location}/CMakeLists.txt")
+    message(FATAL_ERROR "External project location ${location} is not valid")
+  endif()
+  list(APPEND LLVM_EXTERNAL_PROJECTS ${name})
+  list(REMOVE_DUPLICATES LLVM_EXTERNAL_PROJECTS)
+  set(LLVM_EXTERNAL_${identifier}_SOURCE_DIR ${location} CACHE STRING "" FORCE)
+  set(LLVM_EXTERNAL_PROJECTS ${LLVM_EXTERNAL_PROJECTS} CACHE STRING "" FORCE)
+endmacro()
+
 macro(iree_set_spirv_cross_cmake_options)
   set(SPIRV_CROSS_ENABLE_MSL ON CACHE BOOL "" FORCE)
   set(SPIRV_CROSS_ENABLE_GLSL ON CACHE BOOL "" FORCE) # Required to enable MSL
diff --git a/iree/tools/CMakeLists.txt b/iree/tools/CMakeLists.txt
index 0764f85..956752c 100644
--- a/iree/tools/CMakeLists.txt
+++ b/iree/tools/CMakeLists.txt
@@ -196,6 +196,7 @@
       "init_iree_dialects.h"
       "init_iree_passes.h"
     DEPS
+      IREEDialectsIREEDialect
       MLIRIR
       iree::compiler::Bindings::Native::Transforms
       iree::compiler::Bindings::TFLite::Transforms
diff --git a/llvm-projects/iree-compiler-api/CMakeLists.txt b/llvm-projects/iree-compiler-api/CMakeLists.txt
index 977bf19..4313f0b 100644
--- a/llvm-projects/iree-compiler-api/CMakeLists.txt
+++ b/llvm-projects/iree-compiler-api/CMakeLists.txt
@@ -66,7 +66,8 @@
 # prefixing, which feels gross but is stable. Investigate a better mechanism
 # upstream.
 iree_set_llvm_cmake_options()
-set(LLVM_EXTERNAL_PROJECTS "mlir-iree-dialects;mlir-hlo" CACHE STRING "" FORCE)
+iree_add_llvm_external_project(mlir-iree-dialects MLIR_IREE_DIALECTS ${LLVM_EXTERNAL_MLIR_IREE_DIALECTS_SOURCE_DIR})
+iree_add_llvm_external_project(mlir-hlo MLIR_HLO ${LLVM_EXTERNAL_MLIR_HLO_SOURCE_DIR})
 set(MLIR_ENABLE_BINDINGS_PYTHON ON CACHE BOOL "" FORCE)
 set(MLIR_BINDINGS_PYTHON_LOCK_VERSION OFF CACHE BOOL "" FORCE)
 # TODO: Conflicting gtest.
diff --git a/llvm-projects/iree-dialects/CMakeLists.txt b/llvm-projects/iree-dialects/CMakeLists.txt
index 945b878..7c9bfd8 100644
--- a/llvm-projects/iree-dialects/CMakeLists.txt
+++ b/llvm-projects/iree-dialects/CMakeLists.txt
@@ -14,7 +14,7 @@
 # TODO: Fix this upstream so that global include directories are not needed.
 set(MLIR_MAIN_SRC_DIR ${LLVM_MAIN_SRC_DIR}/../mlir)
 set(MLIR_INCLUDE_DIR ${LLVM_MAIN_SRC_DIR}/../mlir/include)
-set(MLIR_GENERATED_INCLUDE_DIR ${CMAKE_BINARY_DIR}/tools/mlir/include)
+set(MLIR_GENERATED_INCLUDE_DIR ${LLVM_BINARY_DIR}/tools/mlir/include)
 
 # TODO: Needed for tablegen. Remove.
 include_directories(SYSTEM ${MLIR_INCLUDE_DIR})