Bug 1616692 - Update to clang 10.0.0 r=froydnj
☠☠ backed out by 005ef1c25992 ☠ ☠
authorDavid Major <dmajor@mozilla.com>
Wed, 20 May 2020 07:39:23 +0300
changeset 530941 c17af0632260c9e645f5ba983a54602c50cfb1ec
parent 530940 cd4c8b9e05536dce48de21d7edaa8b09cda6b262
child 530942 2a54634147e5af3120138c4360e4816602f2dc2d
push id37434
push userabutkovits@mozilla.com
push dateWed, 20 May 2020 10:05:10 +0000
treeherdermozilla-central@005ef1c25992 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1616692
milestone78.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1616692 - Update to clang 10.0.0 r=froydnj Differential Revision: https://phabricator.services.mozilla.com/D74768
build/build-clang/clang-10-linux64.json
build/build-clang/clang-9-linux64.json
build/build-clang/clang-linux64.json
build/build-clang/clang-win64.json
build/build-clang/find_symbolizer_linux-clang-9.patch
build/build-clang/find_symbolizer_linux.patch
build/build-clang/find_symbolizer_linux_clang_10.patch
build/build-clang/llvmorg-10-init-5191-ga84b200e604-windows-pgo.patch
build/build-clang/llvmorg-11-init-14017-g02b303321d3-libclang.patch
build/build-clang/llvmorg-11-init-4265-g2dcbdba8540-clang-9.patch
build/build-clang/llvmorg-11-init-4265-g2dcbdba8540.patch
build/build-clang/llvmorg-11-init-4265-g2dcbdba8540_clang_10.patch
build/build-clang/rG7e18aeba5062-clang-9.patch
build/build-clang/rG7e18aeba5062.patch
build/build-clang/rG7e18aeba5062_clang_10.patch
build/build-clang/rename_gcov_flush-clang-9.patch
build/build-clang/rename_gcov_flush.patch
build/build-clang/rename_gcov_flush_clang_10.patch
build/build-clang/tsan-hang-be41a98ac222-clang-9.patch
build/build-clang/tsan-hang-be41a98ac222.patch
build/build-clang/tsan-hang-be41a98ac222_clang_10.patch
build/build-clang/unpoison-thread-stacks-clang-9.patch
build/build-clang/unpoison-thread-stacks.patch
build/build-clang/unpoison-thread-stacks_clang_10.patch
taskcluster/ci/build/linux.yml
taskcluster/ci/fetch/toolchains.yml
taskcluster/ci/toolchain/cbindgen.yml
taskcluster/ci/toolchain/cctools-port.yml
taskcluster/ci/toolchain/clang-tidy.yml
taskcluster/ci/toolchain/clang.yml
taskcluster/ci/toolchain/dist-toolchains.yml
taskcluster/ci/toolchain/fix-stacks.yml
taskcluster/ci/toolchain/gn.yml
taskcluster/ci/toolchain/minidump_stackwalk.yml
taskcluster/ci/toolchain/misc.yml
taskcluster/ci/toolchain/sccache.yml
deleted file mode 100644
--- a/build/build-clang/clang-10-linux64.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
-    "stages": "4",
-    "pgo" : true,
-    "build_libcxx": true,
-    "build_wasm": true,
-    "build_type": "Release",
-    "assertions": false,
-    "python_path": "/usr/bin/python2.7",
-    "gcc_dir": "{MOZ_FETCHES_DIR}/gcc",
-    "cc": "{MOZ_FETCHES_DIR}/gcc/bin/gcc",
-    "cxx": "{MOZ_FETCHES_DIR}/gcc/bin/g++",
-    "as": "{MOZ_FETCHES_DIR}/gcc/bin/gcc",
-    "wasi-sysroot": "{MOZ_FETCHES_DIR}/wasi-sysroot",
-    "patches": [
-      "static-llvm-symbolizer.patch",
-      "find_symbolizer_linux_clang_10.patch",
-      "rename_gcov_flush_clang_10.patch",
-      "critical_section_on_gcov_flush-rG02ce9d8ef5a8.patch",
-      "rG7e18aeba5062_clang_10.patch",
-      "llvmorg-11-init-4265-g2dcbdba8540_clang_10.patch",
-      "android-mangling-error.patch",
-      "unpoison-thread-stacks_clang_10.patch",
-      "downgrade-mangling-error.patch",
-      "tsan-hang-be41a98ac222_clang_10.patch",
-      "loosen-msvc-detection.patch"
-    ]
-}
new file mode 100644
--- /dev/null
+++ b/build/build-clang/clang-9-linux64.json
@@ -0,0 +1,27 @@
+{
+    "stages": "4",
+    "pgo" : true,
+    "build_libcxx": true,
+    "build_wasm": true,
+    "build_type": "Release",
+    "assertions": false,
+    "python_path": "/usr/bin/python2.7",
+    "gcc_dir": "{MOZ_FETCHES_DIR}/gcc",
+    "cc": "{MOZ_FETCHES_DIR}/gcc/bin/gcc",
+    "cxx": "{MOZ_FETCHES_DIR}/gcc/bin/g++",
+    "as": "{MOZ_FETCHES_DIR}/gcc/bin/gcc",
+    "wasi-sysroot": "{MOZ_FETCHES_DIR}/wasi-sysroot",
+    "patches": [
+      "static-llvm-symbolizer.patch",
+      "find_symbolizer_linux-clang-9.patch",
+      "rename_gcov_flush-clang-9.patch",
+      "critical_section_on_gcov_flush-rG02ce9d8ef5a8.patch",
+      "rG7e18aeba5062-clang-9.patch",
+      "llvmorg-11-init-4265-g2dcbdba8540-clang-9.patch",
+      "android-mangling-error.patch",
+      "unpoison-thread-stacks-clang-9.patch",
+      "downgrade-mangling-error.patch",
+      "tsan-hang-be41a98ac222-clang-9.patch",
+      "loosen-msvc-detection.patch"
+    ]
+}
--- a/build/build-clang/clang-linux64.json
+++ b/build/build-clang/clang-linux64.json
@@ -17,11 +17,12 @@
       "rename_gcov_flush.patch",
       "critical_section_on_gcov_flush-rG02ce9d8ef5a8.patch",
       "rG7e18aeba5062.patch",
       "llvmorg-11-init-4265-g2dcbdba8540.patch",
       "android-mangling-error.patch",
       "unpoison-thread-stacks.patch",
       "downgrade-mangling-error.patch",
       "tsan-hang-be41a98ac222.patch",
+      "llvmorg-11-init-14017-g02b303321d3-libclang.patch",
       "loosen-msvc-detection.patch"
     ]
 }
--- a/build/build-clang/clang-win64.json
+++ b/build/build-clang/clang-win64.json
@@ -7,12 +7,11 @@
     "python_path": "c:/mozilla-build/python/python.exe",
     "cc": "cl.exe",
     "cxx": "cl.exe",
     "ml": "ml64.exe",
     "patches": [
       "unpoison-thread-stacks.patch",
       "downgrade-mangling-error.patch",
       "rG7e18aeba5062.patch",
-      "llvmorg-10-init-5191-ga84b200e604-windows-pgo.patch",
       "loosen-msvc-detection.patch"
     ]
 }
new file mode 100644
--- /dev/null
+++ b/build/build-clang/find_symbolizer_linux-clang-9.patch
@@ -0,0 +1,58 @@
+We currently need this patch because ASan only searches PATH to find the
+llvm-symbolizer binary to symbolize ASan traces. On testing machines, this
+can be installed in PATH easily. However, for e.g. the ASan Nightly Project,
+where we ship an ASan build, including llvm-symbolizer, to the user, we
+cannot expect llvm-symbolizer to be on PATH. Instead, we should try to look
+it up next to the binary. This patch implements the functionality for Linux
+only until there is similar functionality provided upstream.
+
+diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cc b/compiler-rt/lib/sanitizer_common/sanitizer_file.cc
+index cde54bf..8daade1 100644
+--- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cc
++++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cc
+@@ -21,6 +21,10 @@
+ #include "sanitizer_common.h"
+ #include "sanitizer_file.h"
+ 
++#if SANITIZER_LINUX
++#include "sanitizer_posix.h"
++#endif
++
+ namespace __sanitizer {
+ 
+ void CatastrophicErrorWrite(const char *buffer, uptr length) {
+@@ -156,6 +160,34 @@ char *FindPathToBinary(const char *name) {
+     if (*end == '\0') break;
+     beg = end + 1;
+   }
++
++#if SANITIZER_LINUX
++  // If we cannot find the requested binary in PATH, we should try to locate
++  // it next to the binary, in case it is shipped with the build itself
++  // (e.g. llvm-symbolizer shipped with sanitizer build to symbolize on client.
++  if (internal_readlink("/proc/self/exe", buffer.data(), kMaxPathLength) < 0)
++    return nullptr;
++
++  uptr buf_len = internal_strlen(buffer.data());
++
++  /* Avoid using dirname() here */
++  while (buf_len > 0) {
++    if (buffer[buf_len - 1] == '/')
++      break;
++    buf_len--;
++  }
++
++  if (!buf_len)
++    return nullptr;
++
++  if (buf_len + name_len + 1 <= kMaxPathLength) {
++    internal_memcpy(&buffer[buf_len], name, name_len);
++    buffer[buf_len + name_len] = '\0';
++    if (FileExists(buffer.data()))
++      return internal_strdup(buffer.data());
++  }
++#endif
++
+   return nullptr;
+ }
+ 
--- a/build/build-clang/find_symbolizer_linux.patch
+++ b/build/build-clang/find_symbolizer_linux.patch
@@ -1,32 +1,32 @@
 We currently need this patch because ASan only searches PATH to find the
 llvm-symbolizer binary to symbolize ASan traces. On testing machines, this
 can be installed in PATH easily. However, for e.g. the ASan Nightly Project,
 where we ship an ASan build, including llvm-symbolizer, to the user, we
 cannot expect llvm-symbolizer to be on PATH. Instead, we should try to look
 it up next to the binary. This patch implements the functionality for Linux
 only until there is similar functionality provided upstream.
 
-diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cc b/compiler-rt/lib/sanitizer_common/sanitizer_file.cc
-index cde54bf..8daade1 100644
---- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cc
-+++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cc
-@@ -21,6 +21,10 @@
+diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
+index 79930d79425..cfb4f90c0d5 100644
+--- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
++++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
+@@ -20,6 +20,10 @@
  #include "sanitizer_common.h"
  #include "sanitizer_file.h"
  
 +#if SANITIZER_LINUX
 +#include "sanitizer_posix.h"
 +#endif
 +
  namespace __sanitizer {
  
  void CatastrophicErrorWrite(const char *buffer, uptr length) {
-@@ -156,6 +160,34 @@ char *FindPathToBinary(const char *name) {
+@@ -194,6 +198,34 @@ char *FindPathToBinary(const char *name) {
      if (*end == '\0') break;
      beg = end + 1;
    }
 +
 +#if SANITIZER_LINUX
 +  // If we cannot find the requested binary in PATH, we should try to locate
 +  // it next to the binary, in case it is shipped with the build itself
 +  // (e.g. llvm-symbolizer shipped with sanitizer build to symbolize on client.
deleted file mode 100644
--- a/build/build-clang/find_symbolizer_linux_clang_10.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-We currently need this patch because ASan only searches PATH to find the
-llvm-symbolizer binary to symbolize ASan traces. On testing machines, this
-can be installed in PATH easily. However, for e.g. the ASan Nightly Project,
-where we ship an ASan build, including llvm-symbolizer, to the user, we
-cannot expect llvm-symbolizer to be on PATH. Instead, we should try to look
-it up next to the binary. This patch implements the functionality for Linux
-only until there is similar functionality provided upstream.
-
-diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
-index 79930d79425..cfb4f90c0d5 100644
---- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
-+++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
-@@ -20,6 +20,10 @@
- #include "sanitizer_common.h"
- #include "sanitizer_file.h"
- 
-+#if SANITIZER_LINUX
-+#include "sanitizer_posix.h"
-+#endif
-+
- namespace __sanitizer {
- 
- void CatastrophicErrorWrite(const char *buffer, uptr length) {
-@@ -194,6 +198,34 @@ char *FindPathToBinary(const char *name) {
-     if (*end == '\0') break;
-     beg = end + 1;
-   }
-+
-+#if SANITIZER_LINUX
-+  // If we cannot find the requested binary in PATH, we should try to locate
-+  // it next to the binary, in case it is shipped with the build itself
-+  // (e.g. llvm-symbolizer shipped with sanitizer build to symbolize on client.
-+  if (internal_readlink("/proc/self/exe", buffer.data(), kMaxPathLength) < 0)
-+    return nullptr;
-+
-+  uptr buf_len = internal_strlen(buffer.data());
-+
-+  /* Avoid using dirname() here */
-+  while (buf_len > 0) {
-+    if (buffer[buf_len - 1] == '/')
-+      break;
-+    buf_len--;
-+  }
-+
-+  if (!buf_len)
-+    return nullptr;
-+
-+  if (buf_len + name_len + 1 <= kMaxPathLength) {
-+    internal_memcpy(&buffer[buf_len], name, name_len);
-+    buffer[buf_len + name_len] = '\0';
-+    if (FileExists(buffer.data()))
-+      return internal_strdup(buffer.data());
-+  }
-+#endif
-+
-   return nullptr;
- }
- 
deleted file mode 100644
--- a/build/build-clang/llvmorg-10-init-5191-ga84b200e604-windows-pgo.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-[cmake] Changes to get Windows self-host working with PGO
-
-Fixes quoting of profile arguments to work on Windows
-Suppresses adding profile arguments to linker flags when using lld-link
-Avoids -fprofile-instr-use being added to rc.exe flags
-Removes duplicated adding of -fprofile-instr-use to linker flags (since
-r355541)
-Move handling LLVM_PROFDATA_FILE to HandleLLVMOptions.cmake
-
-Differential Revision: https://reviews.llvm.org/D62063
-
-llvm-svn: 372209
-
-diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
-index b9a10685b99..73f8664cdcf 100644
---- a/llvm/CMakeLists.txt
-+++ b/llvm/CMakeLists.txt
-@@ -612,6 +612,9 @@ mark_as_advanced(LLVM_TARGET_TRIPLE_ENV)
- set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR OFF CACHE BOOL
-   "Enable per-target runtimes directory")
- 
-+set(LLVM_PROFDATA_FILE "" CACHE FILEPATH
-+  "Profiling data file to use when compiling in order to improve runtime performance.")
-+
- # All options referred to from HandleLLVMOptions have to be specified
- # BEFORE this include, otherwise options will not be correctly set on
- # first cmake run
-@@ -873,17 +876,6 @@ endif( ${CMAKE_SYSTEM_NAME} MATCHES SunOS )
- # use export_executable_symbols(target).
- set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
- 
--set(LLVM_PROFDATA_FILE "" CACHE FILEPATH
--  "Profiling data file to use when compiling in order to improve runtime performance.")
--
--if(LLVM_PROFDATA_FILE AND EXISTS ${LLVM_PROFDATA_FILE})
--  if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
--    add_definitions("-fprofile-instr-use=${LLVM_PROFDATA_FILE}")
--  else()
--    message(FATAL_ERROR "LLVM_PROFDATA_FILE can only be specified when compiling with clang")
--  endif()
--endif()
--
- include(AddLLVM)
- include(TableGen)
- 
-diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
-index 4425eb91a5f..2e780d56254 100644
---- a/llvm/cmake/modules/HandleLLVMOptions.cmake
-+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
-@@ -846,32 +846,48 @@ string(TOUPPER "${LLVM_BUILD_INSTRUMENTED}" uppercase_LLVM_BUILD_INSTRUMENTED)
- 
- if (LLVM_BUILD_INSTRUMENTED)
-   if (LLVM_ENABLE_IR_PGO OR uppercase_LLVM_BUILD_INSTRUMENTED STREQUAL "IR")
--    append("-fprofile-generate='${LLVM_PROFILE_DATA_DIR}'"
-+    append("-fprofile-generate=\"${LLVM_PROFILE_DATA_DIR}\""
-       CMAKE_CXX_FLAGS
--      CMAKE_C_FLAGS
--      CMAKE_EXE_LINKER_FLAGS
--      CMAKE_SHARED_LINKER_FLAGS)
-+      CMAKE_C_FLAGS)
-+    if(NOT LINKER_IS_LLD_LINK)
-+        append("-fprofile-generate=\"${LLVM_PROFILE_DATA_DIR}\""
-+          CMAKE_EXE_LINKER_FLAGS
-+          CMAKE_SHARED_LINKER_FLAGS)
-+    endif()
-   elseif(uppercase_LLVM_BUILD_INSTRUMENTED STREQUAL "CSIR")
--    append("-fcs-profile-generate='${LLVM_CSPROFILE_DATA_DIR}'"
-+    append("-fcs-profile-generate=\"${LLVM_CSPROFILE_DATA_DIR}\""
-       CMAKE_CXX_FLAGS
--      CMAKE_C_FLAGS
--      CMAKE_EXE_LINKER_FLAGS
--      CMAKE_SHARED_LINKER_FLAGS)
-+      CMAKE_C_FLAGS)
-+    if(NOT LINKER_IS_LLD_LINK)
-+      append("-fcs-profile-generate=\"${LLVM_CSPROFILE_DATA_DIR}\""
-+        CMAKE_EXE_LINKER_FLAGS
-+        CMAKE_SHARED_LINKER_FLAGS)
-+    endif()
-   else()
--    append("-fprofile-instr-generate='${LLVM_PROFILE_FILE_PATTERN}'"
-+    append("-fprofile-instr-generate=\"${LLVM_PROFILE_FILE_PATTERN}\""
-       CMAKE_CXX_FLAGS
--      CMAKE_C_FLAGS
--      CMAKE_EXE_LINKER_FLAGS
--      CMAKE_SHARED_LINKER_FLAGS)
-+      CMAKE_C_FLAGS)
-+    if(NOT LINKER_IS_LLD_LINK)
-+      append("-fprofile-instr-generate=\"${LLVM_PROFILE_FILE_PATTERN}\""
-+        CMAKE_EXE_LINKER_FLAGS
-+        CMAKE_SHARED_LINKER_FLAGS)
-+    endif()
-   endif()
- endif()
- 
--# Need to pass -fprofile-instr-use to linker for context-sensitive PGO
--# compilation.
- if(LLVM_PROFDATA_FILE AND EXISTS ${LLVM_PROFDATA_FILE})
--    append("-fprofile-instr-use='${LLVM_PROFDATA_FILE}'"
--      CMAKE_EXE_LINKER_FLAGS
--      CMAKE_SHARED_LINKER_FLAGS)
-+  if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
-+    append("-fprofile-instr-use=\"${LLVM_PROFDATA_FILE}\""
-+      CMAKE_CXX_FLAGS
-+      CMAKE_C_FLAGS)
-+    if(NOT LINKER_IS_LLD_LINK)
-+      append("-fprofile-instr-use=\"${LLVM_PROFDATA_FILE}\""
-+        CMAKE_EXE_LINKER_FLAGS
-+        CMAKE_SHARED_LINKER_FLAGS)
-+    endif()
-+  else()
-+    message(FATAL_ERROR "LLVM_PROFDATA_FILE can only be specified when compiling with clang")
-+  endif()
- endif()
- 
- option(LLVM_BUILD_INSTRUMENTED_COVERAGE "Build LLVM and tools with Code Coverage instrumentation" Off)
new file mode 100644
--- /dev/null
+++ b/build/build-clang/llvmorg-11-init-14017-g02b303321d3-libclang.patch
@@ -0,0 +1,16 @@
+[libclang] Remove duplicate dependency on LLVMSupport
+
+Differential Revision: https://reviews.llvm.org/D79451
+    
+diff --git a/clang/tools/libclang/CMakeLists.txt b/clang/tools/libclang/CMakeLists.txt
+index bd0c945a5e1..973655361f7 100644
+--- a/clang/tools/libclang/CMakeLists.txt
++++ b/clang/tools/libclang/CMakeLists.txt
+@@ -44,7 +44,6 @@ set(LIBS
+   clangSema
+   clangSerialization
+   clangTooling
+-  LLVMSupport
+ )
+ 
+ if (CLANG_ENABLE_ARCMT)
new file mode 100644
--- /dev/null
+++ b/build/build-clang/llvmorg-11-init-4265-g2dcbdba8540-clang-9.patch
@@ -0,0 +1,106 @@
+diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
+index 9a184c79798..733decfe52c 100644
+--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
++++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
+@@ -1021,7 +1021,7 @@ TSAN_INTERCEPTOR(int, pthread_create,
+ 
+ TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) {
+   SCOPED_INTERCEPTOR_RAW(pthread_join, th, ret);
+-  int tid = ThreadTid(thr, pc, (uptr)th);
++  int tid = ThreadConsumeTid(thr, pc, (uptr)th);
+   ThreadIgnoreBegin(thr, pc);
+   int res = BLOCK_REAL(pthread_join)(th, ret);
+   ThreadIgnoreEnd(thr, pc);
+@@ -1034,8 +1034,8 @@ TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) {
+ DEFINE_REAL_PTHREAD_FUNCTIONS
+ 
+ TSAN_INTERCEPTOR(int, pthread_detach, void *th) {
+-  SCOPED_TSAN_INTERCEPTOR(pthread_detach, th);
+-  int tid = ThreadTid(thr, pc, (uptr)th);
++  SCOPED_INTERCEPTOR_RAW(pthread_detach, th);
++  int tid = ThreadConsumeTid(thr, pc, (uptr)th);
+   int res = REAL(pthread_detach)(th);
+   if (res == 0) {
+     ThreadDetach(thr, pc, tid);
+@@ -1055,8 +1055,8 @@ TSAN_INTERCEPTOR(void, pthread_exit, void *retval) {
+ 
+ #if SANITIZER_LINUX
+ TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) {
+-  SCOPED_TSAN_INTERCEPTOR(pthread_tryjoin_np, th, ret);
+-  int tid = ThreadTid(thr, pc, (uptr)th);
++  SCOPED_INTERCEPTOR_RAW(pthread_tryjoin_np, th, ret);
++  int tid = ThreadConsumeTid(thr, pc, (uptr)th);
+   ThreadIgnoreBegin(thr, pc);
+   int res = REAL(pthread_tryjoin_np)(th, ret);
+   ThreadIgnoreEnd(thr, pc);
+@@ -1069,8 +1069,8 @@ TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) {
+ 
+ TSAN_INTERCEPTOR(int, pthread_timedjoin_np, void *th, void **ret,
+                  const struct timespec *abstime) {
+-  SCOPED_TSAN_INTERCEPTOR(pthread_timedjoin_np, th, ret, abstime);
+-  int tid = ThreadTid(thr, pc, (uptr)th);
++  SCOPED_INTERCEPTOR_RAW(pthread_timedjoin_np, th, ret, abstime);
++  int tid = ThreadConsumeTid(thr, pc, (uptr)th);
+   ThreadIgnoreBegin(thr, pc);
+   int res = BLOCK_REAL(pthread_timedjoin_np)(th, ret, abstime);
+   ThreadIgnoreEnd(thr, pc);
+diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
+index 3a8231bda9a..30e144fbd00 100644
+--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h
++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
+@@ -772,7 +772,7 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached);
+ void ThreadStart(ThreadState *thr, int tid, tid_t os_id,
+                  ThreadType thread_type);
+ void ThreadFinish(ThreadState *thr);
+-int ThreadTid(ThreadState *thr, uptr pc, uptr uid);
++int ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid);
+ void ThreadJoin(ThreadState *thr, uptr pc, int tid);
+ void ThreadDetach(ThreadState *thr, uptr pc, int tid);
+ void ThreadFinalize(ThreadState *thr);
+diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
+index fd95cfed4f5..13e457bd770 100644
+--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
+@@ -285,19 +285,34 @@ void ThreadFinish(ThreadState *thr) {
+   ctx->thread_registry->FinishThread(thr->tid);
+ }
+ 
+-static bool FindThreadByUid(ThreadContextBase *tctx, void *arg) {
+-  uptr uid = (uptr)arg;
+-  if (tctx->user_id == uid && tctx->status != ThreadStatusInvalid) {
++struct ConsumeThreadContext {
++  uptr uid;
++  ThreadContextBase* tctx;
++};
++
++static bool ConsumeThreadByUid(ThreadContextBase *tctx, void *arg) {
++  ConsumeThreadContext *findCtx = (ConsumeThreadContext*)arg;
++  if (tctx->user_id == findCtx->uid && tctx->status != ThreadStatusInvalid) {
++    if (findCtx->tctx) {
++      // Ensure that user_id is unique. If it's not the case we are screwed.
++      // Something went wrong before, but now there is no way to recover.
++      // Returning a wrong thread is not an option, it may lead to very hard
++      // to debug false positives (e.g. if we join a wrong thread).
++      Report("ThreadSanitizer: dup thread with used id 0x%zx\n", findCtx->uid);
++      Die();
++    }
++    findCtx->tctx = tctx;
+     tctx->user_id = 0;
+-    return true;
+   }
+   return false;
+ }
+ 
+-int ThreadTid(ThreadState *thr, uptr pc, uptr uid) {
+-  int res = ctx->thread_registry->FindThread(FindThreadByUid, (void*)uid);
+-  DPrintf("#%d: ThreadTid uid=%zu tid=%d\n", thr->tid, uid, res);
+-  return res;
++int ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid) {
++  ConsumeThreadContext findCtx = {uid, nullptr};
++  ctx->thread_registry->FindThread(ConsumeThreadByUid, &findCtx);
++  int tid = findCtx.tctx ? findCtx.tctx->tid : ThreadRegistry::kUnknownTid;
++  DPrintf("#%d: ThreadTid uid=%zu tid=%d\n", thr->tid, uid, tid);
++  return tid;
+ }
+ 
+ void ThreadJoin(ThreadState *thr, uptr pc, int tid) {
--- a/build/build-clang/llvmorg-11-init-4265-g2dcbdba8540.patch
+++ b/build/build-clang/llvmorg-11-init-4265-g2dcbdba8540.patch
@@ -1,71 +1,71 @@
-diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
-index 9a184c79798..733decfe52c 100644
---- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
-+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
-@@ -1021,7 +1021,7 @@ TSAN_INTERCEPTOR(int, pthread_create,
+diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+index 8aea1e4ec05..a623f4fe589 100644
+--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
++++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+@@ -1016,7 +1016,7 @@ TSAN_INTERCEPTOR(int, pthread_create,
  
  TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) {
    SCOPED_INTERCEPTOR_RAW(pthread_join, th, ret);
 -  int tid = ThreadTid(thr, pc, (uptr)th);
 +  int tid = ThreadConsumeTid(thr, pc, (uptr)th);
    ThreadIgnoreBegin(thr, pc);
    int res = BLOCK_REAL(pthread_join)(th, ret);
    ThreadIgnoreEnd(thr, pc);
-@@ -1034,8 +1034,8 @@ TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) {
+@@ -1029,8 +1029,8 @@ TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) {
  DEFINE_REAL_PTHREAD_FUNCTIONS
  
  TSAN_INTERCEPTOR(int, pthread_detach, void *th) {
 -  SCOPED_TSAN_INTERCEPTOR(pthread_detach, th);
 -  int tid = ThreadTid(thr, pc, (uptr)th);
 +  SCOPED_INTERCEPTOR_RAW(pthread_detach, th);
 +  int tid = ThreadConsumeTid(thr, pc, (uptr)th);
    int res = REAL(pthread_detach)(th);
    if (res == 0) {
      ThreadDetach(thr, pc, tid);
-@@ -1055,8 +1055,8 @@ TSAN_INTERCEPTOR(void, pthread_exit, void *retval) {
+@@ -1050,8 +1050,8 @@ TSAN_INTERCEPTOR(void, pthread_exit, void *retval) {
  
  #if SANITIZER_LINUX
  TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) {
 -  SCOPED_TSAN_INTERCEPTOR(pthread_tryjoin_np, th, ret);
 -  int tid = ThreadTid(thr, pc, (uptr)th);
 +  SCOPED_INTERCEPTOR_RAW(pthread_tryjoin_np, th, ret);
 +  int tid = ThreadConsumeTid(thr, pc, (uptr)th);
    ThreadIgnoreBegin(thr, pc);
    int res = REAL(pthread_tryjoin_np)(th, ret);
    ThreadIgnoreEnd(thr, pc);
-@@ -1069,8 +1069,8 @@ TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) {
+@@ -1064,8 +1064,8 @@ TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) {
  
  TSAN_INTERCEPTOR(int, pthread_timedjoin_np, void *th, void **ret,
                   const struct timespec *abstime) {
 -  SCOPED_TSAN_INTERCEPTOR(pthread_timedjoin_np, th, ret, abstime);
 -  int tid = ThreadTid(thr, pc, (uptr)th);
 +  SCOPED_INTERCEPTOR_RAW(pthread_timedjoin_np, th, ret, abstime);
 +  int tid = ThreadConsumeTid(thr, pc, (uptr)th);
    ThreadIgnoreBegin(thr, pc);
    int res = BLOCK_REAL(pthread_timedjoin_np)(th, ret, abstime);
    ThreadIgnoreEnd(thr, pc);
 diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
-index 3a8231bda9a..30e144fbd00 100644
+index c38fc43a9f8..20f7a99157a 100644
 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h
 +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
-@@ -772,7 +772,7 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached);
+@@ -775,7 +775,7 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached);
  void ThreadStart(ThreadState *thr, int tid, tid_t os_id,
                   ThreadType thread_type);
  void ThreadFinish(ThreadState *thr);
 -int ThreadTid(ThreadState *thr, uptr pc, uptr uid);
 +int ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid);
  void ThreadJoin(ThreadState *thr, uptr pc, int tid);
  void ThreadDetach(ThreadState *thr, uptr pc, int tid);
  void ThreadFinalize(ThreadState *thr);
-diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
-index fd95cfed4f5..13e457bd770 100644
---- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
-+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
+diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
+index 0ac1ee99c47..f7068f0d331 100644
+--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
 @@ -285,19 +285,34 @@ void ThreadFinish(ThreadState *thr) {
    ctx->thread_registry->FinishThread(thr->tid);
  }
  
 -static bool FindThreadByUid(ThreadContextBase *tctx, void *arg) {
 -  uptr uid = (uptr)arg;
 -  if (tctx->user_id == uid && tctx->status != ThreadStatusInvalid) {
 +struct ConsumeThreadContext {
deleted file mode 100644
--- a/build/build-clang/llvmorg-11-init-4265-g2dcbdba8540_clang_10.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
-index 8aea1e4ec05..a623f4fe589 100644
---- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
-+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
-@@ -1016,7 +1016,7 @@ TSAN_INTERCEPTOR(int, pthread_create,
- 
- TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) {
-   SCOPED_INTERCEPTOR_RAW(pthread_join, th, ret);
--  int tid = ThreadTid(thr, pc, (uptr)th);
-+  int tid = ThreadConsumeTid(thr, pc, (uptr)th);
-   ThreadIgnoreBegin(thr, pc);
-   int res = BLOCK_REAL(pthread_join)(th, ret);
-   ThreadIgnoreEnd(thr, pc);
-@@ -1029,8 +1029,8 @@ TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) {
- DEFINE_REAL_PTHREAD_FUNCTIONS
- 
- TSAN_INTERCEPTOR(int, pthread_detach, void *th) {
--  SCOPED_TSAN_INTERCEPTOR(pthread_detach, th);
--  int tid = ThreadTid(thr, pc, (uptr)th);
-+  SCOPED_INTERCEPTOR_RAW(pthread_detach, th);
-+  int tid = ThreadConsumeTid(thr, pc, (uptr)th);
-   int res = REAL(pthread_detach)(th);
-   if (res == 0) {
-     ThreadDetach(thr, pc, tid);
-@@ -1050,8 +1050,8 @@ TSAN_INTERCEPTOR(void, pthread_exit, void *retval) {
- 
- #if SANITIZER_LINUX
- TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) {
--  SCOPED_TSAN_INTERCEPTOR(pthread_tryjoin_np, th, ret);
--  int tid = ThreadTid(thr, pc, (uptr)th);
-+  SCOPED_INTERCEPTOR_RAW(pthread_tryjoin_np, th, ret);
-+  int tid = ThreadConsumeTid(thr, pc, (uptr)th);
-   ThreadIgnoreBegin(thr, pc);
-   int res = REAL(pthread_tryjoin_np)(th, ret);
-   ThreadIgnoreEnd(thr, pc);
-@@ -1064,8 +1064,8 @@ TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) {
- 
- TSAN_INTERCEPTOR(int, pthread_timedjoin_np, void *th, void **ret,
-                  const struct timespec *abstime) {
--  SCOPED_TSAN_INTERCEPTOR(pthread_timedjoin_np, th, ret, abstime);
--  int tid = ThreadTid(thr, pc, (uptr)th);
-+  SCOPED_INTERCEPTOR_RAW(pthread_timedjoin_np, th, ret, abstime);
-+  int tid = ThreadConsumeTid(thr, pc, (uptr)th);
-   ThreadIgnoreBegin(thr, pc);
-   int res = BLOCK_REAL(pthread_timedjoin_np)(th, ret, abstime);
-   ThreadIgnoreEnd(thr, pc);
-diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
-index c38fc43a9f8..20f7a99157a 100644
---- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h
-+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
-@@ -775,7 +775,7 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached);
- void ThreadStart(ThreadState *thr, int tid, tid_t os_id,
-                  ThreadType thread_type);
- void ThreadFinish(ThreadState *thr);
--int ThreadTid(ThreadState *thr, uptr pc, uptr uid);
-+int ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid);
- void ThreadJoin(ThreadState *thr, uptr pc, int tid);
- void ThreadDetach(ThreadState *thr, uptr pc, int tid);
- void ThreadFinalize(ThreadState *thr);
-diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
-index 0ac1ee99c47..f7068f0d331 100644
---- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
-+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
-@@ -285,19 +285,34 @@ void ThreadFinish(ThreadState *thr) {
-   ctx->thread_registry->FinishThread(thr->tid);
- }
- 
--static bool FindThreadByUid(ThreadContextBase *tctx, void *arg) {
--  uptr uid = (uptr)arg;
--  if (tctx->user_id == uid && tctx->status != ThreadStatusInvalid) {
-+struct ConsumeThreadContext {
-+  uptr uid;
-+  ThreadContextBase* tctx;
-+};
-+
-+static bool ConsumeThreadByUid(ThreadContextBase *tctx, void *arg) {
-+  ConsumeThreadContext *findCtx = (ConsumeThreadContext*)arg;
-+  if (tctx->user_id == findCtx->uid && tctx->status != ThreadStatusInvalid) {
-+    if (findCtx->tctx) {
-+      // Ensure that user_id is unique. If it's not the case we are screwed.
-+      // Something went wrong before, but now there is no way to recover.
-+      // Returning a wrong thread is not an option, it may lead to very hard
-+      // to debug false positives (e.g. if we join a wrong thread).
-+      Report("ThreadSanitizer: dup thread with used id 0x%zx\n", findCtx->uid);
-+      Die();
-+    }
-+    findCtx->tctx = tctx;
-     tctx->user_id = 0;
--    return true;
-   }
-   return false;
- }
- 
--int ThreadTid(ThreadState *thr, uptr pc, uptr uid) {
--  int res = ctx->thread_registry->FindThread(FindThreadByUid, (void*)uid);
--  DPrintf("#%d: ThreadTid uid=%zu tid=%d\n", thr->tid, uid, res);
--  return res;
-+int ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid) {
-+  ConsumeThreadContext findCtx = {uid, nullptr};
-+  ctx->thread_registry->FindThread(ConsumeThreadByUid, &findCtx);
-+  int tid = findCtx.tctx ? findCtx.tctx->tid : ThreadRegistry::kUnknownTid;
-+  DPrintf("#%d: ThreadTid uid=%zu tid=%d\n", thr->tid, uid, tid);
-+  return tid;
- }
- 
- void ThreadJoin(ThreadState *thr, uptr pc, int tid) {
new file mode 100644
--- /dev/null
+++ b/build/build-clang/rG7e18aeba5062-clang-9.patch
@@ -0,0 +1,255 @@
+From 779a169144581438d9e24b8b46a86704f6335e35 Mon Sep 17 00:00:00 2001
+From: Nikita Popov <nikita.ppv@gmail.com>
+Date: Sat, 16 Nov 2019 16:22:18 +0100
+Subject: [PATCH] [LVI] Restructure caching
+
+Variant on D70103. The caching is switched to always use a BB to
+cache entry map, which then contains per-value caches. A separate
+set contains value handles with a deletion callback. This allows us
+to properly invalidate overdefined values.
+
+A possible alternative would be to always cache by value first and
+have per-BB maps/sets in the each cache entry. In that case we could
+use a ValueMap and would avoid the separate value handle set. I went
+with the BB indexing at the top level to make it easier to integrate
+D69914, but possibly that's not the right choice.
+
+Differential Revision: https://reviews.llvm.org/D70376
+---
+ llvm/lib/Analysis/LazyValueInfo.cpp | 143 +++++++++-------------------
+ 1 file changed, 47 insertions(+), 96 deletions(-)
+
+diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
+index 542ff709d47..eb51744aec3 100644
+--- a/llvm/lib/Analysis/LazyValueInfo.cpp
++++ b/llvm/lib/Analysis/LazyValueInfo.cpp
+@@ -132,12 +132,9 @@ namespace {
+   /// A callback value handle updates the cache when values are erased.
+   class LazyValueInfoCache;
+   struct LVIValueHandle final : public CallbackVH {
+-    // Needs to access getValPtr(), which is protected.
+-    friend struct DenseMapInfo<LVIValueHandle>;
+-
+     LazyValueInfoCache *Parent;
+ 
+-    LVIValueHandle(Value *V, LazyValueInfoCache *P)
++    LVIValueHandle(Value *V, LazyValueInfoCache *P = nullptr)
+       : CallbackVH(V), Parent(P) { }
+ 
+     void deleted() override;
+@@ -151,89 +148,63 @@ namespace {
+   /// This is the cache kept by LazyValueInfo which
+   /// maintains information about queries across the clients' queries.
+   class LazyValueInfoCache {
+-    /// This is all of the cached block information for exactly one Value*.
+-    /// The entries are sorted by the BasicBlock* of the
+-    /// entries, allowing us to do a lookup with a binary search.
+-    /// Over-defined lattice values are recorded in OverDefinedCache to reduce
+-    /// memory overhead.
+-    struct ValueCacheEntryTy {
+-      ValueCacheEntryTy(Value *V, LazyValueInfoCache *P) : Handle(V, P) {}
+-      LVIValueHandle Handle;
+-      SmallDenseMap<PoisoningVH<BasicBlock>, ValueLatticeElement, 4> BlockVals;
++    /// This is all of the cached information for one basic block. It contains
++    /// the per-value lattice elements, as well as a separate set for
++    /// overdefined values to reduce memory usage.
++    struct BlockCacheEntryTy {
++      SmallDenseMap<AssertingVH<Value>, ValueLatticeElement, 4> LatticeElements;
++      SmallDenseSet<AssertingVH<Value>, 4> OverDefined;
+     };
+ 
+-    /// This tracks, on a per-block basis, the set of values that are
+-    /// over-defined at the end of that block.
+-    typedef DenseMap<PoisoningVH<BasicBlock>, SmallPtrSet<Value *, 4>>
+-        OverDefinedCacheTy;
+-    /// Keep track of all blocks that we have ever seen, so we
+-    /// don't spend time removing unused blocks from our caches.
+-    DenseSet<PoisoningVH<BasicBlock> > SeenBlocks;
+-
+-    /// This is all of the cached information for all values,
+-    /// mapped from Value* to key information.
+-    DenseMap<Value *, std::unique_ptr<ValueCacheEntryTy>> ValueCache;
+-    OverDefinedCacheTy OverDefinedCache;
+-
++    /// Cached information per basic block.
++    DenseMap<PoisoningVH<BasicBlock>, BlockCacheEntryTy> BlockCache;
++    /// Set of value handles used to erase values from the cache on deletion.
++    DenseSet<LVIValueHandle, DenseMapInfo<Value *>> ValueHandles;
+ 
+   public:
+     void insertResult(Value *Val, BasicBlock *BB,
+                       const ValueLatticeElement &Result) {
+-      SeenBlocks.insert(BB);
+-
++      auto &CacheEntry = BlockCache.try_emplace(BB).first->second;
+       // Insert over-defined values into their own cache to reduce memory
+       // overhead.
+       if (Result.isOverdefined())
+-        OverDefinedCache[BB].insert(Val);
+-      else {
+-        auto It = ValueCache.find_as(Val);
+-        if (It == ValueCache.end()) {
+-          ValueCache[Val] = make_unique<ValueCacheEntryTy>(Val, this);
+-          It = ValueCache.find_as(Val);
+-          assert(It != ValueCache.end() && "Val was just added to the map!");
+-        }
+-        It->second->BlockVals[BB] = Result;
+-      }
+-    }
+-
+-    bool isOverdefined(Value *V, BasicBlock *BB) const {
+-      auto ODI = OverDefinedCache.find(BB);
+-
+-      if (ODI == OverDefinedCache.end())
+-        return false;
++        CacheEntry.OverDefined.insert(Val);
++      else
++        CacheEntry.LatticeElements.insert({ Val, Result });
+ 
+-      return ODI->second.count(V);
++      auto HandleIt = ValueHandles.find_as(Val);
++      if (HandleIt == ValueHandles.end())
++        ValueHandles.insert({ Val, this });
+     }
+ 
+     bool hasCachedValueInfo(Value *V, BasicBlock *BB) const {
+-      if (isOverdefined(V, BB))
+-        return true;
+-
+-      auto I = ValueCache.find_as(V);
+-      if (I == ValueCache.end())
++      auto It = BlockCache.find(BB);
++      if (It == BlockCache.end())
+         return false;
+ 
+-      return I->second->BlockVals.count(BB);
++      return It->second.OverDefined.count(V) ||
++             It->second.LatticeElements.count(V);
+     }
+ 
+     ValueLatticeElement getCachedValueInfo(Value *V, BasicBlock *BB) const {
+-      if (isOverdefined(V, BB))
++      auto It = BlockCache.find(BB);
++      if (It == BlockCache.end())
++        return ValueLatticeElement();
++
++      if (It->second.OverDefined.count(V))
+         return ValueLatticeElement::getOverdefined();
+ 
+-      auto I = ValueCache.find_as(V);
+-      if (I == ValueCache.end())
++      auto LatticeIt = It->second.LatticeElements.find(V);
++      if (LatticeIt == It->second.LatticeElements.end())
+         return ValueLatticeElement();
+-      auto BBI = I->second->BlockVals.find(BB);
+-      if (BBI == I->second->BlockVals.end())
+-        return ValueLatticeElement();
+-      return BBI->second;
++
++      return LatticeIt->second;
+     }
+ 
+     /// clear - Empty the cache.
+     void clear() {
+-      SeenBlocks.clear();
+-      ValueCache.clear();
+-      OverDefinedCache.clear();
++      BlockCache.clear();
++      ValueHandles.clear();
+     }
+ 
+     /// Inform the cache that a given value has been deleted.
+@@ -247,23 +218,18 @@ namespace {
+     /// OldSucc might have (unless also overdefined in NewSucc).  This just
+     /// flushes elements from the cache and does not add any.
+     void threadEdgeImpl(BasicBlock *OldSucc,BasicBlock *NewSucc);
+-
+-    friend struct LVIValueHandle;
+   };
+ }
+ 
+ void LazyValueInfoCache::eraseValue(Value *V) {
+-  for (auto I = OverDefinedCache.begin(), E = OverDefinedCache.end(); I != E;) {
+-    // Copy and increment the iterator immediately so we can erase behind
+-    // ourselves.
+-    auto Iter = I++;
+-    SmallPtrSetImpl<Value *> &ValueSet = Iter->second;
+-    ValueSet.erase(V);
+-    if (ValueSet.empty())
+-      OverDefinedCache.erase(Iter);
++  for (auto &Pair : BlockCache) {
++    Pair.second.LatticeElements.erase(V);
++    Pair.second.OverDefined.erase(V);
+   }
+ 
+-  ValueCache.erase(V);
++  auto HandleIt = ValueHandles.find_as(V);
++  if (HandleIt != ValueHandles.end())
++    ValueHandles.erase(HandleIt);
+ }
+ 
+ void LVIValueHandle::deleted() {
+@@ -273,18 +239,7 @@ void LVIValueHandle::deleted() {
+ }
+ 
+ void LazyValueInfoCache::eraseBlock(BasicBlock *BB) {
+-  // Shortcut if we have never seen this block.
+-  DenseSet<PoisoningVH<BasicBlock> >::iterator I = SeenBlocks.find(BB);
+-  if (I == SeenBlocks.end())
+-    return;
+-  SeenBlocks.erase(I);
+-
+-  auto ODI = OverDefinedCache.find(BB);
+-  if (ODI != OverDefinedCache.end())
+-    OverDefinedCache.erase(ODI);
+-
+-  for (auto &I : ValueCache)
+-    I.second->BlockVals.erase(BB);
++  BlockCache.erase(BB);
+ }
+ 
+ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
+@@ -302,10 +257,11 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
+   std::vector<BasicBlock*> worklist;
+   worklist.push_back(OldSucc);
+ 
+-  auto I = OverDefinedCache.find(OldSucc);
+-  if (I == OverDefinedCache.end())
++  auto I = BlockCache.find(OldSucc);
++  if (I == BlockCache.end() || I->second.OverDefined.empty())
+     return; // Nothing to process here.
+-  SmallVector<Value *, 4> ValsToClear(I->second.begin(), I->second.end());
++  SmallVector<Value *, 4> ValsToClear(I->second.OverDefined.begin(),
++                                      I->second.OverDefined.end());
+ 
+   // Use a worklist to perform a depth-first search of OldSucc's successors.
+   // NOTE: We do not need a visited list since any blocks we have already
+@@ -319,10 +275,10 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
+     if (ToUpdate == NewSucc) continue;
+ 
+     // If a value was marked overdefined in OldSucc, and is here too...
+-    auto OI = OverDefinedCache.find(ToUpdate);
+-    if (OI == OverDefinedCache.end())
++    auto OI = BlockCache.find(ToUpdate);
++    if (OI == BlockCache.end() || OI->second.OverDefined.empty())
+       continue;
+-    SmallPtrSetImpl<Value *> &ValueSet = OI->second;
++    auto &ValueSet = OI->second.OverDefined;
+ 
+     bool changed = false;
+     for (Value *V : ValsToClear) {
+@@ -332,11 +288,6 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
+       // If we removed anything, then we potentially need to update
+       // blocks successors too.
+       changed = true;
+-
+-      if (ValueSet.empty()) {
+-        OverDefinedCache.erase(OI);
+-        break;
+-      }
+     }
+ 
+     if (!changed) continue;
+-- 
+2.24.0
+
--- a/build/build-clang/rG7e18aeba5062.patch
+++ b/build/build-clang/rG7e18aeba5062.patch
@@ -10,39 +10,36 @@ to properly invalidate overdefined value
 
 A possible alternative would be to always cache by value first and
 have per-BB maps/sets in the each cache entry. In that case we could
 use a ValueMap and would avoid the separate value handle set. I went
 with the BB indexing at the top level to make it easier to integrate
 D69914, but possibly that's not the right choice.
 
 Differential Revision: https://reviews.llvm.org/D70376
----
- llvm/lib/Analysis/LazyValueInfo.cpp | 143 +++++++++-------------------
- 1 file changed, 47 insertions(+), 96 deletions(-)
 
 diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
-index 542ff709d47..eb51744aec3 100644
+index bad2de9e5f5..33406a75d80 100644
 --- a/llvm/lib/Analysis/LazyValueInfo.cpp
 +++ b/llvm/lib/Analysis/LazyValueInfo.cpp
-@@ -132,12 +132,9 @@ namespace {
+@@ -136,12 +136,10 @@ namespace {
    /// A callback value handle updates the cache when values are erased.
    class LazyValueInfoCache;
    struct LVIValueHandle final : public CallbackVH {
 -    // Needs to access getValPtr(), which is protected.
 -    friend struct DenseMapInfo<LVIValueHandle>;
--
+ 
      LazyValueInfoCache *Parent;
  
 -    LVIValueHandle(Value *V, LazyValueInfoCache *P)
 +    LVIValueHandle(Value *V, LazyValueInfoCache *P = nullptr)
        : CallbackVH(V), Parent(P) { }
  
      void deleted() override;
-@@ -151,89 +148,63 @@ namespace {
+@@ -155,89 +153,63 @@ namespace {
    /// This is the cache kept by LazyValueInfo which
    /// maintains information about queries across the clients' queries.
    class LazyValueInfoCache {
 -    /// This is all of the cached block information for exactly one Value*.
 -    /// The entries are sorted by the BasicBlock* of the
 -    /// entries, allowing us to do a lookup with a binary search.
 -    /// Over-defined lattice values are recorded in OverDefinedCache to reduce
 -    /// memory overhead.
@@ -84,17 +81,17 @@ index 542ff709d47..eb51744aec3 100644
 +      auto &CacheEntry = BlockCache.try_emplace(BB).first->second;
        // Insert over-defined values into their own cache to reduce memory
        // overhead.
        if (Result.isOverdefined())
 -        OverDefinedCache[BB].insert(Val);
 -      else {
 -        auto It = ValueCache.find_as(Val);
 -        if (It == ValueCache.end()) {
--          ValueCache[Val] = make_unique<ValueCacheEntryTy>(Val, this);
+-          ValueCache[Val] = std::make_unique<ValueCacheEntryTy>(Val, this);
 -          It = ValueCache.find_as(Val);
 -          assert(It != ValueCache.end() && "Val was just added to the map!");
 -        }
 -        It->second->BlockVals[BB] = Result;
 -      }
 -    }
 -
 -    bool isOverdefined(Value *V, BasicBlock *BB) const {
@@ -133,38 +130,38 @@ index 542ff709d47..eb51744aec3 100644
 +      if (It == BlockCache.end())
 +        return ValueLatticeElement();
 +
 +      if (It->second.OverDefined.count(V))
          return ValueLatticeElement::getOverdefined();
  
 -      auto I = ValueCache.find_as(V);
 -      if (I == ValueCache.end())
+-        return ValueLatticeElement();
+-      auto BBI = I->second->BlockVals.find(BB);
+-      if (BBI == I->second->BlockVals.end())
 +      auto LatticeIt = It->second.LatticeElements.find(V);
 +      if (LatticeIt == It->second.LatticeElements.end())
          return ValueLatticeElement();
--      auto BBI = I->second->BlockVals.find(BB);
--      if (BBI == I->second->BlockVals.end())
--        return ValueLatticeElement();
 -      return BBI->second;
 +
 +      return LatticeIt->second;
      }
  
      /// clear - Empty the cache.
      void clear() {
 -      SeenBlocks.clear();
 -      ValueCache.clear();
 -      OverDefinedCache.clear();
 +      BlockCache.clear();
 +      ValueHandles.clear();
      }
  
      /// Inform the cache that a given value has been deleted.
-@@ -247,23 +218,18 @@ namespace {
+@@ -251,23 +223,18 @@ namespace {
      /// OldSucc might have (unless also overdefined in NewSucc).  This just
      /// flushes elements from the cache and does not add any.
      void threadEdgeImpl(BasicBlock *OldSucc,BasicBlock *NewSucc);
 -
 -    friend struct LVIValueHandle;
    };
  }
  
@@ -184,17 +181,17 @@ index 542ff709d47..eb51744aec3 100644
  
 -  ValueCache.erase(V);
 +  auto HandleIt = ValueHandles.find_as(V);
 +  if (HandleIt != ValueHandles.end())
 +    ValueHandles.erase(HandleIt);
  }
  
  void LVIValueHandle::deleted() {
-@@ -273,18 +239,7 @@ void LVIValueHandle::deleted() {
+@@ -277,18 +244,7 @@ void LVIValueHandle::deleted() {
  }
  
  void LazyValueInfoCache::eraseBlock(BasicBlock *BB) {
 -  // Shortcut if we have never seen this block.
 -  DenseSet<PoisoningVH<BasicBlock> >::iterator I = SeenBlocks.find(BB);
 -  if (I == SeenBlocks.end())
 -    return;
 -  SeenBlocks.erase(I);
@@ -204,52 +201,49 @@ index 542ff709d47..eb51744aec3 100644
 -    OverDefinedCache.erase(ODI);
 -
 -  for (auto &I : ValueCache)
 -    I.second->BlockVals.erase(BB);
 +  BlockCache.erase(BB);
  }
  
  void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
-@@ -302,10 +257,11 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
+@@ -306,10 +262,11 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
    std::vector<BasicBlock*> worklist;
    worklist.push_back(OldSucc);
  
 -  auto I = OverDefinedCache.find(OldSucc);
 -  if (I == OverDefinedCache.end())
 +  auto I = BlockCache.find(OldSucc);
 +  if (I == BlockCache.end() || I->second.OverDefined.empty())
      return; // Nothing to process here.
 -  SmallVector<Value *, 4> ValsToClear(I->second.begin(), I->second.end());
 +  SmallVector<Value *, 4> ValsToClear(I->second.OverDefined.begin(),
 +                                      I->second.OverDefined.end());
  
    // Use a worklist to perform a depth-first search of OldSucc's successors.
    // NOTE: We do not need a visited list since any blocks we have already
-@@ -319,10 +275,10 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
+@@ -323,10 +280,10 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
      if (ToUpdate == NewSucc) continue;
  
      // If a value was marked overdefined in OldSucc, and is here too...
 -    auto OI = OverDefinedCache.find(ToUpdate);
 -    if (OI == OverDefinedCache.end())
 +    auto OI = BlockCache.find(ToUpdate);
 +    if (OI == BlockCache.end() || OI->second.OverDefined.empty())
        continue;
 -    SmallPtrSetImpl<Value *> &ValueSet = OI->second;
 +    auto &ValueSet = OI->second.OverDefined;
  
      bool changed = false;
      for (Value *V : ValsToClear) {
-@@ -332,11 +288,6 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
+@@ -336,11 +293,6 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
        // If we removed anything, then we potentially need to update
        // blocks successors too.
        changed = true;
 -
 -      if (ValueSet.empty()) {
 -        OverDefinedCache.erase(OI);
 -        break;
 -      }
      }
  
      if (!changed) continue;
--- 
-2.24.0
-
deleted file mode 100644
--- a/build/build-clang/rG7e18aeba5062_clang_10.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-From 779a169144581438d9e24b8b46a86704f6335e35 Mon Sep 17 00:00:00 2001
-From: Nikita Popov <nikita.ppv@gmail.com>
-Date: Sat, 16 Nov 2019 16:22:18 +0100
-Subject: [PATCH] [LVI] Restructure caching
-
-Variant on D70103. The caching is switched to always use a BB to
-cache entry map, which then contains per-value caches. A separate
-set contains value handles with a deletion callback. This allows us
-to properly invalidate overdefined values.
-
-A possible alternative would be to always cache by value first and
-have per-BB maps/sets in the each cache entry. In that case we could
-use a ValueMap and would avoid the separate value handle set. I went
-with the BB indexing at the top level to make it easier to integrate
-D69914, but possibly that's not the right choice.
-
-Differential Revision: https://reviews.llvm.org/D70376
-
-diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
-index bad2de9e5f5..33406a75d80 100644
---- a/llvm/lib/Analysis/LazyValueInfo.cpp
-+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
-@@ -136,12 +136,10 @@ namespace {
-   /// A callback value handle updates the cache when values are erased.
-   class LazyValueInfoCache;
-   struct LVIValueHandle final : public CallbackVH {
--    // Needs to access getValPtr(), which is protected.
--    friend struct DenseMapInfo<LVIValueHandle>;
- 
-     LazyValueInfoCache *Parent;
- 
--    LVIValueHandle(Value *V, LazyValueInfoCache *P)
-+    LVIValueHandle(Value *V, LazyValueInfoCache *P = nullptr)
-       : CallbackVH(V), Parent(P) { }
- 
-     void deleted() override;
-@@ -155,89 +153,63 @@ namespace {
-   /// This is the cache kept by LazyValueInfo which
-   /// maintains information about queries across the clients' queries.
-   class LazyValueInfoCache {
--    /// This is all of the cached block information for exactly one Value*.
--    /// The entries are sorted by the BasicBlock* of the
--    /// entries, allowing us to do a lookup with a binary search.
--    /// Over-defined lattice values are recorded in OverDefinedCache to reduce
--    /// memory overhead.
--    struct ValueCacheEntryTy {
--      ValueCacheEntryTy(Value *V, LazyValueInfoCache *P) : Handle(V, P) {}
--      LVIValueHandle Handle;
--      SmallDenseMap<PoisoningVH<BasicBlock>, ValueLatticeElement, 4> BlockVals;
-+    /// This is all of the cached information for one basic block. It contains
-+    /// the per-value lattice elements, as well as a separate set for
-+    /// overdefined values to reduce memory usage.
-+    struct BlockCacheEntryTy {
-+      SmallDenseMap<AssertingVH<Value>, ValueLatticeElement, 4> LatticeElements;
-+      SmallDenseSet<AssertingVH<Value>, 4> OverDefined;
-     };
- 
--    /// This tracks, on a per-block basis, the set of values that are
--    /// over-defined at the end of that block.
--    typedef DenseMap<PoisoningVH<BasicBlock>, SmallPtrSet<Value *, 4>>
--        OverDefinedCacheTy;
--    /// Keep track of all blocks that we have ever seen, so we
--    /// don't spend time removing unused blocks from our caches.
--    DenseSet<PoisoningVH<BasicBlock> > SeenBlocks;
--
--    /// This is all of the cached information for all values,
--    /// mapped from Value* to key information.
--    DenseMap<Value *, std::unique_ptr<ValueCacheEntryTy>> ValueCache;
--    OverDefinedCacheTy OverDefinedCache;
--
-+    /// Cached information per basic block.
-+    DenseMap<PoisoningVH<BasicBlock>, BlockCacheEntryTy> BlockCache;
-+    /// Set of value handles used to erase values from the cache on deletion.
-+    DenseSet<LVIValueHandle, DenseMapInfo<Value *>> ValueHandles;
- 
-   public:
-     void insertResult(Value *Val, BasicBlock *BB,
-                       const ValueLatticeElement &Result) {
--      SeenBlocks.insert(BB);
--
-+      auto &CacheEntry = BlockCache.try_emplace(BB).first->second;
-       // Insert over-defined values into their own cache to reduce memory
-       // overhead.
-       if (Result.isOverdefined())
--        OverDefinedCache[BB].insert(Val);
--      else {
--        auto It = ValueCache.find_as(Val);
--        if (It == ValueCache.end()) {
--          ValueCache[Val] = std::make_unique<ValueCacheEntryTy>(Val, this);
--          It = ValueCache.find_as(Val);
--          assert(It != ValueCache.end() && "Val was just added to the map!");
--        }
--        It->second->BlockVals[BB] = Result;
--      }
--    }
--
--    bool isOverdefined(Value *V, BasicBlock *BB) const {
--      auto ODI = OverDefinedCache.find(BB);
--
--      if (ODI == OverDefinedCache.end())
--        return false;
-+        CacheEntry.OverDefined.insert(Val);
-+      else
-+        CacheEntry.LatticeElements.insert({ Val, Result });
- 
--      return ODI->second.count(V);
-+      auto HandleIt = ValueHandles.find_as(Val);
-+      if (HandleIt == ValueHandles.end())
-+        ValueHandles.insert({ Val, this });
-     }
- 
-     bool hasCachedValueInfo(Value *V, BasicBlock *BB) const {
--      if (isOverdefined(V, BB))
--        return true;
--
--      auto I = ValueCache.find_as(V);
--      if (I == ValueCache.end())
-+      auto It = BlockCache.find(BB);
-+      if (It == BlockCache.end())
-         return false;
- 
--      return I->second->BlockVals.count(BB);
-+      return It->second.OverDefined.count(V) ||
-+             It->second.LatticeElements.count(V);
-     }
- 
-     ValueLatticeElement getCachedValueInfo(Value *V, BasicBlock *BB) const {
--      if (isOverdefined(V, BB))
-+      auto It = BlockCache.find(BB);
-+      if (It == BlockCache.end())
-+        return ValueLatticeElement();
-+
-+      if (It->second.OverDefined.count(V))
-         return ValueLatticeElement::getOverdefined();
- 
--      auto I = ValueCache.find_as(V);
--      if (I == ValueCache.end())
--        return ValueLatticeElement();
--      auto BBI = I->second->BlockVals.find(BB);
--      if (BBI == I->second->BlockVals.end())
-+      auto LatticeIt = It->second.LatticeElements.find(V);
-+      if (LatticeIt == It->second.LatticeElements.end())
-         return ValueLatticeElement();
--      return BBI->second;
-+
-+      return LatticeIt->second;
-     }
- 
-     /// clear - Empty the cache.
-     void clear() {
--      SeenBlocks.clear();
--      ValueCache.clear();
--      OverDefinedCache.clear();
-+      BlockCache.clear();
-+      ValueHandles.clear();
-     }
- 
-     /// Inform the cache that a given value has been deleted.
-@@ -251,23 +223,18 @@ namespace {
-     /// OldSucc might have (unless also overdefined in NewSucc).  This just
-     /// flushes elements from the cache and does not add any.
-     void threadEdgeImpl(BasicBlock *OldSucc,BasicBlock *NewSucc);
--
--    friend struct LVIValueHandle;
-   };
- }
- 
- void LazyValueInfoCache::eraseValue(Value *V) {
--  for (auto I = OverDefinedCache.begin(), E = OverDefinedCache.end(); I != E;) {
--    // Copy and increment the iterator immediately so we can erase behind
--    // ourselves.
--    auto Iter = I++;
--    SmallPtrSetImpl<Value *> &ValueSet = Iter->second;
--    ValueSet.erase(V);
--    if (ValueSet.empty())
--      OverDefinedCache.erase(Iter);
-+  for (auto &Pair : BlockCache) {
-+    Pair.second.LatticeElements.erase(V);
-+    Pair.second.OverDefined.erase(V);
-   }
- 
--  ValueCache.erase(V);
-+  auto HandleIt = ValueHandles.find_as(V);
-+  if (HandleIt != ValueHandles.end())
-+    ValueHandles.erase(HandleIt);
- }
- 
- void LVIValueHandle::deleted() {
-@@ -277,18 +244,7 @@ void LVIValueHandle::deleted() {
- }
- 
- void LazyValueInfoCache::eraseBlock(BasicBlock *BB) {
--  // Shortcut if we have never seen this block.
--  DenseSet<PoisoningVH<BasicBlock> >::iterator I = SeenBlocks.find(BB);
--  if (I == SeenBlocks.end())
--    return;
--  SeenBlocks.erase(I);
--
--  auto ODI = OverDefinedCache.find(BB);
--  if (ODI != OverDefinedCache.end())
--    OverDefinedCache.erase(ODI);
--
--  for (auto &I : ValueCache)
--    I.second->BlockVals.erase(BB);
-+  BlockCache.erase(BB);
- }
- 
- void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
-@@ -306,10 +262,11 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
-   std::vector<BasicBlock*> worklist;
-   worklist.push_back(OldSucc);
- 
--  auto I = OverDefinedCache.find(OldSucc);
--  if (I == OverDefinedCache.end())
-+  auto I = BlockCache.find(OldSucc);
-+  if (I == BlockCache.end() || I->second.OverDefined.empty())
-     return; // Nothing to process here.
--  SmallVector<Value *, 4> ValsToClear(I->second.begin(), I->second.end());
-+  SmallVector<Value *, 4> ValsToClear(I->second.OverDefined.begin(),
-+                                      I->second.OverDefined.end());
- 
-   // Use a worklist to perform a depth-first search of OldSucc's successors.
-   // NOTE: We do not need a visited list since any blocks we have already
-@@ -323,10 +280,10 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
-     if (ToUpdate == NewSucc) continue;
- 
-     // If a value was marked overdefined in OldSucc, and is here too...
--    auto OI = OverDefinedCache.find(ToUpdate);
--    if (OI == OverDefinedCache.end())
-+    auto OI = BlockCache.find(ToUpdate);
-+    if (OI == BlockCache.end() || OI->second.OverDefined.empty())
-       continue;
--    SmallPtrSetImpl<Value *> &ValueSet = OI->second;
-+    auto &ValueSet = OI->second.OverDefined;
- 
-     bool changed = false;
-     for (Value *V : ValsToClear) {
-@@ -336,11 +293,6 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
-       // If we removed anything, then we potentially need to update
-       // blocks successors too.
-       changed = true;
--
--      if (ValueSet.empty()) {
--        OverDefinedCache.erase(OI);
--        break;
--      }
-     }
- 
-     if (!changed) continue;
new file mode 100644
--- /dev/null
+++ b/build/build-clang/rename_gcov_flush-clang-9.patch
@@ -0,0 +1,40 @@
+Index: compiler-rt/lib/profile/GCDAProfiling.c
+===================================================================
+diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
+--- a/compiler-rt/lib/profile/GCDAProfiling.c
++++ b/compiler-rt/lib/profile/GCDAProfiling.c
+@@ -619,7 +619,7 @@
+   fn_list_insert(&flush_fn_list, fn);
+ }
+ 
+-void __gcov_flush() {
++void __custom_llvm_gcov_flush() {
+   struct fn_node* curr = flush_fn_list.head;
+ 
+   while (curr) {
+diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+index 9af64ed332c..bcebe303ff4 100644
+--- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
++++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+@@ -647,7 +647,7 @@
+   for (auto I : ForkAndExecs) {
+     IRBuilder<> Builder(I);
+     FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
+-    FunctionCallee GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy);
++    FunctionCallee GCOVFlush = M->getOrInsertFunction("__custom_llvm_gcov_flush", FTy);
+     Builder.CreateCall(GCOVFlush);
+     I->getParent()->splitBasicBlock(I);
+   }
+diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
+index e113f9a679..b3a07b18c0 100644
+--- a/clang/lib/Driver/ToolChains/Darwin.cpp
++++ b/clang/lib/Driver/ToolChains/Darwin.cpp
+@@ -1122,7 +1122,7 @@
+   // runtime's functionality.
+   if (hasExportSymbolDirective(Args)) {
+     if (needsGCovInstrumentation(Args)) {
+-      addExportedSymbol(CmdArgs, "___gcov_flush");
++      addExportedSymbol(CmdArgs, "___custom_llvm_gcov_flush");
+       addExportedSymbol(CmdArgs, "_flush_fn_list");
+       addExportedSymbol(CmdArgs, "_writeout_fn_list");
+     } else {
--- a/build/build-clang/rename_gcov_flush.patch
+++ b/build/build-clang/rename_gcov_flush.patch
@@ -1,40 +1,42 @@
-Index: compiler-rt/lib/profile/GCDAProfiling.c
-===================================================================
+diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
+index 220bc8f9835..4f7ce485777 100644
+--- a/clang/lib/Driver/ToolChains/Darwin.cpp
++++ b/clang/lib/Driver/ToolChains/Darwin.cpp
+@@ -1143,7 +1143,7 @@ void Darwin::addProfileRTLibs(const ArgList &Args,
+   // runtime's functionality.
+   if (hasExportSymbolDirective(Args)) {
+     if (ForGCOV) {
+-      addExportedSymbol(CmdArgs, "___gcov_flush");
++      addExportedSymbol(CmdArgs, "___custom_llvm_gcov_flush");
+       addExportedSymbol(CmdArgs, "_flush_fn_list");
+       addExportedSymbol(CmdArgs, "_writeout_fn_list");
+     } else {
 diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
+index 498c05900bf..b7257db10e7 100644
 --- a/compiler-rt/lib/profile/GCDAProfiling.c
 +++ b/compiler-rt/lib/profile/GCDAProfiling.c
-@@ -619,7 +619,7 @@
+@@ -619,7 +619,7 @@ void llvm_register_flush_function(fn_ptr fn) {
    fn_list_insert(&flush_fn_list, fn);
  }
  
 -void __gcov_flush() {
 +void __custom_llvm_gcov_flush() {
    struct fn_node* curr = flush_fn_list.head;
  
    while (curr) {
+diff --git a/compiler-rt/test/tsan/pthread_atfork_deadlock2.c b/compiler-rt/test/tsan/pthread_atfork_deadlock2.c
+new file mode 100644
+index 00000000000..e69de29bb2d
 diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
-index 9af64ed332c..bcebe303ff4 100644
+index bf3e4ed3e31..37bdcfaeab8 100644
 --- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
 +++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
-@@ -647,7 +647,7 @@
+@@ -656,7 +656,7 @@ void GCOVProfiler::AddFlushBeforeForkAndExec() {
    for (auto I : ForkAndExecs) {
      IRBuilder<> Builder(I);
      FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
 -    FunctionCallee GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy);
 +    FunctionCallee GCOVFlush = M->getOrInsertFunction("__custom_llvm_gcov_flush", FTy);
      Builder.CreateCall(GCOVFlush);
      I->getParent()->splitBasicBlock(I);
    }
-diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
-index e113f9a679..b3a07b18c0 100644
---- a/clang/lib/Driver/ToolChains/Darwin.cpp
-+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
-@@ -1122,7 +1122,7 @@
-   // runtime's functionality.
-   if (hasExportSymbolDirective(Args)) {
-     if (needsGCovInstrumentation(Args)) {
--      addExportedSymbol(CmdArgs, "___gcov_flush");
-+      addExportedSymbol(CmdArgs, "___custom_llvm_gcov_flush");
-       addExportedSymbol(CmdArgs, "_flush_fn_list");
-       addExportedSymbol(CmdArgs, "_writeout_fn_list");
-     } else {
deleted file mode 100644
--- a/build/build-clang/rename_gcov_flush_clang_10.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
-index 220bc8f9835..4f7ce485777 100644
---- a/clang/lib/Driver/ToolChains/Darwin.cpp
-+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
-@@ -1143,7 +1143,7 @@ void Darwin::addProfileRTLibs(const ArgList &Args,
-   // runtime's functionality.
-   if (hasExportSymbolDirective(Args)) {
-     if (ForGCOV) {
--      addExportedSymbol(CmdArgs, "___gcov_flush");
-+      addExportedSymbol(CmdArgs, "___custom_llvm_gcov_flush");
-       addExportedSymbol(CmdArgs, "_flush_fn_list");
-       addExportedSymbol(CmdArgs, "_writeout_fn_list");
-     } else {
-diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
-index 498c05900bf..b7257db10e7 100644
---- a/compiler-rt/lib/profile/GCDAProfiling.c
-+++ b/compiler-rt/lib/profile/GCDAProfiling.c
-@@ -619,7 +619,7 @@ void llvm_register_flush_function(fn_ptr fn) {
-   fn_list_insert(&flush_fn_list, fn);
- }
- 
--void __gcov_flush() {
-+void __custom_llvm_gcov_flush() {
-   struct fn_node* curr = flush_fn_list.head;
- 
-   while (curr) {
-diff --git a/compiler-rt/test/tsan/pthread_atfork_deadlock2.c b/compiler-rt/test/tsan/pthread_atfork_deadlock2.c
-new file mode 100644
-index 00000000000..e69de29bb2d
-diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
-index bf3e4ed3e31..37bdcfaeab8 100644
---- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
-+++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
-@@ -656,7 +656,7 @@ void GCOVProfiler::AddFlushBeforeForkAndExec() {
-   for (auto I : ForkAndExecs) {
-     IRBuilder<> Builder(I);
-     FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
--    FunctionCallee GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy);
-+    FunctionCallee GCOVFlush = M->getOrInsertFunction("__custom_llvm_gcov_flush", FTy);
-     Builder.CreateCall(GCOVFlush);
-     I->getParent()->splitBasicBlock(I);
-   }
new file mode 100644
--- /dev/null
+++ b/build/build-clang/tsan-hang-be41a98ac222-clang-9.patch
@@ -0,0 +1,100 @@
+From be41a98ac222f33ed5558d86e1cede67249e99b5 Mon Sep 17 00:00:00 2001
+From: Dmitry Vyukov <dvyukov@google.com>
+Date: Sat, 21 Mar 2020 13:34:50 +0100
+Subject: [PATCH] tsan: fix deadlock with pthread_atfork callbacks
+
+This fixes the bug reported at:
+https://groups.google.com/forum/#!topic/thread-sanitizer/e_zB9gYqFHM
+
+A pthread_atfork callback triggers a data race
+and we deadlock on the report_mtx. Ignore memory access
+in the pthread_atfork callbacks to prevent the deadlock.
+---
+ compiler-rt/lib/tsan/rtl/tsan_rtl.cc          |  9 ++++
+ .../test/tsan/pthread_atfork_deadlock2.c      | 49 +++++++++++++++++++
+ 2 files changed, 58 insertions(+)
+ create mode 100644 compiler-rt/test/tsan/pthread_atfork_deadlock2.c
+
+diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl.ccc
+index fe469faad2a2..13c9b770f50a 100644
+--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc
++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc
+@@ -495,14 +495,23 @@ int Finalize(ThreadState *thr) {
+ void ForkBefore(ThreadState *thr, uptr pc) {
+   ctx->thread_registry->Lock();
+   ctx->report_mtx.Lock();
++  // Ignore memory accesses in the pthread_atfork callbacks.
++  // If any of them triggers a data race we will deadlock
++  // on the report_mtx.
++  // We could ignore interceptors and sync operations as well,
++  // but so far it's unclear if it will do more good or harm.
++  // Unnecessarily ignoring things can lead to false positives later.
++  ThreadIgnoreBegin(thr, pc);
+ }
+ 
+ void ForkParentAfter(ThreadState *thr, uptr pc) {
++  ThreadIgnoreEnd(thr, pc);  // Begin is in ForkBefore.
+   ctx->report_mtx.Unlock();
+   ctx->thread_registry->Unlock();
+ }
+ 
+ void ForkChildAfter(ThreadState *thr, uptr pc) {
++  ThreadIgnoreEnd(thr, pc);  // Begin is in ForkBefore.
+   ctx->report_mtx.Unlock();
+   ctx->thread_registry->Unlock();
+ 
+diff --git a/compiler-rt/test/tsan/pthread_atfork_deadlock2.c b/compiler-rt/test/tsan/pthread_atfork_deadlock2.c
+new file mode 100644
+index 000000000000..700507c1e637
+--- /dev/null
++++ b/compiler-rt/test/tsan/pthread_atfork_deadlock2.c
+@@ -0,0 +1,49 @@
++// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
++// Regression test for
++// https://groups.google.com/d/msg/thread-sanitizer/e_zB9gYqFHM/DmAiTsrLAwAJ
++// pthread_atfork() callback triggers a data race and we deadlocked
++// on the report_mtx as we lock it around fork.
++#include "test.h"
++#include <sys/types.h>
++#include <sys/wait.h>
++#include <errno.h>
++
++int glob = 0;
++
++void *worker(void *unused) {
++  glob++;
++  barrier_wait(&barrier);
++  return NULL;
++}
++
++void atfork() {
++  glob++;
++}
++
++int main() {
++  barrier_init(&barrier, 2);
++  pthread_atfork(atfork, NULL, NULL);
++  pthread_t t;
++  pthread_create(&t, NULL, worker, NULL);
++  barrier_wait(&barrier);
++  pid_t pid = fork();
++  if (pid < 0) {
++    fprintf(stderr, "fork failed: %d\n", errno);
++    return 1;
++  }
++  if (pid == 0) {
++    fprintf(stderr, "CHILD\n");
++    return 0;
++  }
++  if (pid != waitpid(pid, NULL, 0)) {
++    fprintf(stderr, "waitpid failed: %d\n", errno);
++    return 1;
++  }
++  pthread_join(t, NULL);
++  fprintf(stderr, "PARENT\n");
++  return 0;
++}
++
++// CHECK-NOT: ThreadSanitizer: data race
++// CHECK: CHILD
++// CHECK: PARENT
--- a/build/build-clang/tsan-hang-be41a98ac222.patch
+++ b/build/build-clang/tsan-hang-be41a98ac222.patch
@@ -10,21 +10,21 @@ A pthread_atfork callback triggers a dat
 and we deadlock on the report_mtx. Ignore memory access
 in the pthread_atfork callbacks to prevent the deadlock.
 ---
  compiler-rt/lib/tsan/rtl/tsan_rtl.cc          |  9 ++++
  .../test/tsan/pthread_atfork_deadlock2.c      | 49 +++++++++++++++++++
  2 files changed, 58 insertions(+)
  create mode 100644 compiler-rt/test/tsan/pthread_atfork_deadlock2.c
 
-diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl.ccc
-index fe469faad2a2..13c9b770f50a 100644
---- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc
-+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc
-@@ -495,14 +495,23 @@ int Finalize(ThreadState *thr) {
+diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
+index 3f3c0cce119..5e324a0a5fd 100644
+--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
+@@ -494,14 +494,23 @@ int Finalize(ThreadState *thr) {
  void ForkBefore(ThreadState *thr, uptr pc) {
    ctx->thread_registry->Lock();
    ctx->report_mtx.Lock();
 +  // Ignore memory accesses in the pthread_atfork callbacks.
 +  // If any of them triggers a data race we will deadlock
 +  // on the report_mtx.
 +  // We could ignore interceptors and sync operations as well,
 +  // but so far it's unclear if it will do more good or harm.
@@ -40,17 +40,17 @@ index fe469faad2a2..13c9b770f50a 100644
  
  void ForkChildAfter(ThreadState *thr, uptr pc) {
 +  ThreadIgnoreEnd(thr, pc);  // Begin is in ForkBefore.
    ctx->report_mtx.Unlock();
    ctx->thread_registry->Unlock();
  
 diff --git a/compiler-rt/test/tsan/pthread_atfork_deadlock2.c b/compiler-rt/test/tsan/pthread_atfork_deadlock2.c
 new file mode 100644
-index 000000000000..700507c1e637
+index 00000000000..700507c1e63
 --- /dev/null
 +++ b/compiler-rt/test/tsan/pthread_atfork_deadlock2.c
 @@ -0,0 +1,49 @@
 +// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
 +// Regression test for
 +// https://groups.google.com/d/msg/thread-sanitizer/e_zB9gYqFHM/DmAiTsrLAwAJ
 +// pthread_atfork() callback triggers a data race and we deadlocked
 +// on the report_mtx as we lock it around fork.
deleted file mode 100644
--- a/build/build-clang/tsan-hang-be41a98ac222_clang_10.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From be41a98ac222f33ed5558d86e1cede67249e99b5 Mon Sep 17 00:00:00 2001
-From: Dmitry Vyukov <dvyukov@google.com>
-Date: Sat, 21 Mar 2020 13:34:50 +0100
-Subject: [PATCH] tsan: fix deadlock with pthread_atfork callbacks
-
-This fixes the bug reported at:
-https://groups.google.com/forum/#!topic/thread-sanitizer/e_zB9gYqFHM
-
-A pthread_atfork callback triggers a data race
-and we deadlock on the report_mtx. Ignore memory access
-in the pthread_atfork callbacks to prevent the deadlock.
----
- compiler-rt/lib/tsan/rtl/tsan_rtl.cc          |  9 ++++
- .../test/tsan/pthread_atfork_deadlock2.c      | 49 +++++++++++++++++++
- 2 files changed, 58 insertions(+)
- create mode 100644 compiler-rt/test/tsan/pthread_atfork_deadlock2.c
-
-diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
-index 3f3c0cce119..5e324a0a5fd 100644
---- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
-+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
-@@ -494,14 +494,23 @@ int Finalize(ThreadState *thr) {
- void ForkBefore(ThreadState *thr, uptr pc) {
-   ctx->thread_registry->Lock();
-   ctx->report_mtx.Lock();
-+  // Ignore memory accesses in the pthread_atfork callbacks.
-+  // If any of them triggers a data race we will deadlock
-+  // on the report_mtx.
-+  // We could ignore interceptors and sync operations as well,
-+  // but so far it's unclear if it will do more good or harm.
-+  // Unnecessarily ignoring things can lead to false positives later.
-+  ThreadIgnoreBegin(thr, pc);
- }
- 
- void ForkParentAfter(ThreadState *thr, uptr pc) {
-+  ThreadIgnoreEnd(thr, pc);  // Begin is in ForkBefore.
-   ctx->report_mtx.Unlock();
-   ctx->thread_registry->Unlock();
- }
- 
- void ForkChildAfter(ThreadState *thr, uptr pc) {
-+  ThreadIgnoreEnd(thr, pc);  // Begin is in ForkBefore.
-   ctx->report_mtx.Unlock();
-   ctx->thread_registry->Unlock();
- 
-diff --git a/compiler-rt/test/tsan/pthread_atfork_deadlock2.c b/compiler-rt/test/tsan/pthread_atfork_deadlock2.c
-new file mode 100644
-index 00000000000..700507c1e63
---- /dev/null
-+++ b/compiler-rt/test/tsan/pthread_atfork_deadlock2.c
-@@ -0,0 +1,49 @@
-+// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-+// Regression test for
-+// https://groups.google.com/d/msg/thread-sanitizer/e_zB9gYqFHM/DmAiTsrLAwAJ
-+// pthread_atfork() callback triggers a data race and we deadlocked
-+// on the report_mtx as we lock it around fork.
-+#include "test.h"
-+#include <sys/types.h>
-+#include <sys/wait.h>
-+#include <errno.h>
-+
-+int glob = 0;
-+
-+void *worker(void *unused) {
-+  glob++;
-+  barrier_wait(&barrier);
-+  return NULL;
-+}
-+
-+void atfork() {
-+  glob++;
-+}
-+
-+int main() {
-+  barrier_init(&barrier, 2);
-+  pthread_atfork(atfork, NULL, NULL);
-+  pthread_t t;
-+  pthread_create(&t, NULL, worker, NULL);
-+  barrier_wait(&barrier);
-+  pid_t pid = fork();
-+  if (pid < 0) {
-+    fprintf(stderr, "fork failed: %d\n", errno);
-+    return 1;
-+  }
-+  if (pid == 0) {
-+    fprintf(stderr, "CHILD\n");
-+    return 0;
-+  }
-+  if (pid != waitpid(pid, NULL, 0)) {
-+    fprintf(stderr, "waitpid failed: %d\n", errno);
-+    return 1;
-+  }
-+  pthread_join(t, NULL);
-+  fprintf(stderr, "PARENT\n");
-+  return 0;
-+}
-+
-+// CHECK-NOT: ThreadSanitizer: data race
-+// CHECK: CHILD
-+// CHECK: PARENT
new file mode 100644
--- /dev/null
+++ b/build/build-clang/unpoison-thread-stacks-clang-9.patch
@@ -0,0 +1,62 @@
+[winasan] Unpoison the stack in NtTerminateThread
+
+In long-running builds we've seen some ASan complaints during thread creation
+that we suspect are due to leftover poisoning from previous threads whose stacks
+occupied that memory. This patch adds a hook that unpoisons the stack just
+before the NtTerminateThread syscall.
+
+Differential Revision: https://reviews.llvm.org/D52091
+
+** Update for clang 9 ** : After some backouts, this patch eventually landed
+upstream in a different form, as the TLS handler `asan_thread_exit`, but that
+variant causes failures in our test suite, so revert the TLS handler in favor of
+the interceptor approach from the first patch.
+
+--- a/compiler-rt/lib/asan/asan_win.cc
++++ b/compiler-rt/lib/asan/asan_win.cc
+@@ -154,6 +154,14 @@
+                             thr_flags, tid);
+ }
+ 
++INTERCEPTOR_WINAPI(void, NtTerminateThread, void *rcx) {
++  // Unpoison the terminating thread's stack because the memory may be re-used.
++  NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
++  uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
++  __asan_unpoison_memory_region(tib->StackLimit, stackSize);
++  return REAL(NtTerminateThread(rcx));
++}
++
+ // }}}
+ 
+ namespace __asan {
+@@ -168,7 +176,9 @@
+ 
+   ASAN_INTERCEPT_FUNC(CreateThread);
+   ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter);
+-
++  CHECK(::__interception::OverrideFunction("NtTerminateThread",
++                                           (uptr)WRAP(NtTerminateThread),
++                                           (uptr *)&REAL(NtTerminateThread)));
+ #ifdef _WIN64
+   ASAN_INTERCEPT_FUNC(__C_specific_handler);
+ #else
+@@ -380,19 +390,6 @@
+     void *, unsigned long, void *) = asan_thread_init;
+ #endif
+ 
+-static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) {
+-  if (reason == DLL_THREAD_DETACH) {
+-    // Unpoison the thread's stack because the memory may be re-used.
+-    NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
+-    uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
+-    __asan_unpoison_memory_region(tib->StackLimit, stackSize);
+-  }
+-}
+-
+-#pragma section(".CRT$XLY", long, read)  // NOLINT
+-__declspec(allocate(".CRT$XLY")) void(NTAPI *__asan_tls_exit)(
+-    void *, unsigned long, void *) = asan_thread_exit;
+-
+ WIN_FORCE_LINK(__asan_dso_reg_hook)
+ 
+ // }}}
--- a/build/build-clang/unpoison-thread-stacks.patch
+++ b/build/build-clang/unpoison-thread-stacks.patch
@@ -7,56 +7,58 @@ before the NtTerminateThread syscall.
 
 Differential Revision: https://reviews.llvm.org/D52091
 
 ** Update for clang 9 ** : After some backouts, this patch eventually landed
 upstream in a different form, as the TLS handler `asan_thread_exit`, but that
 variant causes failures in our test suite, so revert the TLS handler in favor of
 the interceptor approach from the first patch.
 
---- a/compiler-rt/lib/asan/asan_win.cc
-+++ b/compiler-rt/lib/asan/asan_win.cc
-@@ -154,6 +154,14 @@
+diff --git a/compiler-rt/lib/asan/asan_win.cpp b/compiler-rt/lib/asan/asan_win.cpp
+index 417892aaedd..5fe86db44f4 100644
+--- a/compiler-rt/lib/asan/asan_win.cpp
++++ b/compiler-rt/lib/asan/asan_win.cpp
+@@ -154,6 +154,14 @@ INTERCEPTOR_WINAPI(HANDLE, CreateThread, LPSECURITY_ATTRIBUTES security,
                              thr_flags, tid);
  }
  
 +INTERCEPTOR_WINAPI(void, NtTerminateThread, void *rcx) {
 +  // Unpoison the terminating thread's stack because the memory may be re-used.
 +  NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
 +  uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
 +  __asan_unpoison_memory_region(tib->StackLimit, stackSize);
 +  return REAL(NtTerminateThread(rcx));
 +}
 +
  // }}}
  
  namespace __asan {
-@@ -168,7 +176,9 @@
+@@ -168,7 +176,9 @@ void InitializePlatformInterceptors() {
  
    ASAN_INTERCEPT_FUNC(CreateThread);
    ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter);
 -
 +  CHECK(::__interception::OverrideFunction("NtTerminateThread",
 +                                           (uptr)WRAP(NtTerminateThread),
 +                                           (uptr *)&REAL(NtTerminateThread)));
  #ifdef _WIN64
    ASAN_INTERCEPT_FUNC(__C_specific_handler);
  #else
-@@ -380,19 +390,6 @@
+@@ -380,19 +390,6 @@ __declspec(allocate(".CRT$XLAB")) void(NTAPI *__asan_tls_init)(
      void *, unsigned long, void *) = asan_thread_init;
  #endif
  
 -static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) {
 -  if (reason == DLL_THREAD_DETACH) {
 -    // Unpoison the thread's stack because the memory may be re-used.
 -    NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
 -    uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
 -    __asan_unpoison_memory_region(tib->StackLimit, stackSize);
 -  }
 -}
 -
--#pragma section(".CRT$XLY", long, read)  // NOLINT
+-#pragma section(".CRT$XLY", long, read)
 -__declspec(allocate(".CRT$XLY")) void(NTAPI *__asan_tls_exit)(
 -    void *, unsigned long, void *) = asan_thread_exit;
 -
  WIN_FORCE_LINK(__asan_dso_reg_hook)
  
  // }}}
deleted file mode 100644
--- a/build/build-clang/unpoison-thread-stacks_clang_10.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-[winasan] Unpoison the stack in NtTerminateThread
-
-In long-running builds we've seen some ASan complaints during thread creation
-that we suspect are due to leftover poisoning from previous threads whose stacks
-occupied that memory. This patch adds a hook that unpoisons the stack just
-before the NtTerminateThread syscall.
-
-Differential Revision: https://reviews.llvm.org/D52091
-
-** Update for clang 9 ** : After some backouts, this patch eventually landed
-upstream in a different form, as the TLS handler `asan_thread_exit`, but that
-variant causes failures in our test suite, so revert the TLS handler in favor of
-the interceptor approach from the first patch.
-
-diff --git a/compiler-rt/lib/asan/asan_win.cpp b/compiler-rt/lib/asan/asan_win.cpp
-index 417892aaedd..5fe86db44f4 100644
---- a/compiler-rt/lib/asan/asan_win.cpp
-+++ b/compiler-rt/lib/asan/asan_win.cpp
-@@ -154,6 +154,14 @@ INTERCEPTOR_WINAPI(HANDLE, CreateThread, LPSECURITY_ATTRIBUTES security,
-                             thr_flags, tid);
- }
- 
-+INTERCEPTOR_WINAPI(void, NtTerminateThread, void *rcx) {
-+  // Unpoison the terminating thread's stack because the memory may be re-used.
-+  NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
-+  uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
-+  __asan_unpoison_memory_region(tib->StackLimit, stackSize);
-+  return REAL(NtTerminateThread(rcx));
-+}
-+
- // }}}
- 
- namespace __asan {
-@@ -168,7 +176,9 @@ void InitializePlatformInterceptors() {
- 
-   ASAN_INTERCEPT_FUNC(CreateThread);
-   ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter);
--
-+  CHECK(::__interception::OverrideFunction("NtTerminateThread",
-+                                           (uptr)WRAP(NtTerminateThread),
-+                                           (uptr *)&REAL(NtTerminateThread)));
- #ifdef _WIN64
-   ASAN_INTERCEPT_FUNC(__C_specific_handler);
- #else
-@@ -380,19 +390,6 @@ __declspec(allocate(".CRT$XLAB")) void(NTAPI *__asan_tls_init)(
-     void *, unsigned long, void *) = asan_thread_init;
- #endif
- 
--static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) {
--  if (reason == DLL_THREAD_DETACH) {
--    // Unpoison the thread's stack because the memory may be re-used.
--    NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
--    uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
--    __asan_unpoison_memory_region(tib->StackLimit, stackSize);
--  }
--}
--
--#pragma section(".CRT$XLY", long, read)
--__declspec(allocate(".CRT$XLY")) void(NTAPI *__asan_tls_exit)(
--    void *, unsigned long, void *) = asan_thread_exit;
--
- WIN_FORCE_LINK(__asan_dso_reg_hook)
- 
- // }}}
--- a/taskcluster/ci/build/linux.yml
+++ b/taskcluster/ci/build/linux.yml
@@ -1330,17 +1330,17 @@ linux64-ccov/opt:
         script: "mozharness/scripts/fx_desktop_build.py"
         secrets: true
         custom-build-variant-cfg: code-coverage-opt
         mozconfig-variant: code-coverage-opt
         tooltool-downloads: public
         need-xvfb: true
     fetches:
         toolchain:
-            - linux64-clang-9
+            - linux64-clang
             - linux64-rust
             - linux64-gcc-7
             - linux64-cbindgen
             - linux64-sccache
             - linux64-nasm
             - linux64-node
             - linux64-grcov
             - linux64-lucetc
--- a/taskcluster/ci/fetch/toolchains.yml
+++ b/taskcluster/ci/fetch/toolchains.yml
@@ -317,17 +317,17 @@ hfsplus-tools:
         sha256: b01b203a97f9a3bf36a027c13ddfc59292730552e62722d690d33bd5c24f5497
         size: 411205
 
 llvm-for-dsymutil:
     description: llvm source code for dsymutil
     fetch:
         type: git
         repo: https://github.com/llvm/llvm-project
-        revision: 3b7811f6441be13c9f613f81ef93297d231b4f8e
+        revision: d32170dbd5b0d54436537b6b75beaf44324e0c28
 
 rust-size:
     description: rust-size source code
     fetch:
         type: git
         repo: https://github.com/luser/rust-size
         revision: ab659d93b1faba95307df952aefe3fbed3583669
 
--- a/taskcluster/ci/toolchain/cbindgen.yml
+++ b/taskcluster/ci/toolchain/cbindgen.yml
@@ -37,17 +37,17 @@ macosx64-cbindgen:
         - trunk
     run:
         arguments: ['x86_64-apple-darwin']
         resources:
             - taskcluster/scripts/misc/tooltool-download.sh
         tooltool-downloads: internal
     fetches:
         toolchain:
-            - linux64-cctools-port
+            - linux64-cctools-clang-9-port
             - linux64-clang-9
             - linux64-llvm-dsymutil
             - linux64-rust-macos-1.41
 
 win64-cbindgen:
     treeherder:
         symbol: TW64(cbindgen)
     worker-type: b-win2012
--- a/taskcluster/ci/toolchain/cctools-port.yml
+++ b/taskcluster/ci/toolchain/cctools-port.yml
@@ -7,31 +7,31 @@ job-defaults:
     worker-type: b-linux
     worker:
         max-run-time: 1800
     fetches:
         fetch:
             - cctools-port
             - libtapi
 
-linux64-cctools-port:
+linux64-cctools-clang-9-port:
     treeherder:
-        symbol: TL(cctools)
+        symbol: TL(cctools-clang-9)
     run:
         script: build-cctools-port.sh
         toolchain-artifact: public/build/cctools.tar.xz
         tooltool-downloads: internal
     fetches:
         toolchain:
             - linux64-clang-9
             - linux64-binutils
 
-linux64-cctools-clang-10-port:
+linux64-cctools-port:
     treeherder:
-        symbol: TL(cctools-clang-10)
+        symbol: TL(cctools)
     run:
         script: build-cctools-port.sh
         toolchain-artifact: public/build/cctools.tar.xz
         tooltool-downloads: internal
     fetches:
         toolchain:
             - linux64-clang-10
             - linux64-binutils
--- a/taskcluster/ci/toolchain/clang-tidy.yml
+++ b/taskcluster/ci/toolchain/clang-tidy.yml
@@ -57,17 +57,17 @@ macosx64-clang-tidy:
         arguments:
             - 'build/build-clang/clang-tidy-macosx64.json'
         resources:
             - 'build/build-clang/clang-tidy-macosx64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
     fetches:
         toolchain:
             - linux64-binutils
-            - linux64-cctools-clang-10-port
+            - linux64-cctools-port
             - linux64-clang-10
             - linux64-gcc-7
             - linux64-node
 
 win64-clang-tidy:
     description: "Clang-tidy toolchain build"
     index:
         job-name: win64-clang-tidy
--- a/taskcluster/ci/toolchain/clang.yml
+++ b/taskcluster/ci/toolchain/clang.yml
@@ -50,20 +50,19 @@ linux64-clang-7:
 linux64-clang-9:
     description: "Clang 9 toolchain build"
     treeherder:
         symbol: TL(clang9)
     run:
         using: toolchain-script
         script: build-clang.sh
         arguments:
-            - 'build/build-clang/clang-linux64.json'
+            - 'build/build-clang/clang-9-linux64.json'
         resources:
-            - 'build/build-clang/clang-linux64.json'
-        toolchain-alias: linux64-clang
+            - 'build/build-clang/clang-9-linux64.json'
         toolchain-artifact: public/build/clang.tar.xz
     fetches:
         fetch:
             - clang-9
         toolchain:
             - linux64-binutils
             - linux64-gcc-7
             - wasi-sysroot
@@ -112,65 +111,65 @@ linux64-clang-9-mingw-x64:
             - mingw-w64
             - libunwind
             - llvm-mingw
             - gcc-9.1.0
         toolchain:
             - linux64-gcc-7
             - linux64-binutils
 
-linux64-clang-9-android-cross:
-    description: "Clang 9 toolchain build"
+linux64-clang-10-android-cross:
+    description: "Clang 10 toolchain build"
     treeherder:
-        symbol: TL(clang9-android)
+        symbol: TL(clang10-android)
     run:
         using: toolchain-script
         script: build-clang.sh
         arguments:
             - 'build/build-clang/clang-android.json'
         resources:
             - 'build/build-clang/clang-android.json'
         toolchain-alias: linux64-clang-android-cross
         toolchain-artifact: public/build/clang.tar.xz
     fetches:
         fetch:
-            - clang-9
+            - clang-10
         toolchain:
             - linux64-binutils
             - linux64-gcc-7
             - linux64-android-ndk-linux-repack
 
-linux64-clang-9-aarch64-cross:
-    description: "Clang 9 toolchain build with aarch64 runtime"
+linux64-clang-10-aarch64-cross:
+    description: "Clang 10 toolchain build with aarch64 runtime"
     treeherder:
-        symbol: TL(clang9-aarch64)
+        symbol: TL(clang10-aarch64)
     worker-type: b-linux
     worker:
         max-run-time: 5400
         docker-image: {in-tree: toolchain-arm64-build}
     run:
         using: toolchain-script
         script: build-clang.sh
         arguments:
             - 'build/build-clang/clang-linux64-aarch64-cross.json'
         resources:
             - 'build/build-clang/clang-linux64-aarch64-cross.json'
         toolchain-alias: linux64-clang-aarch64-cross
         toolchain-artifact: public/build/clang.tar.xz
     fetches:
         fetch:
-            - clang-9
+            - clang-10
         toolchain:
             - linux64-binutils
             - linux64-gcc-7
 
-linux64-clang-9-macosx-cross:
-    description: "Clang 9 toolchain build with MacOS Compiler RT libs"
+linux64-clang-10-macosx-cross:
+    description: "Clang 10 toolchain build with MacOS Compiler RT libs"
     treeherder:
-        symbol: TL(clang9-macosx-cross)
+        symbol: TL(clang10-macosx-cross)
     worker-type: b-linux
     worker:
         max-run-time: 3600
         env:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/macosx64/cross-releng.manifest"
     run:
         script: build-clang-linux-macosx-cross.sh
         arguments:
@@ -178,55 +177,56 @@ linux64-clang-9-macosx-cross:
         resources:
             - 'build/build-clang/clang-macosx64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-alias: linux64-clang-macosx-cross
         toolchain-artifact: public/build/clang.tar.xz
         tooltool-downloads: internal
     fetches:
         fetch:
-            - clang-9
+            - clang-10
         toolchain:
             - linux64-binutils
             - linux64-cctools-port
-            - linux64-clang-9
+            - linux64-clang-10
             - linux64-gcc-7
 
-linux64-clang-9-win-cross:
-    description: "Clang 9 toolchain build with Windows Compiler RT libs"
+linux64-clang-10-win-cross:
+    description: "Clang 10 toolchain build with Windows Compiler RT libs"
     treeherder:
-        symbol: TL(clang9-win-cross)
+        symbol: TL(clang10-win-cross)
     worker-type: b-linux
     worker:
         max-run-time: 600
     run:
         script: build-clang-linux-win-cross.sh
         toolchain-alias: linux64-clang-win-cross
         toolchain-artifact: public/build/clang.tar.xz
     dependencies:
         win64-clang-cl-2stage: toolchain-win64-clang-cl-2stage
     fetches:
         toolchain:
-            - linux64-clang-9
+            - linux64-clang-10
         win64-clang-cl-2stage:
             - artifact: clang.tar.bz2
               extract: false
 
 
 linux64-clang-10:
     description: "Clang 10 toolchain build"
     treeherder:
         symbol: TL(clang10)
     run:
         using: toolchain-script
         script: build-clang.sh
         arguments:
-            - 'build/build-clang/clang-10-linux64.json'
+            - 'build/build-clang/clang-linux64.json'
         resources:
-            - 'build/build-clang/clang-10-linux64.json'
+            - 'build/build-clang/clang-linux64.json'
+        toolchain-alias: linux64-clang
         toolchain-artifact: public/build/clang.tar.xz
     fetches:
         fetch:
             - clang-10
         toolchain:
             - linux64-binutils
             - linux64-gcc-7
             - wasi-sysroot
@@ -248,21 +248,21 @@ macosx64-clang:
         arguments:
             - 'build/build-clang/clang-macosx64.json'
         resources:
             - 'build/build-clang/clang-macosx64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/clang.tar.xz
     fetches:
         fetch:
-            - clang-9
+            - clang-10
         toolchain:
             - linux64-binutils
             - linux64-cctools-port
-            - linux64-clang-9
+            - linux64-clang-10
             - linux64-gcc-7
             - linux64-node
 
 win64-clang-cl:
     description: "Clang-cl toolchain build"
     treeherder:
         symbol: TW64(clang-cl)
     worker-type: b-win2012
@@ -275,17 +275,17 @@ win64-clang-cl:
             - 'build/build-clang/clang-win64.json'
         resources:
             - 'build/build-clang/clang-win64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/clang.tar.bz2
         tooltool-downloads: internal
     fetches:
         fetch:
-            - clang-9
+            - clang-10
             - cmake
             - ninja
 
 win64-clang-cl-2stage:
     description: "Clang-cl toolchain 2-stage quick build"
     treeherder:
         symbol: TW64(clang-cl-2stage)
     worker-type: b-win2012
@@ -298,11 +298,11 @@ win64-clang-cl-2stage:
             - 'build/build-clang/clang-win64-2stage.json'
         resources:
             - 'build/build-clang/clang-win64-2stage.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/clang.tar.bz2
         tooltool-downloads: internal
     fetches:
         fetch:
-            - clang-9
+            - clang-10
             - cmake
             - ninja
--- a/taskcluster/ci/toolchain/dist-toolchains.yml
+++ b/taskcluster/ci/toolchain/dist-toolchains.yml
@@ -16,17 +16,17 @@ clang-dist-toolchain:
         symbol: TL(clang-dist)
     worker:
         max-run-time: 1800
     run:
         arguments: ['clang']
         toolchain-artifact: public/build/clang-dist-toolchain.tar.xz
     fetches:
         toolchain:
-            - linux64-clang-9
+            - linux64-clang-10
             - linux64-sccache
 
 rustc-dist-toolchain:
     treeherder:
         symbol: TL(rustc-dist)
     worker:
         max-run-time: 1800
     run:
--- a/taskcluster/ci/toolchain/fix-stacks.yml
+++ b/taskcluster/ci/toolchain/fix-stacks.yml
@@ -36,17 +36,17 @@ macosx64-fix-stacks:
     run:
         arguments: ['x86_64-apple-darwin']
         resources:
             - taskcluster/scripts/misc/tooltool-download.sh
         toolchain-artifact: public/build/fix-stacks.tar.xz
         tooltool-downloads: internal
     fetches:
         toolchain:
-            - linux64-cctools-port
+            - linux64-cctools-clang-9-port
             - linux64-clang-9
             - linux64-rust-macos
 
 win32-fix-stacks:
     treeherder:
         symbol: TW32(fix-stacks)
     worker:
         env:
--- a/taskcluster/ci/toolchain/gn.yml
+++ b/taskcluster/ci/toolchain/gn.yml
@@ -34,17 +34,17 @@ macosx64-gn:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/macosx64/cross-releng.manifest"
     run:
         script: build-gn-macosx.sh
         resources:
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         tooltool-downloads: internal
     fetches:
         toolchain:
-            - linux64-cctools-port
+            - linux64-cctools-clang-9-port
             - linux64-clang-9
 
 win32-gn:
     treeherder:
         symbol: TW64(gn)
     worker-type: b-win2012
     worker:
         max-run-time: 3600
--- a/taskcluster/ci/toolchain/minidump_stackwalk.yml
+++ b/taskcluster/ci/toolchain/minidump_stackwalk.yml
@@ -42,17 +42,17 @@ macosx64-minidump-stackwalk:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/macosx64/cross-releng.manifest"
     run:
         arguments: ['macosx64']
         resources:
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         tooltool-downloads: internal
     fetches:
         toolchain:
-            - linux64-cctools-port
+            - linux64-cctools-clang-9-port
             - linux64-clang-9
             - linux64-rust-macos-1.41
 
 win32-minidump-stackwalk:
     treeherder:
         symbol: TW32(stackwalk)
     worker:
         docker-image: {in-tree: mingw32-build}
--- a/taskcluster/ci/toolchain/misc.yml
+++ b/taskcluster/ci/toolchain/misc.yml
@@ -145,17 +145,17 @@ wasi-sysroot:
     treeherder:
         symbol: TL(wasi-sysroot)
     run:
         script: build-wasi-sysroot.sh
         sparse-profile: null
         toolchain-artifact: public/build/wasi-sysroot.tar.xz
     fetches:
         fetch:
-            - clang-9
+            - clang-10
             - wasi-sdk
         toolchain:
             - linux64-binutils
             - linux64-gcc-7
 
 wrench-deps:
     description: "Downloads all the crates needed for building wrench"
     treeherder:
--- a/taskcluster/ci/toolchain/sccache.yml
+++ b/taskcluster/ci/toolchain/sccache.yml
@@ -41,17 +41,17 @@ macosx64-sccache:
         resources:
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         tooltool-downloads: internal
         toolchain-artifact: public/build/sccache.tar.xz
     fetches:
         toolchain:
             - linux64-rust-macos-1.41
             - linux64-clang-9
-            - linux64-cctools-port
+            - linux64-cctools-clang-9-port
             - linux64-llvm-dsymutil
             - linux64-binutils
 
 win64-sccache:
     treeherder:
         symbol: TW64(sccache)
     worker-type: b-win2012
     worker: