Commit: ff6673d8b80d969cbdd98402a347fe7e2175fb97
Author: Lukas Tönne
Date:   Tue Apr 5 10:16:57 2016 +0200
Branches: object_nodes
https://developer.blender.org/rBff6673d8b80d969cbdd98402a347fe7e2175fb97

Type generation for LLVM based on node socket types.

Currently every socket stores a complete and unique type definition.
This should be changed to module-level type declarations and referencing by 
name.

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

M       source/blender/blenvm/llvm/llvm_codegen.cc
M       source/blender/blenvm/llvm/llvm_codegen.h

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

diff --git a/source/blender/blenvm/llvm/llvm_codegen.cc 
b/source/blender/blenvm/llvm/llvm_codegen.cc
index 560c19b..dde5e11 100644
--- a/source/blender/blenvm/llvm/llvm_codegen.cc
+++ b/source/blender/blenvm/llvm/llvm_codegen.cc
@@ -30,6 +30,7 @@
  */
 
 #include <set>
+#include <sstream>
 
 #include "nodegraph.h"
 
@@ -38,8 +39,86 @@
 #include "llvm_function.h"
 #include "llvm_headers.h"
 
+/* TypeBuilder specializations for own structs */
+
+namespace llvm {
+
+template <bool xcompile>
+class TypeBuilder<blenvm::float3, xcompile> {
+public:
+       static StructType *get(LLVMContext &context) {
+               return StructType::get(
+                           TypeBuilder<types::ieee_float, 
xcompile>::get(context),
+                           TypeBuilder<types::ieee_float, 
xcompile>::get(context),
+                           TypeBuilder<types::ieee_float, 
xcompile>::get(context),
+                           NULL);
+       }
+       
+       enum Fields {
+               FIELD_X = 0,
+               FIELD_Y = 1,
+               FIELD_Z = 2,
+       };
+};
+
+template <bool xcompile>
+class TypeBuilder<blenvm::float4, xcompile> {
+public:
+       static StructType *get(LLVMContext &context) {
+               return StructType::get(
+                           TypeBuilder<types::ieee_float, 
xcompile>::get(context),
+                           TypeBuilder<types::ieee_float, 
xcompile>::get(context),
+                           TypeBuilder<types::ieee_float, 
xcompile>::get(context),
+                           TypeBuilder<types::ieee_float, 
xcompile>::get(context),
+                           NULL);
+       }
+       
+       enum Fields {
+               FIELD_X = 0,
+               FIELD_Y = 1,
+               FIELD_Z = 2,
+               FIELD_W = 3,
+       };
+};
+
+template <bool xcompile>
+class TypeBuilder<blenvm::matrix44, xcompile> {
+public:
+       static StructType *get(LLVMContext &context) {
+               return StructType::get(
+                           ArrayType::get(
+                               ArrayType::get(
+                                   TypeBuilder<types::ieee_float, 
xcompile>::get(context),
+                                   4),
+                               4),
+                           NULL);
+       }
+};
+
+} /* namespace llvm */
+
+
 namespace blenvm {
 
+/* XXX Should eventually declare and reference types by name,
+ * rather than storing full TypeDesc in each socket!
+ * These functions just provides per-socket type names in the meantime.
+ */
+static string dummy_type_name(const InputKey &input)
+{
+       size_t hash = std::hash<const NodeInstance *>()(input.node) ^ 
std::hash<const NodeInput *>()(input.socket);
+       std::stringstream ss;
+       ss << "InputType" << (unsigned short)hash;
+       return ss.str();
+}
+static string dummy_type_name(const OutputKey &output)
+{
+       size_t hash = std::hash<const NodeInstance *>()(output.node) ^ 
std::hash<const NodeOutput *>()(output.socket);
+       std::stringstream ss;
+       ss << "OutputType" << (unsigned short)hash;
+       return ss.str();
+}
+
 LLVMCompiler::LLVMCompiler()
 {
 }
@@ -48,11 +127,47 @@ LLVMCompiler::~LLVMCompiler()
 {
 }
 
-llvm::Type *LLVMCompiler::codegen_typedesc(TypeDesc *td)
+llvm::LLVMContext &LLVMCompiler::context() const
+{
+       return llvm::getGlobalContext();
+}
+
+llvm::Type *LLVMCompiler::codegen_typedesc(const string &name, const TypeDesc 
*td)
 {
        using namespace llvm;
        
-       // TODO
+       if (td->is_structure()) {
+               const StructSpec *s = td->structure();
+               std::vector<Type*> elemtypes;
+               for (int i = 0; i < s->num_fields(); ++s) {
+                       Type *ftype = codegen_typedesc(s->field(i).name, 
&s->field(i).typedesc);
+                       elemtypes.push_back(ftype);
+               }
+               
+               StructType *stype = StructType::create(context(), 
ArrayRef<Type*>(elemtypes), name);
+               return stype;
+       }
+       else {
+               switch (td->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;
 }
 
@@ -60,47 +175,36 @@ llvm::FunctionType 
*LLVMCompiler::codegen_node_function_type(const NodeGraph &gr
 {
        using namespace llvm;
        
-       LLVMContext &context = getGlobalContext();
-       
        std::vector<Type *> input_types, output_types;
        
-#if 0
        for (int i = 0; i < graph.outputs.size(); ++i) {
-#if 0 // TODO
                const NodeGraph::Output &output = graph.outputs[i];
-               Type *type = bjit_get_socket_llvm_type(output.type, context, 
module);
+               Type *type = codegen_typedesc(dummy_type_name(output.key), 
&output.typedesc);
                output_types.push_back(type);
-#endif
        }
-       StructType *return_type = StructType::get(context, output_types);
+       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) {
-#if 0 // TODO
                const NodeGraph::Input &input = graph.inputs[i];
-               Type *type = bjit_get_socket_llvm_type(input.type, context, 
module);
-               type = PointerType::get(type, 0);
+               Type *type = codegen_typedesc(dummy_type_name(input.key), 
&input.typedesc);
+//             type = PointerType::get(type, 0);
                input_types.push_back(type);
-#endif
        }
-#endif
        
-       return FunctionType::get(TypeBuilder<void, true>::get(context), 
input_types, false);
+       return FunctionType::get(TypeBuilder<void, true>::get(context()), 
input_types, false);
 }
 
 llvm::Function *LLVMCompiler::codegen_node_function(const string &name, const 
NodeGraph &graph, llvm::Module *module)
 {
        using namespace llvm;
        
-       LLVMContext &context = getGlobalContext();
-       IRBuilder<> builder(context);
+       IRBuilder<> builder(context());
        
        FunctionType *functype = codegen_node_function_type(graph);
-//     Function *func = Function::Create(functype, Function::ExternalLinkage, 
name, module);
        Function *func = llvm::cast<Function>(module->getOrInsertFunction(name, 
functype));
-#if 0
        Argument *retarg = func->getArgumentList().begin();
-       retarg->addAttr(AttributeSet::get(context, AttributeSet::ReturnIndex, 
Attribute::StructRet));
+       retarg->addAttr(AttributeSet::get(context(), AttributeSet::ReturnIndex, 
Attribute::StructRet));
        
        int num_inputs = graph.inputs.size();
        int num_outputs = graph.outputs.size();
@@ -111,16 +215,15 @@ llvm::Function *LLVMCompiler::codegen_node_function(const 
string &name, const No
        }
        
        Function::ArgumentListType::iterator it = 
func->getArgumentList().begin();
-//     ++it; /* skip return arg */
+       ++it; /* skip return arg */
        for (int i = 0; i < num_inputs; ++i) {
 //             Argument *arg = &(*it++);
 //             const NodeGraph::Input &input = graph.inputs[i];
                
 //             graph.set_input_argument(input.name, arg);
        }
-#endif
        
-       BasicBlock *entry = BasicBlock::Create(context, "entry", func);
+       BasicBlock *entry = BasicBlock::Create(context(), "entry", func);
        builder.SetInsertPoint(entry);
        
 #if 0 // TODO
@@ -134,9 +237,8 @@ llvm::Function *LLVMCompiler::codegen_node_function(const 
string &name, const No
        }
 #endif
        
-#if 0
        for (int i = 0; i < num_outputs; ++i) {
-               Value *retptr = builder.CreateStructGEP(retarg, i);
+//             Value *retptr = builder.CreateStructGEP(retarg, i);
                
 #if 0 // TODO
                const NodeGraph::Output &output = graph.outputs[i];
@@ -153,7 +255,6 @@ llvm::Function *LLVMCompiler::codegen_node_function(const 
string &name, const No
                builder.CreateStore(retval, retptr);
 #endif
        }
-#endif
        
        builder.CreateRetVoid();
        
@@ -164,12 +265,16 @@ FunctionLLVM *LLVMCompiler::compile_function(const string 
&name, const NodeGraph
 {
        using namespace llvm;
        
-       Module *module = new Module(name, getGlobalContext());
+       Module *module = new Module(name, context());
        llvm_execution_engine()->addModule(module);
        
        Function *func = codegen_node_function(name, graph, module);
        assert(func != NULL && "codegen_node_function returned NULL!");
        
+       printf("=== NODE FUNCTION ===\n");
+       func->dump();
+       printf("=====================\n");
+       
        FunctionPassManager fpm(module);
        PassManagerBuilder builder;
        builder.OptLevel = 0;
diff --git a/source/blender/blenvm/llvm/llvm_codegen.h 
b/source/blender/blenvm/llvm/llvm_codegen.h
index d764c17..f23ed37 100644
--- a/source/blender/blenvm/llvm/llvm_codegen.h
+++ b/source/blender/blenvm/llvm/llvm_codegen.h
@@ -43,6 +43,7 @@
 #include "util_string.h"
 
 namespace llvm {
+class LLVMContext;
 class Function;
 class FunctionType;
 class Module;
@@ -63,9 +64,11 @@ struct LLVMCompiler {
        FunctionLLVM *compile_function(const string &name, const NodeGraph 
&graph);
        
 protected:
+       llvm::LLVMContext &context() const;
+       
        llvm::FunctionType *codegen_node_function_type(const NodeGraph &graph);
        llvm::Function *codegen_node_function(const string &name, const 
NodeGraph &graph, llvm::Module *module);
-       llvm::Type *codegen_typedesc(TypeDesc *td);
+       llvm::Type *codegen_typedesc(const string &name, const TypeDesc *td);
 };
 
 } /* namespace blenvm */

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to