[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