[Bf-blender-cvs] [ff3c066] object_nodes: Refactor of the node graph compiler class, to have a backend-agnostic base.
Lukas Tönne
noreply at git.blender.org
Sat Jun 18 12:41:47 CEST 2016
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. @@
More information about the Bf-blender-cvs
mailing list