diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenvm/llvm/llvm_compiler.cc | 91 | ||||
-rw-r--r-- | source/blender/blenvm/llvm/llvm_compiler.h | 46 |
2 files changed, 84 insertions, 53 deletions
diff --git a/source/blender/blenvm/llvm/llvm_compiler.cc b/source/blender/blenvm/llvm/llvm_compiler.cc index 98f8362c5b0..dd14637e664 100644 --- a/source/blender/blenvm/llvm/llvm_compiler.cc +++ b/source/blender/blenvm/llvm/llvm_compiler.cc @@ -48,6 +48,57 @@ namespace blenvm { +Scope::Scope(Scope *parent) : + parent(parent) +{ +} + +bool Scope::has_node(const NodeInstance *node) const +{ + /* XXX this is not ideal, but we can expect all outputs + * to be mapped once a node is added. + */ + ConstOutputKey key(node, node->type->find_output(0)); + return has_value(key); +} + +bool Scope::has_value(const ConstOutputKey &key) const +{ + const Scope *scope = this; + while (scope) { + SocketValueMap::const_iterator it = scope->values.find(key); + if (it != scope->values.end()) { + return true; + } + + scope = scope->parent; + } + return false; +} + +ValueHandle Scope::find_value(const ConstOutputKey &key) const +{ + const Scope *scope = this; + while (scope) { + SocketValueMap::const_iterator it = scope->values.find(key); + if (it != scope->values.end()) { + return it->second; + } + + scope = scope->parent; + } + return ValueHandle(0); +} + +void Scope::set_value(const ConstOutputKey &key, ValueHandle value) +{ + bool ok = values.insert(SocketValueMap::value_type(key, value)).second; + BLI_assert(ok && "Could not insert socket value!"); + UNUSED_VARS(ok); +} + +/* ------------------------------------------------------------------------- */ + LLVMCompilerBase::LLVMCompilerBase() : m_module(NULL), m_globals_ptr(NULL) @@ -127,13 +178,14 @@ llvm::BasicBlock *LLVMCompilerBase::codegen_function_body_expression(const NodeG } } + Scope scope_main(NULL); + for (int i = 0; i < num_outputs; ++i) { const NodeGraph::Output &output = graph.outputs[i]; const TypeSpec *typespec = output.typedesc.get_typespec(); - ExpressionMap node_outputs; - expand_node(block, output.key.node, node_outputs); - ValueHandle value = node_outputs.at(output.key); + expand_node(block, output.key.node, scope_main); + ValueHandle value = scope_main.find_value(output.key); store_return_value(block, typespec, value, output_args[i]); } @@ -171,23 +223,26 @@ llvm::Function *LLVMCompilerBase::codegen_node_function(const string &name, cons return func; } -void LLVMCompilerBase::expand_node(llvm::BasicBlock *block, const NodeInstance *node, ExpressionMap &outputs) +void LLVMCompilerBase::expand_node(llvm::BasicBlock *block, const NodeInstance *node, Scope &scope) { + if (scope.has_node(node)) + return; + switch (node->type->kind()) { case NODE_TYPE_FUNCTION: case NODE_TYPE_KERNEL: - expand_expression_node(block, node, outputs); + expand_expression_node(block, node, scope); break; case NODE_TYPE_PASS: - expand_pass_node(block, node, outputs); + expand_pass_node(block, node, scope); break; case NODE_TYPE_ARG: - expand_argument_node(block, node, outputs); + expand_argument_node(block, node, scope); break; } } -void LLVMCompilerBase::expand_pass_node(llvm::BasicBlock *block, const NodeInstance *node, ExpressionMap &outputs) +void LLVMCompilerBase::expand_pass_node(llvm::BasicBlock *block, const NodeInstance *node, Scope &scope) { using namespace llvm; @@ -195,28 +250,24 @@ void LLVMCompilerBase::expand_pass_node(llvm::BasicBlock *block, const NodeInsta BLI_assert(node->num_outputs() == 1); ConstInputKey input = node->input(0); - ConstOutputKey output = node->output(0); BLI_assert(input.value_type() == INPUT_EXPRESSION); - ExpressionMap pass_outputs; - expand_node(block, input.link().node, pass_outputs); - - outputs[output] = pass_outputs.at(input.link()); + expand_node(block, input.link().node, scope); } -void LLVMCompilerBase::expand_argument_node(llvm::BasicBlock *block, const NodeInstance *node, ExpressionMap &outputs) +void LLVMCompilerBase::expand_argument_node(llvm::BasicBlock *block, const NodeInstance *node, Scope &scope) { using namespace llvm; BLI_assert(node->num_outputs() == 1); ConstOutputKey output = node->output(0); - outputs[output] = m_argument_values.at(output); + scope.set_value(output, m_argument_values.at(output)); UNUSED_VARS(block); } -void LLVMCompilerBase::expand_expression_node(llvm::BasicBlock *block, const NodeInstance *node, ExpressionMap &outputs) +void LLVMCompilerBase::expand_expression_node(llvm::BasicBlock *block, const NodeInstance *node, Scope &scope) { using namespace llvm; @@ -241,7 +292,7 @@ void LLVMCompilerBase::expand_expression_node(llvm::BasicBlock *block, const Nod ValueHandle value = alloc_node_value(block, typespec); append_output_arguments(args, typespec, value); - outputs.insert(ExpressionMap::value_type(output, value)); + scope.set_value(output, value); } /* set input arguments */ @@ -255,10 +306,10 @@ void LLVMCompilerBase::expand_expression_node(llvm::BasicBlock *block, const Nod break; } case INPUT_EXPRESSION: { - ExpressionMap link_outputs; - expand_node(block, input.link().node, link_outputs); + expand_node(block, input.link().node, scope); - append_input_value(block, args, typespec, link_outputs.at(input.link())); + ValueHandle link_value = scope.find_value(input.link()); + append_input_value(block, args, typespec, link_value); break; } case INPUT_VARIABLE: { diff --git a/source/blender/blenvm/llvm/llvm_compiler.h b/source/blender/blenvm/llvm/llvm_compiler.h index 0851b84a6ee..44f8eb01ada 100644 --- a/source/blender/blenvm/llvm/llvm_compiler.h +++ b/source/blender/blenvm/llvm/llvm_compiler.h @@ -75,38 +75,18 @@ struct FunctionParameter { typedef std::vector<FunctionParameter> FunctionParameterList; typedef void* ValueHandle; -typedef std::map<ConstOutputKey, ValueHandle> ExpressionMap; - -#if 0 -struct Expression { - explicit Expression(const NodeInstance *node) : - m_node(node) - {} +typedef std::map<ConstOutputKey, ValueHandle> SocketValueMap; +struct Scope { + Scope(Scope *parent); - bool operator < (const Expression &other) const - { - if (m_node == other.m_node) { - return false; - } - else - return m_node < other.m_node; - } - - bool operator == (const Expression &other) const - { - if (m_node == other.m_node) { - return true; - } - else - return false; - } - - const NodeInstance *node() const { return m_node; } + bool has_node(const NodeInstance *node) const; + bool has_value(const ConstOutputKey &key) const; + ValueHandle find_value(const ConstOutputKey &key) const; + void set_value(const ConstOutputKey &key, ValueHandle value); -private: - const NodeInstance *m_node; + Scope *parent; + SocketValueMap values; }; -#endif struct LLVMCompilerBase { typedef std::map<ConstOutputKey, ValueHandle> ArgumentValueMap; @@ -127,10 +107,10 @@ protected: llvm::BasicBlock *codegen_function_body_expression(const NodeGraph &graph, llvm::Function *func); llvm::Function *codegen_node_function(const string &name, const NodeGraph &graph); - void expand_node(llvm::BasicBlock *block, const NodeInstance *node, ExpressionMap &outputs); - void expand_pass_node(llvm::BasicBlock *block, const NodeInstance *node, ExpressionMap &outputs); - void expand_argument_node(llvm::BasicBlock *block, const NodeInstance *node, ExpressionMap &outputs); - void expand_expression_node(llvm::BasicBlock *block, const NodeInstance *node, ExpressionMap &outputs); + void expand_node(llvm::BasicBlock *block, const NodeInstance *node, Scope &scope); + void expand_pass_node(llvm::BasicBlock *block, const NodeInstance *node, Scope &scope); + void expand_argument_node(llvm::BasicBlock *block, const NodeInstance *node, Scope &scope); + void expand_expression_node(llvm::BasicBlock *block, const NodeInstance *node, Scope &scope); virtual void node_graph_begin() = 0; virtual void node_graph_end() = 0; |