Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenvm/llvm/llvm_compiler.cc91
-rw-r--r--source/blender/blenvm/llvm/llvm_compiler.h46
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;