From f709bd063339c1f1bbbf29b2bced482e40262c81 Mon Sep 17 00:00:00 2001
From: lin-hitonami <linjiang@taichi.graphics>
Date: Mon, 11 Jul 2022 17:11:55 +0800
Subject: [PATCH 1/2] [llvm] (Decomp of #5251 9/n) Make SNode tree compatible
 with parallel compilation

---
 taichi/runtime/llvm/llvm_context.cpp | 31 +++++++++++++++++++++++++---
 taichi/runtime/llvm/llvm_context.h   |  5 +++++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/taichi/runtime/llvm/llvm_context.cpp b/taichi/runtime/llvm/llvm_context.cpp
index 303a30fe97f21..c0cffdd253a3c 100644
--- a/taichi/runtime/llvm/llvm_context.cpp
+++ b/taichi/runtime/llvm/llvm_context.cpp
@@ -515,16 +515,30 @@ std::unique_ptr<llvm::Module> TaichiLLVMContext::clone_struct_module() {
 
 void TaichiLLVMContext::set_struct_module(
     const std::unique_ptr<llvm::Module> &module) {
-  auto data = get_this_thread_data();
+  TI_ASSERT(std::this_thread::get_id() == main_thread_id_);
+  auto this_thread_data = get_this_thread_data();
   TI_ASSERT(module);
   if (llvm::verifyModule(*module, &llvm::errs())) {
     module->print(llvm::errs(), nullptr);
     TI_ERROR("module broken");
   }
   // TODO: Move this after ``if (!arch_is_cpu(arch))``.
-  data->struct_module = llvm::CloneModule(*module);
+  this_thread_data->struct_module = llvm::CloneModule(*module);
+  for (auto &[id, data] : per_thread_data_) {
+    if (id == std::this_thread::get_id()) {
+      continue;
+    }
+    TI_ASSERT(!data->runtime_module);
+    data->struct_module.reset();
+    old_contexts_.push_back(std::move(data->thread_safe_llvm_context));
+    data->thread_safe_llvm_context =
+        std::make_unique<llvm::orc::ThreadSafeContext>(
+            std::make_unique<llvm::LLVMContext>());
+    data->llvm_context = data->thread_safe_llvm_context->getContext();
+    data->struct_module = clone_module_to_context(
+        this_thread_data->struct_module.get(), data->llvm_context);
+  }
 }
-
 template <typename T>
 llvm::Value *TaichiLLVMContext::get_constant(DataType dt, T t) {
   auto ctx = get_this_thread_context();
@@ -823,12 +837,23 @@ void TaichiLLVMContext::delete_functions_of_snode_tree(int id) {
     func->eraseFromParent();
   }
   snode_tree_funcs_.erase(id);
+  set_struct_module(get_this_thread_data()->struct_module);
 }
 
 void TaichiLLVMContext::add_function_to_snode_tree(int id, std::string func) {
   snode_tree_funcs_[id].push_back(func);
 }
 
+TaichiLLVMContext::ThreadLocalData::~ThreadLocalData() {
+  if (struct_module) {
+    TI_ASSERT(&struct_module->getContext() ==
+              thread_safe_llvm_context->getContext());
+  }
+  runtime_module.reset();
+  struct_module.reset();
+  thread_safe_llvm_context.reset();
+}
+
 TI_REGISTER_TASK(make_slim_libdevice);
 
 }  // namespace lang
diff --git a/taichi/runtime/llvm/llvm_context.h b/taichi/runtime/llvm/llvm_context.h
index 08cd8daa2d96c..f72d7965f1032 100644
--- a/taichi/runtime/llvm/llvm_context.h
+++ b/taichi/runtime/llvm/llvm_context.h
@@ -31,6 +31,7 @@ class TaichiLLVMContext {
         nullptr};
     std::unique_ptr<llvm::Module> runtime_module{nullptr};
     std::unique_ptr<llvm::Module> struct_module{nullptr};
+    ~ThreadLocalData();
   };
 
  public:
@@ -162,6 +163,9 @@ class TaichiLLVMContext {
   std::mutex thread_map_mut_;
 
   std::unordered_map<int, std::vector<std::string>> snode_tree_funcs_;
+  std::vector<std::unique_ptr<llvm::orc::ThreadSafeContext>>
+      old_contexts_;  // Contains old contexts that have modules stored inside
+                      // the offline cache.
 };
 
 class LlvmModuleBitcodeLoader {
@@ -187,6 +191,7 @@ class LlvmModuleBitcodeLoader {
   std::string bitcode_path_;
   std::string buffer_id_;
   bool inline_funcs_{false};
+
 };
 
 std::unique_ptr<llvm::Module> module_from_bitcode_file(

From 42bfddc66fc10d13f3f9331c9944b0e9fd85f606 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
 <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Mon, 11 Jul 2022 09:13:57 +0000
Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci
---
 taichi/runtime/llvm/llvm_context.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/taichi/runtime/llvm/llvm_context.h b/taichi/runtime/llvm/llvm_context.h
index f72d7965f1032..09f602559db77 100644
--- a/taichi/runtime/llvm/llvm_context.h
+++ b/taichi/runtime/llvm/llvm_context.h
@@ -191,7 +191,6 @@ class LlvmModuleBitcodeLoader {
   std::string bitcode_path_;
   std::string buffer_id_;
   bool inline_funcs_{false};
-
 };
 
 std::unique_ptr<llvm::Module> module_from_bitcode_file(