Commit: ff3c066324b6848bd2be9c364e017ff98fae8e62
Author: Lukas Tönne
Date:   Sat Jun 18 11:40:46 2016 +0200
Branches: object_nodes
https://developer.blender.org/rBff3c066324b6848bd2be9c364e017ff98fae8e62

Refactor of the node graph compiler class, to have a backend-agnostic base.

The main compiler class is now itself independent of LLVM and can be used for
future backends. The implementation of specific behavior (values, statements, 
etc.)
happens through a CodeGenerator implementation. This also uses aggregation 
rather
than inheritance on the compiler class part (which is not a virtual class 
itself).

===================================================================

M       build_files/cmake/macros.cmake
M       source/blender/blenvm/CMakeLists.txt
M       source/blender/blenvm/compile/CMakeLists.txt
A       source/blender/blenvm/compile/compiler.cc
A       source/blender/blenvm/compile/compiler.h
M       source/blender/blenvm/intern/bvm_api.cc
M       source/blender/blenvm/llvm/CMakeLists.txt
A       source/blender/blenvm/llvm/llvm_codegen.cc
A       source/blender/blenvm/llvm/llvm_codegen.h
D       source/blender/blenvm/llvm/llvm_compiler.cc
D       source/blender/blenvm/llvm/llvm_compiler.h
D       source/blender/blenvm/llvm/llvm_compiler_dual.cc
M       source/blender/blenvm/llvm/llvm_engine.cc
M       source/blender/blenvm/llvm/llvm_types.h
A       source/blender/blenvm/util/util_array.h

===================================================================

diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index c3e444d..fc9ac88 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -705,7 +705,7 @@ function(SETUP_BLENDER_SORTED_LIBS)
        endif()
 
        if(WITH_LLVM)
-               list(APPEND BLENDER_SORTED_LIBS "bf_blenvm_llvm")
+               list_insert_after(BLENDER_SORTED_LIBS "bf_blenvm" 
"bf_blenvm_llvm")
        endif()
 
        foreach(SORTLIB ${BLENDER_SORTED_LIBS})
diff --git a/source/blender/blenvm/CMakeLists.txt 
b/source/blender/blenvm/CMakeLists.txt
index af06863..c15d85f 100644
--- a/source/blender/blenvm/CMakeLists.txt
+++ b/source/blender/blenvm/CMakeLists.txt
@@ -59,7 +59,7 @@ set(SRC
        modules/mod_math.h
        modules/mod_texture.h
 
-       util/util_opcode.h
+       util/util_array.h
        util/util_data_ptr.h
        util/util_debug.h
        util/util_eval_globals.cc
@@ -67,6 +67,7 @@ set(SRC
        util/util_hash.h
        util/util_map.h
        util/util_math.h
+       util/util_opcode.h
        util/util_string.h
        util/util_structs.h
        util/util_thread.h
@@ -113,8 +114,6 @@ add_subdirectory(compile)
 if(WITH_LLVM)
        add_subdirectory(llvm)
        add_definitions(-DWITH_LLVM)
-
-       set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RTTI_DISABLE_FLAGS}")
 endif()
 
 blender_add_lib(bf_blenvm "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/blenvm/compile/CMakeLists.txt 
b/source/blender/blenvm/compile/CMakeLists.txt
index 6d1c583..9f30f4a 100644
--- a/source/blender/blenvm/compile/CMakeLists.txt
+++ b/source/blender/blenvm/compile/CMakeLists.txt
@@ -40,6 +40,8 @@ set(INC_SYS
 )
 
 set(SRC
+       compiler.cc
+       compiler.h
        node_graph.cc
        node_graph.h
        node_value.cc
diff --git a/source/blender/blenvm/compile/compiler.cc 
b/source/blender/blenvm/compile/compiler.cc
new file mode 100644
index 0000000..0d2a9b7
--- /dev/null
+++ b/source/blender/blenvm/compile/compiler.cc
@@ -0,0 +1,247 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenvm/compile/compiler.cc
+ *  \ingroup bvm
+ */
+
+#include <cstdio>
+#include <set>
+#include <sstream>
+
+#include "compiler.h"
+#include "node_graph.h"
+
+#include "util_opcode.h"
+
+namespace blenvm {
+
+const ValueHandle VALUE_UNDEFINED = 0;
+
+/* ------------------------------------------------------------------------- */
+
+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;
+       }
+       BLI_assert(false && "Value not defined in any scope!");
+       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);
+}
+
+/* ------------------------------------------------------------------------- */
+
+Compiler::Compiler(CodeGenerator *codegen) :
+    m_codegen(codegen)
+{
+}
+
+Compiler::~Compiler()
+{
+}
+
+void Compiler::compile_node_graph(const string &name, const NodeGraph &graph)
+{
+       m_codegen->node_graph_begin(name, &graph, true);
+       
+       compile_node_statements(graph);
+       
+       m_codegen->node_graph_end();
+       
+       m_codegen->finalize_function();
+}
+
+void Compiler::debug_node_graph(const string &name, const NodeGraph &graph, 
FILE *file)
+{
+       m_codegen->node_graph_begin(name, &graph, true);
+       
+       compile_node_statements(graph);
+       
+       m_codegen->node_graph_end();
+       
+       m_codegen->debug_function(file);
+}
+
+/* Compile nodes as a simple expression.
+ * Every node can be treated as a single statement. Each node is translated
+ * into a function call, with regular value arguments. The resulting value is
+ * assigned to a variable and can be used for subsequent node function calls.
+ */
+void Compiler::compile_node_statements(const NodeGraph &graph)
+{
+       /* cache function arguments */
+       int num_inputs = graph.inputs.size();
+       int num_outputs = graph.outputs.size();
+       
+       for (int i = 0; i < num_inputs; ++i) {
+               const NodeGraph::Input &input = graph.inputs[i];
+               const TypeSpec *typespec = input.typedesc.get_typespec();
+               
+               if (input.key) {
+                       ValueHandle handle = m_codegen->map_argument(i, 
typespec);
+                       
m_argument_values.insert(ArgumentValueMap::value_type(input.key, handle));
+               }
+       }
+       
+       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();
+               
+               expand_node(output.key.node, scope_main);
+               ValueHandle value = scope_main.find_value(output.key);
+               
+               m_codegen->store_return_value(i, typespec, value);
+       }
+}
+
+
+void Compiler::expand_node(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(node, scope);
+                       break;
+               case NODE_TYPE_PASS:
+                       expand_pass_node(node, scope);
+                       break;
+               case NODE_TYPE_ARG:
+                       expand_argument_node(node, scope);
+                       break;
+       }
+}
+
+void Compiler::expand_pass_node(const NodeInstance *node, Scope &scope)
+{
+       BLI_assert(node->num_inputs() == 1);
+       BLI_assert(node->num_outputs() == 1);
+       
+       ConstInputKey input = node->input(0);
+       BLI_assert(input.value_type() == INPUT_EXPRESSION);
+       
+       expand_node(input.link().node, scope);
+}
+
+void Compiler::expand_argument_node(const NodeInstance *node, Scope &scope)
+{
+       BLI_assert(node->num_outputs() == 1);
+       
+       ConstOutputKey output = node->output(0);
+       scope.set_value(output, m_argument_values.at(output));
+}
+
+void Compiler::expand_expression_node(const NodeInstance *node, Scope &scope)
+{
+       /* function call arguments */
+       std::vector<ValueHandle> input_args, output_args;
+       
+       for (int i = 0; i < node->num_outputs(); ++i) {
+               ConstOutputKey output = node->output(i);
+               const TypeSpec *typespec = 
output.socket->typedesc.get_typespec();
+               
+               ValueHandle value = m_codegen->alloc_node_value(typespec);
+               output_args.push_back(value);
+               
+               scope.set_value(output, value);
+       }
+       
+       /* set input arguments */
+       for (int i = 0; i < node->num_inputs(); ++i) {
+               ConstInputKey input = node->input(i);
+               const TypeSpec *typespec = 
input.socket->typedesc.get_typespec();
+               
+               switch (input.value_type()) {
+                       case INPUT_CONSTANT: {
+                               ValueHandle value = 
m_codegen->create_constant(typespec, input.value());
+                               input_args.push_back(value);
+                               break;
+                       }
+                       case INPUT_EXPRESSION: {
+                               expand_node(input.link().node, scope);
+                               
+                               ValueHandle link_value = 
scope.find_value(input.link());
+                               input_args.push_back(link_value);
+                               break;
+                       }
+                       case INPUT_VARIABLE: {
+                               /* TODO */
+                               BLI_assert(false && "Variable inputs not 
supported yet!");
+                               break;
+                       }
+               }
+       }
+       
+       m_codegen->eval_node(node->type, input_args, output_args);
+}
+
+} /* namespace blenvm */
diff --git a/source/blender/blenvm/compile/compiler.h 
b/source/blender/blenvm/compile/compiler.h
new file mode 100644
index 0000000..375c0bd
--- /dev/null
+++ b/source/blender/blenvm/compile/compiler.h
@@ -0,0 +1,113 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __COMPILER_H__
+#define __COMPILER_H__
+
+/** \file blender/blenvm/compile/compiler.h
+ *  \ingroup bvm
+ */
+
+#include <set>
+#include <vector>
+
+#include "MEM_guardedalloc.h"
+
+#include "node_graph.h"
+
+#include "util_array.h"
+#include "util_opcode.h"
+#include "util_string.h"
+#include "util_math.h"
+
+namespace blenvm {
+
+struct NodeGraph;
+struct NodeInstance;
+struct TypeDesc;
+
+typedef void* ValueHandle;
+
+extern const ValueHandle VALUE_UNDEFINED;
+
+typedef std::map<ConstOutputKey, ValueHandle> SocketValueMap;
+struct Scope {
+       Scope(Scope *parent)

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to