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

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

Reply via email to