[Bf-blender-cvs] [ff6673d] object_nodes: Type generation for LLVM based on node socket types.
Lukas Tönne
noreply at git.blender.org
Tue Apr 5 11:06:01 CEST 2016
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 */
More information about the Bf-blender-cvs
mailing list