Pipeclean byo_llvm, add docs and support requested features. (#14164)

* Reworks LLVM/LLD/Clang/MLIR to use CMake initial-cache files to
configure distribution support
(https://llvm.org/docs/BuildingADistribution.html) for a more precise
build that better matches how the regular distributions are done. This
was suggested by a downstream user who helped work out the incantation.
* Implements libLLVM.so shared library redirection for LLVM
dependencies, when the backing LLVM is configured in such a way.
* Changes byo_llvm.sh to a shared-library based LLVM build.
* Fixes so that IREE can build against the installed MLIR, not just the
MLIR build tree.
* Fixes the iree-tblgen target to be correct in shared-library and
installed builds.
diff --git a/build_tools/cmake/build_and_test_byo_llvm.sh b/build_tools/cmake/build_and_test_byo_llvm.sh
index a2120ac..2b96c16 100755
--- a/build_tools/cmake/build_and_test_byo_llvm.sh
+++ b/build_tools/cmake/build_and_test_byo_llvm.sh
@@ -23,10 +23,10 @@
 # but that exists for good reasons as some users need control more over the
 # building and packaging than over the source repository, and that's good to
 # have test coverage for, and of course that's more convenient for us to test.
-build_tools/scripts/byo_llvm.sh build_llvm
+build_tools/llvm/byo_llvm.sh build_llvm
 
-build_tools/scripts/byo_llvm.sh build_mlir
-build_tools/scripts/byo_llvm.sh build_iree
+build_tools/llvm/byo_llvm.sh build_mlir
+build_tools/llvm/byo_llvm.sh build_iree
 
 echo "*********************** TESTING IREE **********************************"
 iree_build_dir="${IREE_BYOLLVM_BUILD_DIR}/iree"
diff --git a/build_tools/cmake/iree_cc_binary.cmake b/build_tools/cmake/iree_cc_binary.cmake
index 882b13b..ff46706 100644
--- a/build_tools/cmake/iree_cc_binary.cmake
+++ b/build_tools/cmake/iree_cc_binary.cmake
@@ -129,6 +129,7 @@
 
   # Replace dependencies passed by ::name with iree::package::name
   list(TRANSFORM _RULE_DEPS REPLACE "^::" "${_PACKAGE_NS}::")
+  iree_filter_cc_deps(_RULE_DEPS)
 
   # Implicit deps.
   if(IREE_IMPLICIT_DEFS_CC_DEPS)
diff --git a/build_tools/cmake/iree_cc_library.cmake b/build_tools/cmake/iree_cc_library.cmake
index bf2d7b8..868839a 100644
--- a/build_tools/cmake/iree_cc_library.cmake
+++ b/build_tools/cmake/iree_cc_library.cmake
@@ -6,6 +6,35 @@
 
 include(CMakeParseArguments)
 
+# iree_filter_cc_deps(DEPS_VAR)
+#
+# Filters a list of CC dependencies, making alterations as needed.
+# At present, this is used to redirect LLVM libraries to the libLLVM.so
+# dynamic library, when LLVM has been configured to link against it.
+# This is necessary to preserve the one-definition rule in the build graph
+# in a consistent way as to how AddLLVM.cmake does it.
+# Note that this only really works if libLLVM.so was configured to contain
+# "all" components. If this ever becomes unworkable, we may need to port the
+# component naming logic and selectively choose when to divert.
+function(iree_filter_cc_deps DEPS_VAR)
+  set(_deps ${${DEPS_VAR}})
+  set(_new_deps)
+  set(_modified FALSE)
+  foreach(_dep ${_deps})
+    # If linking against the LLVM dylib, then divert any LLVM prefixed
+    # targets there.
+    if(LLVM_LINK_LLVM_DYLIB AND _dep MATCHES "^LLVM")
+      list(APPEND _new_deps "LLVM")
+      set(_modified TRUE)
+    else()
+      list(APPEND _new_deps "${_dep}")
+    endif()
+  endforeach()
+  if(_modified)
+    set(${DEPS_VAR} "${_new_deps}" PARENT_SCOPE)
+  endif()
+endfunction()
+
 # iree_cc_library()
 #
 # CMake function to imitate Bazel's cc_library rule.
@@ -88,6 +117,7 @@
 
   # Replace dependencies passed by ::name with iree::package::name
   list(TRANSFORM _RULE_DEPS REPLACE "^::" "${_PACKAGE_NS}::")
+  iree_filter_cc_deps(_RULE_DEPS)
 
   # Check if this is a header-only library.
   # Note that as of February 2019, many popular OS's (for example, Ubuntu
diff --git a/build_tools/cmake/iree_llvm.cmake b/build_tools/cmake/iree_llvm.cmake
index 1731800..1068940 100644
--- a/build_tools/cmake/iree_llvm.cmake
+++ b/build_tools/cmake/iree_llvm.cmake
@@ -30,6 +30,10 @@
   # Stash cmake build type in case LLVM messes with it.
   set(_CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}")
 
+  # Setup LLVM lib and bin directories.
+  set(LLVM_LIBRARY_OUTPUT_INTDIR "${CMAKE_CURRENT_BINARY_DIR}/llvm-project/lib")
+  set(LLVM_RUNTIME_OUTPUT_INTDIR "${CMAKE_CURRENT_BINARY_DIR}/llvm-project/bin")
+
   add_subdirectory("third_party/llvm-project/llvm" "llvm-project" EXCLUDE_FROM_ALL)
 
   # Reset CMAKE_BUILD_TYPE to its previous setting.
@@ -87,6 +91,10 @@
   list(APPEND CMAKE_MODULE_PATH "${LLD_CMAKE_DIR}")
   include_directories(${LLD_INCLUDE_DIRS})
 
+  find_package(Clang REQUIRED)
+  list(APPEND CMAKE_MODULE_PATH "${CLANG_CMAKE_DIR}")
+  include_directories(${CLANG_INCLUDE_DIRS})
+
   # Lit never gets installed with LLVM. So we have to reach into our copy
   # of the monorepo to get it. I'm sorry. If this doesn't work for you,
   # feel free to -DLLVM_EXTERNAL_LIT to provide your own.
@@ -96,11 +104,13 @@
     set(LLVM_EXTERNAL_LIT "${IREE_SOURCE_DIR}/third_party/llvm-project/llvm/utils/lit/lit.py")
   endif()
 
-  set(IREE_LLVM_LINK_BINARY "${LLVM_INSTALL_DIR}/llvm/bin/llvm-link${CMAKE_EXECUTABLE_SUFFIX}")
-  set(IREE_LLD_BINARY "${LLVM_INSTALL_DIR}/llvm/bin/lld${CMAKE_EXECUTABLE_SUFFIX}")
-  set(IREE_CLANG_BINARY "${LLVM_INSTALL_DIR}/llvm/bin/clang${CMAKE_EXECUTABLE_SUFFIX}")
-  string(REGEX REPLACE "[^0-9].*" "" _LLVM_VERSION_MAJOR "${LLVM_VERSION}")
-  set(IREE_CLANG_BUILTIN_HEADERS_PATH "${LLVM_INSTALL_DIR}/llvm/lib/clang/${_LLVM_VERSION_MAJOR}/include/")
+  set(IREE_LLVM_LINK_BINARY "$<TARGET_FILE:llvm-link>")
+  set(IREE_LLD_BINARY "$<TARGET_FILE:lld>")
+  set(IREE_CLANG_BINARY "$<TARGET_FILE:clang>")
+  set(IREE_CLANG_BUILTIN_HEADERS_PATH "${LLVM_LIBRARY_DIR}/clang/${LLVM_VERSION_MAJOR}/include")
+  if(NOT EXISTS "${IREE_CLANG_BUILTIN_HEADERS_PATH}")
+    message(WARNING "Could not find installed clang-resource-headers (tried ${IREE_CLANG_BUILTIN_HEADERS_PATH})")
+  endif()
 endmacro()
 
 # iree_llvm_set_bundled_cmake_options()