[Bf-blender-cvs] [9deeb8eb222] functions: use centralized pool to reuse llvm contexts

Jacques Lucke noreply at git.blender.org
Thu May 2 10:48:43 CEST 2019


Commit: 9deeb8eb222593d6676eb41022b868ff67357da7
Author: Jacques Lucke
Date:   Thu May 2 10:48:30 2019 +0200
Branches: functions
https://developer.blender.org/rB9deeb8eb222593d6676eb41022b868ff67357da7

use centralized pool to reuse llvm contexts

===================================================================

A	source/blender/blenlib/BLI_object_pool.hpp
M	source/blender/blenlib/CMakeLists.txt
M	source/blender/functions/CMakeLists.txt
A	source/blender/functions/backends/llvm/context_pool.cpp
A	source/blender/functions/backends/llvm/context_pool.hpp
M	source/blender/functions/backends/llvm/ir_to_tuple_call.cpp
M	source/blender/functions/backends/llvm/ir_to_tuple_call.hpp
M	source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
M	source/blender/functions/functions/auto_vectorization.cpp
M	tests/gtests/functions/functions_test.cc

===================================================================

diff --git a/source/blender/blenlib/BLI_object_pool.hpp b/source/blender/blenlib/BLI_object_pool.hpp
new file mode 100644
index 00000000000..2c11543ad9b
--- /dev/null
+++ b/source/blender/blenlib/BLI_object_pool.hpp
@@ -0,0 +1,66 @@
+#pragma once
+
+#include <mutex>
+
+#include "BLI_small_stack.hpp"
+#include "BLI_small_set.hpp"
+
+namespace BLI {
+
+template<typename T> class ThreadSafeObjectPool {
+ private:
+  std::mutex m_mutex;
+  SmallStack<T *> m_free_objects;
+
+#ifdef DEBUG
+  SmallSet<T *> m_all_objects;
+#else
+  SmallVector<T *> m_all_objects;
+#endif
+
+ public:
+  ThreadSafeObjectPool() = default;
+  ThreadSafeObjectPool(ThreadSafeObjectPool &other) = delete;
+
+  ~ThreadSafeObjectPool()
+  {
+    BLI_assert(m_free_objects.size() == m_all_objects.size());
+    for (T *object : m_all_objects) {
+      delete object;
+    }
+  }
+
+  T *aquire()
+  {
+    std::lock_guard<std::mutex> lock(m_mutex);
+
+    if (m_free_objects.empty()) {
+      T *new_object = new T();
+      this->remember(new_object);
+      return new_object;
+    }
+    else {
+      return m_free_objects.pop();
+    }
+  }
+
+  void release(T *object)
+  {
+    std::lock_guard<std::mutex> lock(m_mutex);
+
+    BLI_assert(m_all_objects.contains(object));
+    m_free_objects.push(object);
+  }
+
+ private:
+  void remember(T *object)
+  {
+#ifdef DEBUG
+    m_all_objects.add(object);
+#else
+    m_all_objects.append(object);
+#endif
+  }
+};
+
+}  // namespace BLI
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 150aea7da5f..9a8e5f71193 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -240,6 +240,7 @@ set(SRC
   BLI_mempool.hpp
   BLI_multimap.hpp
   BLI_multipool.hpp
+  BLI_object_pool.hpp
   BLI_optional.hpp
   BLI_range.hpp
   BLI_shared.hpp
diff --git a/source/blender/functions/CMakeLists.txt b/source/blender/functions/CMakeLists.txt
index 5bdd5317319..e1f0416729e 100644
--- a/source/blender/functions/CMakeLists.txt
+++ b/source/blender/functions/CMakeLists.txt
@@ -93,6 +93,8 @@ set(SRC
   backends/llvm/fgraph_ir_generation.cpp
   backends/llvm/builder.hpp
   backends/llvm/builder.cpp
+  backends/llvm/context_pool.hpp
+  backends/llvm/context_pool.cpp
 
   types/lists.hpp
   types/numeric_lists.hpp
diff --git a/source/blender/functions/backends/llvm/context_pool.cpp b/source/blender/functions/backends/llvm/context_pool.cpp
new file mode 100644
index 00000000000..36a05bf437a
--- /dev/null
+++ b/source/blender/functions/backends/llvm/context_pool.cpp
@@ -0,0 +1,18 @@
+#include "context_pool.hpp"
+#include "BLI_object_pool.hpp"
+
+namespace FN {
+
+static BLI::ThreadSafeObjectPool<llvm::LLVMContext> contexts;
+
+llvm::LLVMContext *aquire_llvm_context()
+{
+  return contexts.aquire();
+}
+
+void release_llvm_context(llvm::LLVMContext *context)
+{
+  contexts.release(context);
+}
+
+};  // namespace FN
diff --git a/source/blender/functions/backends/llvm/context_pool.hpp b/source/blender/functions/backends/llvm/context_pool.hpp
new file mode 100644
index 00000000000..30cfb3600ee
--- /dev/null
+++ b/source/blender/functions/backends/llvm/context_pool.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "llvm/IR/LLVMContext.h"
+
+namespace FN {
+
+llvm::LLVMContext *aquire_llvm_context();
+void release_llvm_context(llvm::LLVMContext *context);
+
+}  // namespace FN
diff --git a/source/blender/functions/backends/llvm/ir_to_tuple_call.cpp b/source/blender/functions/backends/llvm/ir_to_tuple_call.cpp
index 62c62fd7b3e..bfc6058c712 100644
--- a/source/blender/functions/backends/llvm/ir_to_tuple_call.cpp
+++ b/source/blender/functions/backends/llvm/ir_to_tuple_call.cpp
@@ -5,6 +5,8 @@
 #include <llvm/Support/TargetSelect.h>
 #include <llvm/ExecutionEngine/ExecutionEngine.h>
 
+#include "context_pool.hpp"
+
 namespace FN {
 
 typedef std::function<void(
@@ -127,12 +129,14 @@ static TupleCallBody *compile_ir_to_tuple_call(SharedFunction &fn, llvm::LLVMCon
   return new LLVMTupleCall(std::move(compiled));
 }
 
-void derive_TupleCallBody_from_LLVMBuildIRBody(SharedFunction &fn, llvm::LLVMContext &context)
+void derive_TupleCallBody_from_LLVMBuildIRBody(SharedFunction &fn)
 {
   BLI_assert(fn->has_body<LLVMBuildIRBody>());
   BLI_assert(!fn->has_body<TupleCallBody>());
 
-  fn->add_body(compile_ir_to_tuple_call(fn, context));
+  auto *context = aquire_llvm_context();
+  fn->add_body(compile_ir_to_tuple_call(fn, *context));
+  release_llvm_context(context);
 }
 
 } /* namespace FN */
diff --git a/source/blender/functions/backends/llvm/ir_to_tuple_call.hpp b/source/blender/functions/backends/llvm/ir_to_tuple_call.hpp
index fd01754a627..0a8924d7949 100644
--- a/source/blender/functions/backends/llvm/ir_to_tuple_call.hpp
+++ b/source/blender/functions/backends/llvm/ir_to_tuple_call.hpp
@@ -2,12 +2,8 @@
 
 #include "FN_core.hpp"
 
-namespace llvm {
-class LLVMContext;
-}
-
 namespace FN {
 
-void derive_TupleCallBody_from_LLVMBuildIRBody(SharedFunction &fn, llvm::LLVMContext &context);
+void derive_TupleCallBody_from_LLVMBuildIRBody(SharedFunction &fn);
 
 } /* namespace FN */
diff --git a/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp b/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
index 70d384a8b9f..9c06ff727e2 100644
--- a/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
+++ b/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
@@ -5,8 +5,6 @@ namespace FN {
 
 static void try_ensure_tuple_call_bodies(SharedDataFlowGraph &graph)
 {
-  auto *context = new llvm::LLVMContext();
-
   for (uint node_id : graph->node_ids()) {
     SharedFunction &fn = graph->function_of_node(node_id);
     if (fn->has_body<TupleCallBody>()) {
@@ -18,7 +16,7 @@ static void try_ensure_tuple_call_bodies(SharedDataFlowGraph &graph)
     }
 
     if (fn->has_body<LLVMBuildIRBody>()) {
-      derive_TupleCallBody_from_LLVMBuildIRBody(fn, *context);
+      derive_TupleCallBody_from_LLVMBuildIRBody(fn);
     }
   }
 }
diff --git a/source/blender/functions/functions/auto_vectorization.cpp b/source/blender/functions/functions/auto_vectorization.cpp
index 8a503a37246..8a01c447f78 100644
--- a/source/blender/functions/functions/auto_vectorization.cpp
+++ b/source/blender/functions/functions/auto_vectorization.cpp
@@ -377,7 +377,7 @@ SharedFunction to_vectorized_function(SharedFunction &original_fn,
 
   if (!original_fn->has_body<TupleCallBody>()) {
     if (original_fn->has_body<LLVMBuildIRBody>()) {
-      derive_TupleCallBody_from_LLVMBuildIRBody(original_fn, *(new llvm::LLVMContext()));
+      derive_TupleCallBody_from_LLVMBuildIRBody(original_fn);
     }
     else {
       BLI_assert(false);
diff --git a/tests/gtests/functions/functions_test.cc b/tests/gtests/functions/functions_test.cc
index d76d5489184..2948e9846a8 100644
--- a/tests/gtests/functions/functions_test.cc
+++ b/tests/gtests/functions/functions_test.cc
@@ -50,7 +50,7 @@ TEST_F(functions_impl, FloatRange)
 TEST_F(functions_impl, AddFloats)
 {
   auto fn = Functions::GET_FN_add_floats();
-  derive_TupleCallBody_from_LLVMBuildIRBody(fn, *(new llvm::LLVMContext()));
+  derive_TupleCallBody_from_LLVMBuildIRBody(fn);
   PREPARE_TUPLE_CALL_TEST(fn);
 
   fn_in.set<float>(0, 3.5f);



More information about the Bf-blender-cvs mailing list