[Bf-blender-cvs] [bf007ba] object_nodes: Define a separate node function module for every compiler type.

Lukas Tönne noreply at git.blender.org
Thu May 19 19:29:31 CEST 2016


Commit: bf007badbf7a10f3106002b75fd9a6be552bd479
Author: Lukas Tönne
Date:   Thu May 19 18:01:17 2016 +0200
Branches: object_nodes
https://developer.blender.org/rBbf007badbf7a10f3106002b75fd9a6be552bd479

Define a separate node function module for every compiler type.

This means we can have differing implementations for every potential use
of nodes, such as plain value functions vs. dual values with derivatives.

Node functions for each compiler type are stored in a static map and are
lazy-initialized on the first node graph compilation.

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

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

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

diff --git a/source/blender/blenvm/llvm/llvm_codegen.cc b/source/blender/blenvm/llvm/llvm_codegen.cc
index 508020c..cecd141 100644
--- a/source/blender/blenvm/llvm/llvm_codegen.cc
+++ b/source/blender/blenvm/llvm/llvm_codegen.cc
@@ -42,6 +42,10 @@
 #include "llvm_modules.h"
 #include "llvm_types.h"
 
+#include "util_opcode.h"
+
+#include "modules.h"
+
 namespace blenvm {
 
 LLVMCompilerBase::LLVMCompilerBase() :
@@ -215,6 +219,8 @@ llvm::BasicBlock *LLVMCompilerBase::codegen_function_body_expression(const NodeG
 	
 	builder.CreateRetVoid();
 	
+	m_output_values.clear();
+	
 	return block;
 }
 
@@ -227,7 +233,7 @@ llvm::Function *LLVMCompilerBase::codegen_node_function(const string &name, cons
 		const NodeGraph::Input &input = graph.inputs[i];
 		const string &tname = input.typedesc.name();
 		const TypeSpec *typespec = input.typedesc.get_typespec();
-		Type *type = llvm_create_value_type(context(), tname, typespec);
+		Type *type = create_value_type(tname, typespec);
 		if (llvm_use_argument_pointer(typespec))
 			type = type->getPointerTo();
 		input_types.push_back(type);
@@ -236,10 +242,10 @@ llvm::Function *LLVMCompilerBase::codegen_node_function(const string &name, cons
 		const NodeGraph::Output &output = graph.outputs[i];
 		const string &tname = output.typedesc.name();
 		const TypeSpec *typespec = output.typedesc.get_typespec();
-		Type *type = llvm_create_value_type(context(), tname, typespec);
+		Type *type = create_value_type(tname, typespec);
 		output_types.push_back(type);
 	}
-	FunctionType *functype = llvm_create_node_function_type(context(), input_types, output_types);
+	FunctionType *functype = create_node_function_type(input_types, output_types);
 	
 	Function *func = Function::Create(functype, Function::ExternalLinkage, name, module());
 	
@@ -299,36 +305,7 @@ void LLVMCompilerBase::optimize_function(llvm::Function *func, int opt_level)
 	FPM.run(*func);
 }
 
-/* ------------------------------------------------------------------------- */
-
-void LLVMSimpleCompilerImpl::codegen_begin()
-{
-}
-
-void LLVMSimpleCompilerImpl::codegen_end()
-{
-	m_output_values.clear();
-}
-
-void LLVMSimpleCompilerImpl::map_argument(llvm::BasicBlock *block, const OutputKey &output, llvm::Argument *arg)
-{
-	m_output_values[output] = arg;
-	UNUSED_VARS(block);
-}
-
-void LLVMSimpleCompilerImpl::store_return_value(llvm::BasicBlock *block, const OutputKey &output, llvm::Value *arg)
-{
-	using namespace llvm;
-	
-	IRBuilder<> builder(context());
-	builder.SetInsertPoint(block);
-	
-	Value *value = m_output_values.at(output);
-	Value *rvalue = builder.CreateLoad(value);
-	builder.CreateStore(rvalue, arg);
-}
-
-void LLVMSimpleCompilerImpl::expand_pass_node(llvm::BasicBlock *block, const NodeInstance *node)
+void LLVMCompilerBase::expand_pass_node(llvm::BasicBlock *block, const NodeInstance *node)
 {
 	using namespace llvm;
 	
@@ -348,7 +325,7 @@ void LLVMSimpleCompilerImpl::expand_pass_node(llvm::BasicBlock *block, const Nod
 	UNUSED_VARS(ok);
 }
 
-void LLVMSimpleCompilerImpl::expand_argument_node(llvm::BasicBlock *block, const NodeInstance *node)
+void LLVMCompilerBase::expand_argument_node(llvm::BasicBlock *block, const NodeInstance *node)
 {
 	using namespace llvm;
 	/* input arguments are mapped in advance */
@@ -357,7 +334,7 @@ void LLVMSimpleCompilerImpl::expand_argument_node(llvm::BasicBlock *block, const
 	UNUSED_VARS(block, node);
 }
 
-void LLVMSimpleCompilerImpl::expand_function_node(llvm::BasicBlock *block, const NodeInstance *node)
+void LLVMCompilerBase::expand_function_node(llvm::BasicBlock *block, const NodeInstance *node)
 {
 	using namespace llvm;
 	
@@ -376,7 +353,7 @@ void LLVMSimpleCompilerImpl::expand_function_node(llvm::BasicBlock *block, const
 		ConstOutputKey output = node->output(i);
 		const string &tname = output.socket->typedesc.name();
 		const TypeSpec *typespec = output.socket->typedesc.get_typespec();
-		Type *type = llvm_create_value_type(context(), tname, typespec);
+		Type *type = create_value_type(tname, typespec);
 		BLI_assert(type != NULL);
 		Value *value = builder.CreateAlloca(type);
 		
@@ -436,24 +413,13 @@ void LLVMSimpleCompilerImpl::expand_function_node(llvm::BasicBlock *block, const
 	UNUSED_VARS(call);
 }
 
-/* ------------------------------------------------------------------------- */
-
-void LLVMTextureCompilerImpl::codegen_begin()
-{
-}
-
-void LLVMTextureCompilerImpl::codegen_end()
-{
-	m_output_values.clear();
-}
-
-void LLVMTextureCompilerImpl::map_argument(llvm::BasicBlock *block, const OutputKey &output, llvm::Argument *arg)
+void LLVMCompilerBase::map_argument(llvm::BasicBlock *block, const OutputKey &output, llvm::Argument *arg)
 {
 	m_output_values[output] = arg;
 	UNUSED_VARS(block);
 }
 
-void LLVMTextureCompilerImpl::store_return_value(llvm::BasicBlock *block, const OutputKey &output, llvm::Value *arg)
+void LLVMCompilerBase::store_return_value(llvm::BasicBlock *block, const OutputKey &output, llvm::Value *arg)
 {
 	using namespace llvm;
 	
@@ -465,112 +431,265 @@ void LLVMTextureCompilerImpl::store_return_value(llvm::BasicBlock *block, const
 	builder.CreateStore(rvalue, arg);
 }
 
-void LLVMTextureCompilerImpl::expand_pass_node(llvm::BasicBlock *block, const NodeInstance *node)
+llvm::StructType *LLVMCompilerBase::create_struct_type(const string &name, const StructSpec *spec)
 {
 	using namespace llvm;
 	
-	IRBuilder<> builder(context());
-	builder.SetInsertPoint(block);
-	
-	BLI_assert(node->num_inputs() == 1);
-	BLI_assert(node->num_outputs() == 1);
+	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);
+	}
 	
-	ConstInputKey input = node->input(0);
-	ConstOutputKey output = node->output(0);
-	BLI_assert(input.value_type() == INPUT_EXPRESSION);
+	return StructType::create(context(), ArrayRef<Type*>(elemtypes), name);
+}
+
+void LLVMCompilerBase::create_type_map(TypeMap &typemap)
+{
+	using namespace llvm;
 	
-	Value *value = m_output_values.at(input.link());
-	bool ok = m_output_values.insert(OutputValueMap::value_type(output, value)).second;
-	BLI_assert(ok && "Value for node output already defined!");
-	UNUSED_VARS(ok);
+	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);
+	}
 }
 
-void LLVMTextureCompilerImpl::expand_argument_node(llvm::BasicBlock *block, const NodeInstance *node)
+llvm::FunctionType *LLVMCompilerBase::create_node_function_type(const std::vector<llvm::Type*> &inputs,
+                                                                const std::vector<llvm::Type*> &outputs)
 {
 	using namespace llvm;
-	/* input arguments are mapped in advance */
-	BLI_assert(m_output_values.find(node->output(0)) != m_output_values.end() &&
-	           "Input argument value node mapped!");
-	UNUSED_VARS(block, node);
+	
+	std::vector<llvm::Type*> arg_types;
+	for (int i = 0; i < outputs.size(); ++i) {
+		Type *value_type = outputs[i];
+		/* use a pointer to store output values */
+		arg_types.push_back(value_type->getPointerTo());
+	}
+	arg_types.insert(arg_types.end(), inputs.begin(), inputs.end());
+	
+	return FunctionType::get(TypeBuilder<void, true>::get(context()), arg_types, false);
+}
+static void define_function_OP_VALUE_SINGLE(llvm::LLVMContext &context, llvm::BasicBlock *block,
+                                            llvm::Value *result, llvm::Value *value)
+{
+	using namespace llvm;
+	
+	IRBuilder<> builder(context);
+	builder.SetInsertPoint(block);
+	
+	builder.CreateStore(value, result);
+	
+	builder.CreateRetVoid();
 }
 
-void LLVMTextureCompilerImpl::expand_function_node(llvm::BasicBlock *block, const NodeInstance *node)
+static void define_function_OP_VALUE_AGGREGATE(llvm::LLVMContext &context, llvm::BasicBlock *block,
+                                               llvm::Value *result, llvm::Value *value, size_t size)
 {
 	using namespace llvm;
 	
-	IRBuilder<> builder(context());
+	IRBuilder<> builder(context);
 	builder.SetInsertPoint(block);
 	
-	/* get evaluation function */
-	const std::string &evalname = node->type->name();
-	Function *evalfunc = llvm_find_external_function(module(), evalname);
-	BLI_assert(evalfunc != NULL && "Could not find node function!");
+	Value *size_v = ConstantInt::get(context, APInt(32, size));
+	builder.CreateMemCpy(result, value, size_v, 0);
 	
-	/* function call arguments (including possible return struct if MRV is used) */
-	std::vector<Value *> args;
+	builder.CreateRetVoid();
+}
+
+static bool define_internal_function(llvm::LLVMContext &context, OpCode op, llvm::Function *func)
+{
+	using namespace llvm;
 	
-	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 = llvm_create_value_type(context(), tname, typespec);
-		BLI_assert(type != NULL);
-		Value *value = builder.CreateAlloca(type);
-		
-		args.push_back(value);
+	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::Cre

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list