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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to