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