Commit: af27ce2497dbc451e47cafcbed7ce66854479f14
Author: Lukas Tönne
Date:   Fri Jun 24 10:23:30 2016 +0200
Branches: object_nodes
https://developer.blender.org/rBaf27ce2497dbc451e47cafcbed7ce66854479f14

Use a hash table to register external functions with the LLVM engine.

This will allow using BLI/BKE code for complex data types, such as DerivedMesh.

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

M       source/blender/blenvm/llvm/llvm_engine.cc
M       source/blender/blenvm/llvm/llvm_engine.h
M       source/blender/blenvm/llvm/llvm_modules.cc
M       source/blender/blenvm/llvm/llvm_modules.h

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

diff --git a/source/blender/blenvm/llvm/llvm_engine.cc 
b/source/blender/blenvm/llvm/llvm_engine.cc
index db057df..eed04ba 100644
--- a/source/blender/blenvm/llvm/llvm_engine.cc
+++ b/source/blender/blenvm/llvm/llvm_engine.cc
@@ -33,12 +33,12 @@
 
 extern "C" {
 #include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+#include "BLI_string.h"
 }
 
 #include "util_opcode.h"
 
-#include "modules.h"
-
 #include "llvm_codegen.h"
 #include "llvm_engine.h"
 #include "llvm_headers.h"
@@ -53,29 +53,8 @@ static llvm::Module *theModule = NULL;
 static llvm::legacy::PassManager *theModulePassMgr[3] = {0};
 static llvm::legacy::FunctionPassManager *theFunctionPassMgr[3] = {0};
 
-bool llvm_has_external_impl_value(OpCode node_op) {
-#define DEF_OPCODE(op) \
-       if (node_op == OP_##op) \
-               return modules::get_node_impl_value<OP_##op>() != NULL; \
-       else
-
-       BVM_DEFINE_OPCODES
-       return false;
-
-#undef DEF_OPCODE
-}
-
-bool llvm_has_external_impl_deriv(OpCode node_op) {
-#define DEF_OPCODE(op) \
-       if (node_op == OP_##op) \
-               return modules::get_node_impl_deriv<OP_##op>() != NULL; \
-       else
-
-       BVM_DEFINE_OPCODES
-       return false;
+static struct GHash *extern_functions = NULL;
 
-#undef DEF_OPCODE
-}
 
 class MemoryManager : public llvm::SectionMemoryManager {
 public:
@@ -84,21 +63,6 @@ public:
        virtual ~MemoryManager()
        {}
        
-       static void *get_node_function_ptr(const string &name) {
-#define DEF_OPCODE(op) \
-               if (name == bvm_value_function_name(STRINGIFY(op))) \
-                       return modules::get_node_impl_value<OP_##op>(); \
-               else if (name == bvm_deriv_function_name(STRINGIFY(op))) \
-                       return modules::get_node_impl_deriv<OP_##op>(); \
-               else
-       
-               BVM_DEFINE_OPCODES
-               return NULL;
-       
-#undef DEF_OPCODE
-       
-       }
-       
        /// This method returns the address of the specified function or 
variable.
        /// It is used to resolve symbols during module linking.
        uint64_t getSymbolAddress(const std::string &Name) override
@@ -107,7 +71,7 @@ public:
                if (addr)
                        return addr;
                
-               void *ptr = get_node_function_ptr(Name);
+               void *ptr = BLI_ghash_lookup(extern_functions, Name.c_str());
                return (uint64_t)ptr;
        }
 };
@@ -190,6 +154,9 @@ void llvm_init()
 {
        using namespace llvm;
        
+       extern_functions = BLI_ghash_str_new("LLVM external functions hash");
+       register_extern_node_functions();
+       
        InitializeNativeTarget();
        InitializeNativeTargetAsmPrinter();
        InitializeNativeTargetAsmParser();
@@ -202,6 +169,11 @@ void llvm_init()
        LLVMCodeGenerator::define_nodes_module(getGlobalContext());
 }
 
+static void extern_functions_keyfree(void *key)
+{
+       MEM_freeN(key);
+}
+
 void llvm_free()
 {
        if (theEngine) {
@@ -215,6 +187,8 @@ void llvm_free()
                if (theFunctionPassMgr[opt_level])
                        delete theFunctionPassMgr[opt_level];
        }
+       
+       BLI_ghash_free(extern_functions, extern_functions_keyfree, NULL);
 }
 
 llvm::ExecutionEngine *llvm_execution_engine()
@@ -222,6 +196,17 @@ llvm::ExecutionEngine *llvm_execution_engine()
        return theEngine;
 }
 
+void llvm_register_external_function(const string &name, void *func)
+{
+       char *namebuf = BLI_strdup(name.c_str());
+       BLI_ghash_insert(extern_functions, namebuf, func);
+}
+
+bool llvm_has_external_function(const string &name)
+{
+       return BLI_ghash_haskey(extern_functions, name.c_str());
+}
+
 void llvm_optimize_module(llvm::Module *mod, int opt_level)
 {
        using namespace llvm;
diff --git a/source/blender/blenvm/llvm/llvm_engine.h 
b/source/blender/blenvm/llvm/llvm_engine.h
index 601a883..7b6b28e 100644
--- a/source/blender/blenvm/llvm/llvm_engine.h
+++ b/source/blender/blenvm/llvm/llvm_engine.h
@@ -48,12 +48,12 @@ void llvm_free();
 
 llvm::ExecutionEngine *llvm_execution_engine();
 
+void llvm_register_external_function(const string &name, void *func);
+bool llvm_has_external_function(const string &name);
+
 void llvm_optimize_module(llvm::Module *mod, int opt_level);
 void llvm_optimize_function(llvm::Function *func, int opt_level);
 
-bool llvm_has_external_impl_value(OpCode op);
-bool llvm_has_external_impl_deriv(OpCode op);
-
 } /* namespace blenvm */
 
 #endif /* __LLVM_ENGINE_H__ */
diff --git a/source/blender/blenvm/llvm/llvm_modules.cc 
b/source/blender/blenvm/llvm/llvm_modules.cc
index 3c74bbe..fcde642 100644
--- a/source/blender/blenvm/llvm/llvm_modules.cc
+++ b/source/blender/blenvm/llvm/llvm_modules.cc
@@ -58,6 +58,47 @@ namespace blenvm {
 
 typedef llvm::IRBuilder<> Builder;
 
+void register_extern_node_functions()
+{
+#define DEF_OPCODE(op) \
+       { \
+               void *func_value = modules::get_node_impl_value<OP_##op>(); \
+               if (func_value != NULL) \
+                       
llvm_register_external_function(bvm_value_function_name(STRINGIFY(op)), 
func_value); \
+               void *func_deriv = modules::get_node_impl_deriv<OP_##op>(); \
+               if (func_deriv != NULL) \
+                       
llvm_register_external_function(bvm_deriv_function_name(STRINGIFY(op)), 
func_value); \
+       }
+       
+       BVM_DEFINE_OPCODES
+       
+#undef DEF_OPCODE
+}
+
+bool llvm_has_external_impl_value(OpCode node_op) {
+#define DEF_OPCODE(op) \
+       if (node_op == OP_##op) \
+               return modules::get_node_impl_value<OP_##op>() != NULL; \
+       else
+
+       BVM_DEFINE_OPCODES
+       return false;
+
+#undef DEF_OPCODE
+}
+
+bool llvm_has_external_impl_deriv(OpCode node_op) {
+#define DEF_OPCODE(op) \
+       if (node_op == OP_##op) \
+               return modules::get_node_impl_deriv<OP_##op>() != NULL; \
+       else
+
+       BVM_DEFINE_OPCODES
+       return false;
+
+#undef DEF_OPCODE
+}
+
 static llvm::Value *float_vector_at(Builder &builder, llvm::Value *p_vec, 
llvm::Value *idx)
 {
        using namespace llvm;
diff --git a/source/blender/blenvm/llvm/llvm_modules.h 
b/source/blender/blenvm/llvm/llvm_modules.h
index 14d5af4..8ab9344 100644
--- a/source/blender/blenvm/llvm/llvm_modules.h
+++ b/source/blender/blenvm/llvm/llvm_modules.h
@@ -47,6 +47,11 @@ namespace blenvm {
 
 struct NodeType;
 
+void register_extern_node_functions();
+
+bool llvm_has_external_impl_value(OpCode op);
+bool llvm_has_external_impl_deriv(OpCode op);
+
 void def_node_VALUE_FLOAT(llvm::LLVMContext &context, llvm::Function *func);
 void def_node_VALUE_INT(llvm::LLVMContext &context, llvm::Function *func);
 void def_node_VALUE_FLOAT3(llvm::LLVMContext &context, llvm::Function *func);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to