[Bf-blender-cvs] [af27ce2] object_nodes: Use a hash table to register external functions with the LLVM engine.

Lukas Tönne noreply at git.blender.org
Fri Jun 24 10:24:30 CEST 2016


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);




More information about the Bf-blender-cvs mailing list