[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