[Bf-blender-cvs] [2556262] object_nodes: Implemented external C function linking and change of function signature convention.
Lukas Tönne
noreply at git.blender.org
Tue May 10 11:25:10 CEST 2016
Commit: 2556262f6c9da7f09acddfa37811d7524f4831c2
Author: Lukas Tönne
Date: Tue May 10 11:14:50 2016 +0200
Branches: object_nodes
https://developer.blender.org/rB2556262f6c9da7f09acddfa37811d7524f4831c2
Implemented external C function linking and change of function signature convention.
The general signature layout for node functions is
void foobar(out1_t *out1, out2_t *out2, ..., in1_t in1, in2_t in2, ...);
All outputs are passed as pointers or references (using references in C code for clarity).
Inputs can be passed by-value or as const pointers/references (for structs and arrays).
In the future we may also support single value return types for convenience.
===================================================================
M source/blender/blenvm/intern/bvm_api.cc
M source/blender/blenvm/llvm/CMakeLists.txt
M source/blender/blenvm/llvm/llvm_codegen.cc
M source/blender/blenvm/llvm/llvm_codegen.h
M source/blender/blenvm/llvm/llvm_engine.cc
M source/blender/blenvm/llvm/llvm_modules.cc
M source/blender/blenvm/llvm/llvm_modules.h
M source/blender/blenvm/llvm/llvm_types.cc
M source/blender/blenvm/llvm/llvm_types.h
M source/blender/blenvm/modules/mod_color.h
A source/blender/blenvm/modules/mod_defines.h
M source/blender/blenvm/modules/mod_math.h
M source/blender/blenvm/modules/mod_value.h
===================================================================
diff --git a/source/blender/blenvm/intern/bvm_api.cc b/source/blender/blenvm/intern/bvm_api.cc
index ac3e288..b969b29 100644
--- a/source/blender/blenvm/intern/bvm_api.cc
+++ b/source/blender/blenvm/intern/bvm_api.cc
@@ -975,11 +975,10 @@ static void parse_tex_nodes(bNodeTree *btree, blenvm::NodeGraph *graph)
namespace blenvm {
-struct TexNodesResult {
- float4 color;
- float3 normal;
-};
-typedef TexNodesResult (*TexNodesFunc)(float3 co, float3 dxt, float3 dyt, int cfra, int osatex);
+typedef void (*TexNodesFunc)(float4 *r_color, float3 *r_normal,
+ const float3 &co,
+ const float3 &dxt, const float3 &dyt,
+ int cfra, int osatex);
static void set_texresult(TexResult *result, const float4 &color, const float3 &normal)
{
@@ -1123,7 +1122,8 @@ void BVM_eval_texture_llvm(struct BVMEvalContext *UNUSED(ctx), struct BVMFunctio
using namespace blenvm;
EvalGlobals globals;
- TexNodesResult result;
+ float4 r_color;
+ float3 r_normal;
UNUSED_VARS(globals);
#ifdef WITH_LLVM
@@ -1139,14 +1139,14 @@ void BVM_eval_texture_llvm(struct BVMEvalContext *UNUSED(ctx), struct BVMFunctio
copy_v3_v3(dyt_v.data(), dyt);
else
zero_v3(dyt_v.data());
- result = fp(coord_v, dxt_v, dyt_v, cfra, osatex);
+ fp(&r_color, &r_normal, coord_v, dxt_v, dyt_v, cfra, osatex);
#else
UNUSED_VARS(fn, coord, dxt, dyt, cfra, osatex);
- result.color = float4(0.0f, 0.0f, 0.0f, 0.0f);
- result.normal = float3(0.0f, 0.0f, 1.0f);
+ r_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
+ r_normal = float3(0.0f, 0.0f, 1.0f);
#endif
- set_texresult(target, result.color, result.normal);
+ set_texresult(target, r_color, r_normal);
}
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/blenvm/llvm/CMakeLists.txt b/source/blender/blenvm/llvm/CMakeLists.txt
index 299296e..b47d5a0 100644
--- a/source/blender/blenvm/llvm/CMakeLists.txt
+++ b/source/blender/blenvm/llvm/CMakeLists.txt
@@ -55,24 +55,32 @@ set(SRC
llvm_types.h
)
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RTTI_DISABLE_FLAGS}")
-
-add_definitions(-DWITH_LLVM -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -std=c++0x)
-
-blender_add_lib(bf_blenvm_llvm "${SRC}" "${INC}" "${INC_SYS}")
-
-
-# Modules
-
set(LLVM_SRC
../modules/modules.cc
)
set(LLVM_HEADERS
../modules/mod_color.h
+ ../modules/mod_defines.h
../modules/mod_math.h
../modules/mod_value.h
)
+#if(NOT WITH_BLENVM_IRMODULES)
+# list(APPEND SRC ${LLVM_SRC} ${LLVM_HEADERS})
+#endif()
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RTTI_DISABLE_FLAGS}")
+
+add_definitions(-DWITH_LLVM -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -std=c++0x)
+add_definitions(
+ -DBVM_MOD_NAMESPACE_BEGIN=namespace\ blenvm\ {\ namespace\ modules\ {
+ -DBVM_MOD_NAMESPACE_END=}}
+)
+
+blender_add_lib(bf_blenvm_llvm "${SRC}" "${INC}" "${INC_SYS}")
+
+
+# Modules
if(WITH_BLENVM_IRMODULES)
# XXX TODO
@@ -94,6 +102,9 @@ if(WITH_BLENVM_IRMODULES)
-o ${CMAKE_CURRENT_BINARY_DIR}/${llvm_ir}
-DBLENVM_RUNTIME
-D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
+ -DBVM_MOD_NAMESPACE_BEGIN
+ -DBVM_MOD_NAMESPACE_END
+ -DBVM_MOD_ANNOTATE_FUNCTIONS
-I${CMAKE_CURRENT_SOURCE_DIR}/../../blenlib
DEPENDS ${LLVM_SRC} ${LLVM_HEADERS})
@@ -112,6 +123,4 @@ if(WITH_BLENVM_IRMODULES)
add_dependencies(bf_blenvm_llvm bf_blenvm_llvm_modules)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${LLVM_HEADERS}" ${LLVM_IR_INSTALL_PATH})
-else()
-
endif()
diff --git a/source/blender/blenvm/llvm/llvm_codegen.cc b/source/blender/blenvm/llvm/llvm_codegen.cc
index ac75926..96e8a7f 100644
--- a/source/blender/blenvm/llvm/llvm_codegen.cc
+++ b/source/blender/blenvm/llvm/llvm_codegen.cc
@@ -53,8 +53,8 @@
* the clang compiler! See
* http://stackoverflow.com/questions/22776391/why-does-clang-coerce-struct-parameters-to-ints
*/
-//#define BVM_NODE_CALL_BYVALUE
-#define BVM_NODE_CALL_BYPOINTER
+#define BVM_NODE_CALL_BYVALUE
+//#define BVM_NODE_CALL_BYPOINTER
namespace blenvm {
@@ -179,33 +179,9 @@ llvm::Constant *LLVMCompilerBase::codegen_constant(const NodeValue *node_value)
return NULL;
}
-llvm::FunctionType *LLVMCompilerBase::codegen_node_function_type(const NodeGraph &graph)
-{
- using namespace llvm;
-
- std::vector<Type *> input_types, output_types;
-
- for (int i = 0; i < graph.outputs.size(); ++i) {
- const NodeGraph::Output &output = graph.outputs[i];
- Type *type = codegen_type(context(), dummy_type_name(output.key), &output.typedesc);
- output_types.push_back(type);
- }
- StructType *return_type = StructType::get(context(), output_types);
-
- input_types.push_back(PointerType::get(return_type, 0));
- for (int i = 0; i < graph.inputs.size(); ++i) {
- const NodeGraph::Input &input = graph.inputs[i];
- Type *type = codegen_type(context(), dummy_type_name(input.key), &input.typedesc);
-// type = PointerType::get(type, 0);
- input_types.push_back(type);
- }
-
- return FunctionType::get(TypeBuilder<void, true>::get(context()), input_types, false);
-}
-
llvm::CallInst *LLVMCompilerBase::codegen_node_call(llvm::BasicBlock *block,
- const NodeInstance *node,
- OutputValueMap &output_values)
+ const NodeInstance *node,
+ OutputValueMap &output_values)
{
using namespace llvm;
@@ -215,10 +191,7 @@ llvm::CallInst *LLVMCompilerBase::codegen_node_call(llvm::BasicBlock *block,
/* get evaluation function */
const std::string &evalname = node->type->name();
Function *evalfunc = llvm_find_external_function(module(), evalname);
- if (!evalfunc) {
- printf("Could not find node function '%s'\n", evalname.c_str());
- return NULL;
- }
+ BLI_assert(evalfunc != NULL && "Could not find node function!");
/* function call arguments (including possible return struct if MRV is used) */
std::vector<Value *> args;
@@ -231,11 +204,24 @@ llvm::CallInst *LLVMCompilerBase::codegen_node_call(llvm::BasicBlock *block,
args.push_back(retval);
}
+ else {
+ for (int i = 0; i < node->num_outputs(); ++i) {
+ ConstOutputKey output = node->output(i);
+ Type *type = llvm_create_value_type(context(), dummy_type_name(output), &output.socket->typedesc);
+ Value *value = builder.CreateAlloca(type);
+
+ args.push_back(value);
+
+ /* use as node output values */
+ bool ok = output_values.insert(OutputValuePair(output, value)).second;
+ BLI_assert(ok && "Value for node output already defined!");
+ }
+ }
#endif
#ifdef BVM_NODE_CALL_BYPOINTER
for (int i = 0; i < node->num_outputs(); ++i) {
ConstOutputKey output = node->output(i);
- Type *output_type = codegen_type(context(), dummy_type_name(output), &output.socket->typedesc);
+ Type *output_type = create_value_type(context(), dummy_type_name(output), &output.socket->typedesc);
AllocaInst *outputmem = builder.CreateAlloca(output_type);
Type *arg_type = evalfunc->getFunctionType()->getParamType(args.size());
@@ -255,20 +241,43 @@ llvm::CallInst *LLVMCompilerBase::codegen_node_call(llvm::BasicBlock *block,
switch (input.value_type()) {
case INPUT_CONSTANT: {
/* create storage for the global value */
- Constant *constval = codegen_constant(input.value());
- AllocaInst *constmem = builder.CreateAlloca(constval->getType());
- builder.CreateStore(constval, constmem);
+ Constant *cvalue = codegen_constant(input.value());
+#ifdef BVM_NODE_CALL_BYVALUE
+ Value *value;
+ if (llvm_use_argument_pointer(&input.socket->typedesc)) {
+ AllocaInst *pvalue = builder.CreateAlloca(cvalue->getType());
+ builder.CreateStore(cvalue, pvalue);
+ value = pvalue;
+ }
+ else {
+ value = cvalue;
+ }
+#endif
+#ifdef BVM_NODE_CALL_BYPOINTER
/* use the pointer as function argument */
Type *arg_type = evalfunc->getFunctionType()->getParamType(args.size());
Value *value = builder.CreatePointerBitCastOrAddrSpaceCast(constmem, arg_type);
+#endif
args.push_back(value);
break;
}
case INPUT_EXPRESSION: {
- Value *valuemem = output_values.at(input.link());
+ Value *pvalue = output_values.at(input.link());
+#ifdef BVM_NODE_CALL_BYVALUE
+ Value *value;
+ if (llvm_use_argument_pointer(&input.socket->typedesc)) {
+ value = pvalue;
+ }
+ else {
+ value = builder.CreateLoad(pvalue);
+ }
+
+#endif
+#ifdef BVM_NODE_CALL_BYPOINTER
Type *arg_type = evalfunc->getFunctionType()->getParamType(args.size());
Value *value = builder.CreatePointerBitCastOrAddrSpaceCast(valuemem, arg_type);
+#endif
args.push_back(value);
break;
}
@@ -302,6 +311,7 @@ llvm::CallInst *LLVMCompilerBase::codegen_node_call(llvm::BasicBlock *block,
BLI_assert(ok && "Value for node output already defined!");
}
}
+#if 0 /* XXX currently we always use result pointers */
else {
BLI_assert(node->num_outputs() == 1);
ConstOutputKey output = node->output(0);
@@ -310,6 +320,7 @@ llvm::CallInst *LLVMCompilerBase::codegen_node_call(llvm::BasicBlock *block,
BLI_assert(ok && "Value for node output already defined!");
}
#endif
+#endif
}
return call;
@@ -335,13 +346,18 @@ llvm::BasicBlock *LLVMCompilerBase::codegen_function_body_expression(const NodeG
OutputValueMap output_values;
Argument *retarg = func->getArgumentList().begin();
- Function::ArgumentListType::iterator it = retarg;
- ++it; /* skip return arg */
- for (int i = 0; i < num_inputs; ++i) {
- const NodeGraph::Input &input = graph.inputs[i];
-
- Argument *arg = &(*it++);
- output_values[input.key] = arg;
+ {
+ Function::ArgumentListType::iterator it = retarg;
+// ++it; /* skip return arg */
+ for (int i = 0; i < num_outputs; ++i) {
+ ++it; /* skip output arguments */
+ }
+ for (int i = 0; i < num_inputs; ++i) {
+ const NodeGraph::Input &input = graph.inputs[i];
+
+ Argument *arg = &(*it++);
+ output_values[input.key] = arg;
+ }
}
OrderedNodeSet nodes;
@@ -356,6 +372,7 @@ llvm::BasicBlock *LLVMCompilerBase::codegen_function_body_exp
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list