[Bf-blender-cvs] [3dcfe053542] functions: build llvm ir for function graph

Jacques Lucke noreply at git.blender.org
Mon Mar 4 16:53:45 CET 2019


Commit: 3dcfe0535420652bca86b63b48cc08d364dced57
Author: Jacques Lucke
Date:   Mon Mar 4 16:14:45 2019 +0100
Branches: functions
https://developer.blender.org/rB3dcfe0535420652bca86b63b48cc08d364dced57

build llvm ir for function graph

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

M	source/blender/functions/CMakeLists.txt
M	source/blender/functions/FN_llvm.hpp
M	source/blender/functions/backends/dependencies/fgraph_dependencies.cpp
M	source/blender/functions/backends/dependencies/fgraph_dependencies.hpp
M	source/blender/functions/backends/llvm/compile.cpp
A	source/blender/functions/backends/llvm/fgraph_ir_generation.cpp
A	source/blender/functions/backends/llvm/fgraph_ir_generation.hpp
M	source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
M	source/blender/functions/backends/tuple_call/fgraph_tuple_call.hpp
M	source/blender/functions/core/data_flow_graph.cpp
M	source/blender/functions/core/data_flow_graph.hpp
M	source/blender/functions/core/dot_export.cpp
M	source/blender/functions/core/parameter.hpp
M	source/blender/functions/frontends/data_flow_nodes/builder.cpp
M	source/blender/functions/frontends/data_flow_nodes/builder.hpp
M	source/blender/functions/frontends/data_flow_nodes/function_generation.cpp
M	source/blender/functions/frontends/data_flow_nodes/graph_generation.cpp
M	source/blender/functions/frontends/data_flow_nodes/inserters.cpp
M	source/blender/functions/frontends/data_flow_nodes/test_nodes.cpp
M	source/blender/functions/frontends/data_flow_nodes/test_sockets.cpp

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

diff --git a/source/blender/functions/CMakeLists.txt b/source/blender/functions/CMakeLists.txt
index eba45cc97d8..f000e32ee2d 100644
--- a/source/blender/functions/CMakeLists.txt
+++ b/source/blender/functions/CMakeLists.txt
@@ -66,6 +66,8 @@ set(SRC
 	backends/llvm/compile.cpp
 	backends/llvm/ir_utils.hpp
 	backends/llvm/ir_utils.cpp
+	backends/llvm/fgraph_ir_generation.hpp
+	backends/llvm/fgraph_ir_generation.cpp
 
 	types/numeric.cpp
 	types/numeric.hpp
diff --git a/source/blender/functions/FN_llvm.hpp b/source/blender/functions/FN_llvm.hpp
index 34f40fc5916..6cc0e069212 100644
--- a/source/blender/functions/FN_llvm.hpp
+++ b/source/blender/functions/FN_llvm.hpp
@@ -5,4 +5,5 @@
 #include "backends/llvm/build_ir_body.hpp"
 #include "backends/llvm/ir_to_tuple_call.hpp"
 #include "backends/llvm/ir_for_tuple_call.hpp"
-#include "backends/llvm/compiled_body.hpp"
\ No newline at end of file
+#include "backends/llvm/compiled_body.hpp"
+#include "backends/llvm/fgraph_ir_generation.hpp"
\ No newline at end of file
diff --git a/source/blender/functions/backends/dependencies/fgraph_dependencies.cpp b/source/blender/functions/backends/dependencies/fgraph_dependencies.cpp
index b94f28cd33d..1a0c4b888c4 100644
--- a/source/blender/functions/backends/dependencies/fgraph_dependencies.cpp
+++ b/source/blender/functions/backends/dependencies/fgraph_dependencies.cpp
@@ -7,22 +7,23 @@ namespace FN {
 		SharedDataFlowGraph m_graph;
 
 	public:
-		FGraphDependencies(const FunctionGraph &function_graph)
+		FGraphDependencies(FunctionGraph &function_graph)
 			: m_graph(function_graph.graph()) {}
 
 		void dependencies(Dependencies &deps) const override
 		{
-			for (const Node *node : m_graph->all_nodes()) {
-				const DependenciesBody *body = node->function()->body<DependenciesBody>();
+			for (Node *node : m_graph->all_nodes()) {
+				DependenciesBody *body = node->function()->body<DependenciesBody>();
 				if (body) body->dependencies(deps);
 			}
 		}
 	};
 
-	DependenciesBody *fgraph_dependencies(
-		const FunctionGraph &function_graph)
+	void fgraph_add_DependenciesBody(
+		SharedFunction &fn,
+		FunctionGraph &fgraph)
 	{
-		return new FGraphDependencies(function_graph);
+		fn->add_body(new FGraphDependencies(fgraph));
 	}
 
 } /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/backends/dependencies/fgraph_dependencies.hpp b/source/blender/functions/backends/dependencies/fgraph_dependencies.hpp
index 7c2a0a8402b..09a497cb076 100644
--- a/source/blender/functions/backends/dependencies/fgraph_dependencies.hpp
+++ b/source/blender/functions/backends/dependencies/fgraph_dependencies.hpp
@@ -5,7 +5,8 @@
 
 namespace FN {
 
-	DependenciesBody *fgraph_dependencies(
-		const FunctionGraph &function_graph);
+	void fgraph_add_DependenciesBody(
+		SharedFunction &fn,
+		FunctionGraph &fgraph);
 
 } /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/backends/llvm/compile.cpp b/source/blender/functions/backends/llvm/compile.cpp
index eb334128666..f49cb41a273 100644
--- a/source/blender/functions/backends/llvm/compile.cpp
+++ b/source/blender/functions/backends/llvm/compile.cpp
@@ -23,7 +23,7 @@ namespace FN {
 		ee->finalizeObject();
 		ee->generateCodeForModule(module);
 
-		module->print(llvm::outs(), nullptr);
+		//module->print(llvm::outs(), nullptr);
 
 		uint64_t function_ptr = ee->getFunctionAddress(
 			main_function->getName().str());
diff --git a/source/blender/functions/backends/llvm/fgraph_ir_generation.cpp b/source/blender/functions/backends/llvm/fgraph_ir_generation.cpp
new file mode 100644
index 00000000000..a59aa9665ec
--- /dev/null
+++ b/source/blender/functions/backends/llvm/fgraph_ir_generation.cpp
@@ -0,0 +1,184 @@
+#include "fgraph_ir_generation.hpp"
+#include "FN_llvm.hpp"
+#include "FN_tuple_call.hpp"
+
+namespace FN {
+
+	class BuildGraphIR : public LLVMBuildIRBody {
+	private:
+		FunctionGraph m_fgraph;
+		SmallSocketSetVector m_inputs;
+		SmallSocketSetVector m_outputs;
+		SocketSet m_required_sockets;
+
+		using SocketValueMap = SmallMap<Socket, llvm::Value *>;
+
+	public:
+		BuildGraphIR(FunctionGraph &fgraph)
+			: m_fgraph(fgraph),
+			  m_inputs(fgraph.inputs()),
+			  m_outputs(fgraph.outputs())
+		{
+			for (Node *node : m_fgraph.graph()->all_nodes()) {
+				SharedFunction &fn = node->function();
+				if (fn->has_body<LLVMBuildIRBody>()) {
+					continue;
+				}
+				if (fn->has_body<TupleCallBody>()) {
+					derive_LLVMBuildIRBody_from_TupleCallBody(fn);
+					continue;
+				}
+				/* TODO: Find easy check to see which nodes
+				 *   will need to be executed. */
+			}
+			m_required_sockets = this->find_required_sockets();
+			std::cout << "Required Sockets: " << m_required_sockets.size() << std::endl;
+		}
+
+		void build_ir(
+			llvm::IRBuilder<> &builder,
+			const LLVMValues &input_values,
+			LLVMValues &r_output_values) const override
+		{
+			SocketValueMap values;
+			for (uint i = 0; i < input_values.size(); i++) {
+				values.add(m_inputs[i], input_values[i]);
+			}
+
+			SocketSet forwarded_sockets;
+			for (Socket socket : m_outputs) {
+				this->generate_for_socket(builder, socket, values, forwarded_sockets);
+				r_output_values.append(values.lookup(socket));
+			}
+		}
+
+	private:
+		SocketSet find_required_sockets() const
+		{
+			SocketSet required_sockets;
+			for (Socket socket : m_fgraph.outputs()) {
+				this->find_required_sockets(socket, required_sockets);
+			}
+			return required_sockets;
+		}
+
+		void find_required_sockets(Socket socket, SocketSet &required_sockets) const
+		{
+			if (required_sockets.contains(socket)) {
+				return;
+			}
+
+			required_sockets.add(socket);
+
+			if (m_inputs.contains(socket)) {
+				/* do nothing */
+			}
+			else if (socket.is_input()) {
+				this->find_required_sockets(socket.origin(), required_sockets);
+				return;
+			}
+			else if (socket.is_output()) {
+				for (Socket input : socket.node()->inputs()) {
+					this->find_required_sockets(input, required_sockets);
+				}
+				return;
+			}
+			else {
+				BLI_assert(!"should never happen");
+			}
+		}
+
+		void generate_for_socket(
+			llvm::IRBuilder<> &builder,
+			Socket socket,
+			SocketValueMap &values,
+			SocketSet &forwarded_sockets) const
+		{
+			if (values.contains(socket)) {
+				/* do nothing */
+			}
+			else if (socket.is_input()) {
+				Socket origin = socket.origin();
+				this->generate_for_socket(builder, origin, values, forwarded_sockets);
+				this->forward_output_if_necessary(builder, origin, values, forwarded_sockets);
+			}
+			else if (socket.is_output()) {
+				Node *node = socket.node();
+				LLVMValues input_values;
+				for (Socket input : node->inputs()) {
+					this->generate_for_socket(builder, input, values, forwarded_sockets);
+					input_values.append(values.lookup(input));
+				}
+
+				LLVMValues output_values;
+				auto *body = node->function()->body<LLVMBuildIRBody>();
+				BLI_assert(body);
+				body->build_ir(builder, input_values, output_values);
+
+				for (uint i = 0; i < output_values.size(); i++) {
+					Socket output = node->output(i);
+					values.add(output, output_values[i]);
+					this->forward_output_if_necessary(builder, output, values, forwarded_sockets);
+				}
+			}
+			else {
+				BLI_assert(!"should never happen");
+			}
+
+		}
+
+		void forward_output_if_necessary(
+			llvm::IRBuilder<> &builder,
+			Socket output,
+			SocketValueMap &values,
+			SocketSet &forwarded_sockets) const
+		{
+			BLI_assert(output.is_output());
+			if (!forwarded_sockets.contains(output)) {
+				this->forward_output(builder, output, values);
+				forwarded_sockets.add(output);
+			}
+		}
+
+		void forward_output(
+			llvm::IRBuilder<> &builder,
+			Socket output,
+			SocketValueMap &values) const
+		{
+			llvm::Value *value_to_forward = values.lookup(output);
+			SharedType &type = output.type();
+			LLVMTypeInfo *type_info = type->extension<LLVMTypeInfo>();
+			BLI_assert(type_info);
+
+			SmallSocketVector targets;
+			for (Socket target : output.targets()) {
+				if (m_required_sockets.contains(target) && !values.contains(target)) {
+					BLI_assert(type == target.type());
+					targets.append(target);
+				}
+			}
+
+			if (targets.size() == 0) {
+				type_info->build_free_ir(builder, value_to_forward);
+			}
+			else if (targets.size() == 1) {
+				values.add(targets[0], value_to_forward);
+			}
+			else {
+				values.add(targets[0], value_to_forward);
+				for (Socket target : targets) {
+					llvm::Value *copied_value = type_info->build_copy_ir(builder, value_to_forward);
+					values.add(target, copied_value);
+				}
+			}
+		}
+	};
+
+	void fgraph_add_LLVMBuildIRBody(
+		SharedFunction &fn,
+		FunctionGraph &fgraph)
+	{
+		fn->add_body(new BuildGraphIR(fgraph));
+	}
+
+} /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/backends/llvm/fgraph_ir_generation.hpp b/source/blender/functions/backends/llvm/fgraph_ir_generation.hpp
new file mode 100644
index 00000000000..38cec2c1c0f
--- /dev/null
+++ b/source/blender/functions/backends/llvm/fgraph_ir_generation.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "FN_core.hpp"
+
+namespace FN {
+
+	void fgraph_add_LLVMBuildIRBody(
+		SharedFunction &fn,
+		FunctionGraph &fgraph);
+
+} /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp b/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
index f61f484a35c..aa8bb1c2560 100644
--- a/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
+++ b/source/blender/functions/backends/tuple_call/fgraph_tuple_call.cpp
@@ -31,7 +31,7 @@ namespace FN {
 				this->compute_socket(fn_in, out, out_index, socket.origin());
 			}
 			else {
-				const Node *node = socket.node();
+				Node *node = socket.node();
 				const Signature &signature = node->signature();
 
 				Tuple tmp_in(signature.input_types());
@@ -41,7 +41,7 @@ namespace FN {
 					this->compute_socket(fn_in, tmp_in, i, node->input(i));
 				}
 
-				const TupleCallBody *body = node->function()->body<TupleCallBody>();
+				TupleCallBody *body = node->function()->body<TupleCallBody>();
 				body->call(tmp_in, tmp_out);
 
 				Tuple::copy_ele

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list