[Bf-blender-cvs] [ee97978] object_nodes: Generate wrapper functions in LLVM for converting dual types to primitives.
Lukas Tönne
noreply at git.blender.org
Mon May 23 15:10:27 CEST 2016
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. @@
More information about the Bf-blender-cvs
mailing list