[Bf-blender-cvs] [ee97978] object_nodes: Generate wrapper functions in LLVM for converting dual types to primitives.

Lukas Tönne noreply at git.blender.org
Mon May 23 15:10:27 CEST 2016


Commit: ee9797808cd4043cd22b9475ee07d5298e9460d7
Author: Lukas Tönne
Date:   Mon May 23 15:07:44 2016 +0200
Branches: object_nodes
https://developer.blender.org/rBee9797808cd4043cd22b9475ee07d5298e9460d7

Generate wrapper functions in LLVM for converting dual types to primitives.

Currently Dual2 arguments are structs with the main value and 2 derivatives
in x and y. Node functions will generally be implemented using the base types,
so the value and derivatives have to be extracted and later combined using
the chain rule.

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

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_base.h
M	source/blender/blenvm/modules/mod_color.h
M	source/blender/blenvm/modules/mod_defines.h
M	source/blender/blenvm/modules/mod_math.h
M	source/blender/blenvm/modules/mod_texture.h

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

diff --git a/source/blender/blenvm/llvm/llvm_codegen.cc b/source/blender/blenvm/llvm/llvm_codegen.cc
index ec211bd..65ec565 100644
--- a/source/blender/blenvm/llvm/llvm_codegen.cc
+++ b/source/blender/blenvm/llvm/llvm_codegen.cc
@@ -70,8 +70,7 @@ void LLVMCompilerBase::create_module(const string &name)
 	
 	/* make sure the node base functions are defined */
 	if (get_nodes_module() == NULL) {
-		Module *nodes_mod = define_nodes_module();
-		set_nodes_module(nodes_mod);
+		define_nodes_module();
 	}
 	
 	/* create an empty module */
@@ -171,21 +170,19 @@ llvm::Function *LLVMCompilerBase::codegen_node_function(const string &name, cons
 	std::vector<llvm::Type*> input_types, output_types;
 	for (int i = 0; i < graph.inputs.size(); ++i) {
 		const NodeGraph::Input &input = graph.inputs[i];
-		const string &tname = input.typedesc.name();
 		const TypeSpec *typespec = input.typedesc.get_typespec();
-		Type *type = create_value_type(tname, typespec);
-		if (use_argument_pointer(typespec))
+		Type *type = get_value_type(typespec, false);
+		if (use_argument_pointer(typespec, false))
 			type = type->getPointerTo();
 		input_types.push_back(type);
 	}
 	for (int i = 0; i < graph.outputs.size(); ++i) {
 		const NodeGraph::Output &output = graph.outputs[i];
-		const string &tname = output.typedesc.name();
 		const TypeSpec *typespec = output.typedesc.get_typespec();
-		Type *type = create_value_type(tname, typespec);
+		Type *type = get_value_type(typespec, false);
 		output_types.push_back(type);
 	}
-	FunctionType *functype = create_node_function_type(input_types, output_types);
+	FunctionType *functype = get_node_function_type(input_types, output_types);
 	
 	Function *func = Function::Create(functype, Function::ExternalLinkage, name, module());
 	
@@ -304,14 +301,13 @@ void LLVMCompilerBase::expand_function_node(llvm::BasicBlock *block, const NodeI
 	Function *evalfunc = llvm_find_external_function(module(), evalname);
 	BLI_assert(evalfunc != NULL && "Could not find node function!");
 	
-	/* function call arguments (including possible return struct if MRV is used) */
+	/* function call arguments */
 	std::vector<Value *> args;
 	
 	for (int i = 0; i < node->num_outputs(); ++i) {
 		ConstOutputKey output = node->output(i);
-		const string &tname = output.socket->typedesc.name();
 		const TypeSpec *typespec = output.socket->typedesc.get_typespec();
-		Type *type = create_value_type(tname, typespec);
+		Type *type = get_value_type(typespec, false);
 		BLI_assert(type != NULL);
 		Value *value = builder.CreateAlloca(type);
 		
@@ -327,6 +323,7 @@ void LLVMCompilerBase::expand_function_node(llvm::BasicBlock *block, const NodeI
 	for (int i = 0; i < node->num_inputs(); ++i) {
 		ConstInputKey input = node->input(i);
 		const TypeSpec *typespec = input.socket->typedesc.get_typespec();
+		bool is_constant = (input.value_type() == INPUT_CONSTANT);
 		
 		switch (input.value_type()) {
 			case INPUT_CONSTANT: {
@@ -334,7 +331,7 @@ void LLVMCompilerBase::expand_function_node(llvm::BasicBlock *block, const NodeI
 				Constant *cvalue = create_node_value_constant(input.value());
 				
 				Value *value;
-				if (use_argument_pointer(typespec)) {
+				if (use_argument_pointer(typespec, is_constant)) {
 					AllocaInst *pvalue = builder.CreateAlloca(cvalue->getType());
 					builder.CreateStore(cvalue, pvalue);
 					value = pvalue;
@@ -349,7 +346,7 @@ void LLVMCompilerBase::expand_function_node(llvm::BasicBlock *block, const NodeI
 			case INPUT_EXPRESSION: {
 				Value *pvalue = m_output_values.at(input.link());
 				Value *value;
-				if (use_argument_pointer(typespec)) {
+				if (use_argument_pointer(typespec, is_constant)) {
 					value = pvalue;
 				}
 				else {
@@ -371,36 +368,8 @@ void LLVMCompilerBase::expand_function_node(llvm::BasicBlock *block, const NodeI
 	UNUSED_VARS(call);
 }
 
-llvm::StructType *LLVMCompilerBase::create_struct_type(const string &name, const StructSpec *spec)
-{
-	using namespace llvm;
-	
-	std::vector<Type*> elemtypes;
-	for (int i = 0; i < spec->num_fields(); ++i) {
-		Type *ftype = create_value_type(spec->field(i).name, spec->field(i).typespec);
-		elemtypes.push_back(ftype);
-	}
-	
-	return StructType::create(context(), ArrayRef<Type*>(elemtypes), name);
-}
-
-void LLVMCompilerBase::create_type_map(TypeMap &typemap)
-{
-	using namespace llvm;
-	
-	for (TypeSpec::typedef_iterator it = TypeSpec::typedef_begin(); it != TypeSpec::typedef_end(); ++it) {
-		const string &name = it->first;
-		const TypeSpec *typespec = it->second;
-		
-		Type *type = create_value_type(name, typespec);
-		bool ok = typemap.insert(TypeMap::value_type(name, type)).second;
-		BLI_assert(ok && "Could not insert LLVM type for TypeSpec!");
-		UNUSED_VARS(ok);
-	}
-}
-
-llvm::FunctionType *LLVMCompilerBase::create_node_function_type(const std::vector<llvm::Type*> &inputs,
-                                                                const std::vector<llvm::Type*> &outputs)
+llvm::FunctionType *LLVMCompilerBase::get_node_function_type(const std::vector<llvm::Type*> &inputs,
+                                                             const std::vector<llvm::Type*> &outputs)
 {
 	using namespace llvm;
 	
@@ -441,64 +410,27 @@ static void define_function_OP_VALUE_AGGREGATE(llvm::LLVMContext &context, llvm:
 	builder.CreateRetVoid();
 }
 
-static bool define_internal_function(llvm::LLVMContext &context, OpCode op, llvm::Function *func)
-{
-	using namespace llvm;
-	
-	std::vector<Value*> args;
-	args.reserve(func->arg_size());
-	for (Function::arg_iterator a = func->arg_begin(); a != func->arg_end(); ++a)
-		args.push_back(a);
-	
-	switch (op) {
-		case OP_VALUE_FLOAT:
-		case OP_VALUE_INT: {
-			BasicBlock *block = BasicBlock::Create(context, "entry", func);
-			define_function_OP_VALUE_SINGLE(context, block, args[0], args[1]);
-			return true;
-		}
-		case OP_VALUE_FLOAT3: {
-			BasicBlock *block = BasicBlock::Create(context, "entry", func);
-			define_function_OP_VALUE_AGGREGATE(context, block, args[0], args[1], sizeof(float3));
-			return true;
-		}
-		case OP_VALUE_FLOAT4: {
-			BasicBlock *block = BasicBlock::Create(context, "entry", func);
-			define_function_OP_VALUE_AGGREGATE(context, block, args[0], args[1], sizeof(float4));
-			return true;
-		}
-		case OP_VALUE_MATRIX44: {
-			BasicBlock *block = BasicBlock::Create(context, "entry", func);
-			define_function_OP_VALUE_AGGREGATE(context, block, args[0], args[1], sizeof(matrix44));
-			return true;
-		}
-		
-		default:
-			return false;
-	}
-}
-
-void LLVMCompilerBase::define_node_function(llvm::Module *mod, OpCode op, const NodeType *nodetype, void *funcptr)
+llvm::Function *LLVMCompilerBase::declare_node_function(llvm::Module *mod, const NodeType *nodetype)
 {
 	using namespace llvm;
 	
 	std::vector<Type *> input_types, output_types;
 	for (int i = 0; i < nodetype->num_inputs(); ++i) {
 		const NodeInput *input = nodetype->find_input(i);
-		const string &tname = input->typedesc.name();
 		const TypeSpec *typespec = input->typedesc.get_typespec();
-		Type *type = create_value_type(tname, typespec);
+		bool is_constant = (input->value_type == INPUT_CONSTANT);
+		
+		Type *type = get_value_type(typespec, is_constant);
 		if (type == NULL)
 			break;
-		if (use_argument_pointer(typespec))
+		if (use_argument_pointer(typespec, is_constant))
 			type = type->getPointerTo();
 		input_types.push_back(type);
 	}
 	for (int i = 0; i < nodetype->num_outputs(); ++i) {
 		const NodeOutput *output = nodetype->find_output(i);
-		const string &tname = output->typedesc.name();
 		const TypeSpec *typespec = output->typedesc.get_typespec();
-		Type *type = create_value_type(tname, typespec);
+		Type *type = get_value_type(typespec, false);
 		if (type == NULL)
 			break;
 		output_types.push_back(type);
@@ -506,82 +438,29 @@ void LLVMCompilerBase::define_node_function(llvm::Module *mod, OpCode op, const
 	if (input_types.size() != nodetype->num_inputs() ||
 	    output_types.size() != nodetype->num_outputs()) {
 		/* some arguments could not be handled */
-		return;
+		return NULL;
 	}
 	
-	FunctionType *functype = create_node_function_type(input_types, output_types);
+	FunctionType *functype = get_node_function_type(input_types, output_types);
 	
 	Function *func = Function::Create(functype, Function::ExternalLinkage, nodetype->name(), mod);
 	
 //	printf("Declared function for node type '%s':\n", nodetype->name().c_str());
 //	func->dump();
 	
-	bool has_internal_impl = define_internal_function(context(), op, func);
-	if (!has_internal_impl) {
-		/* register implementation of the function */
-		llvm_execution_engine()->addGlobalMapping(func, funcptr);
-	}
-}
-
-llvm::Module *LLVMCompilerBase::define_nodes_module()
-{
-	using namespace llvm;
-	
-	Module *mod = new llvm::Module("nodes", context());
-	
-#define DEF_OPCODE(op) \
-	{ \
-		const NodeType *nodetype = NodeGraph::find_node_type(STRINGIFY(op)); \
-		if (nodetype != NULL) { \
-			define_node_function(mod, OP_##op, nodetype, (void*)(intptr_t)modules::op); \
-		} \
-	}
-	
-	BVM_DEFINE_OPCODES
-	
-#undef DEF_OPCODE
-	
-	llvm_execution_engine()->addModule(mod);
-	
-	return mod;
+	return func;
 }
 
 /* ------------------------------------------------------------------------- */
 
 llvm::Module *LLVMSimpleCompilerImpl::m_nodes_module = NULL;
 
-llvm::Type *LLVMSimpleCompilerImpl::create_value_type(const string &name, const TypeSpec *spec)
+llvm::Type *LLVMSimpleCompilerImpl::get_value_type(const TypeSpec *spec, bool UNUSED(is_constant))
 {
-	using namespace llvm;
-	
-	if (spec->is_structure()) {
-		return create_struct_type(name, spec->structure());
-	}
-	else {
-		switch (spec->base_type()) {
-			case BVM_FLOAT:
-				return TypeBuilder<types::ieee_float, true>::get(context());
-			case BVM_FLOAT3:
-				return TypeBuilder<float3, true>::get(context());
-			case BVM_FLOAT4:
-				return TypeBuilder<float4, true>::get(context());
-			case BVM_INT:
-				return TypeBuilder<types::i<32>, true>::get(context());
-			case BVM_MATRIX44:
-				return TypeBuilder<matrix44, true>::get(context());
-				
-			case BVM_STRING:
-			case BVM_RNAPOINTER:
-			case BVM_MESH:
-			case BVM_DUPLIS:
-				/* TODO */
-				return NULL;
-		}
-	}
-	return NULL;
+	return bvm_get_llvm_type(conte

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list