[Bf-blender-cvs] [0e177a3b507] functions: initial llvm wrapper for tuple call

Jacques Lucke noreply at git.blender.org
Sun Mar 3 13:53:43 CET 2019


Commit: 0e177a3b5078a450f45e15271e8a9a0a31645634
Author: Jacques Lucke
Date:   Sun Mar 3 13:53:30 2019 +0100
Branches: functions
https://developer.blender.org/rB0e177a3b5078a450f45e15271e8a9a0a31645634

initial llvm wrapper for tuple call

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

M	source/blender/functions/CMakeLists.txt
M	source/blender/functions/FN_llvm.hpp
A	source/blender/functions/backends/llvm/from_tuple_call.cpp
A	source/blender/functions/backends/llvm/from_tuple_call.hpp
A	source/blender/functions/backends/llvm/ir_utils.cpp
A	source/blender/functions/backends/llvm/ir_utils.hpp
M	source/blender/functions/backends/llvm/llvm_types.cpp
M	source/blender/functions/backends/llvm/llvm_types.hpp
M	source/blender/functions/backends/llvm/to_tuple_call.cpp
M	source/blender/functions/backends/tuple_call/tuple.hpp
M	source/blender/functions/c_wrapper.cpp
M	source/blender/functions/types/numeric.hpp

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

diff --git a/source/blender/functions/CMakeLists.txt b/source/blender/functions/CMakeLists.txt
index a2ede8f049a..0dd2cb2d89d 100644
--- a/source/blender/functions/CMakeLists.txt
+++ b/source/blender/functions/CMakeLists.txt
@@ -56,6 +56,10 @@ set(SRC
 	backends/llvm/llvm_gen.cpp
 	backends/llvm/to_tuple_call.hpp
 	backends/llvm/to_tuple_call.cpp
+	backends/llvm/from_tuple_call.hpp
+	backends/llvm/from_tuple_call.cpp
+	backends/llvm/ir_utils.hpp
+	backends/llvm/ir_utils.cpp
 
 	types/numeric.cpp
 	types/numeric.hpp
diff --git a/source/blender/functions/FN_llvm.hpp b/source/blender/functions/FN_llvm.hpp
index 95b4749a260..0aec30ca896 100644
--- a/source/blender/functions/FN_llvm.hpp
+++ b/source/blender/functions/FN_llvm.hpp
@@ -2,4 +2,5 @@
 
 #include "backends/llvm/llvm_types.hpp"
 #include "backends/llvm/llvm_gen.hpp"
-#include "backends/llvm/to_tuple_call.hpp"
\ No newline at end of file
+#include "backends/llvm/to_tuple_call.hpp"
+#include "backends/llvm/from_tuple_call.hpp"
\ No newline at end of file
diff --git a/source/blender/functions/backends/llvm/from_tuple_call.cpp b/source/blender/functions/backends/llvm/from_tuple_call.cpp
new file mode 100644
index 00000000000..ed7c8075e62
--- /dev/null
+++ b/source/blender/functions/backends/llvm/from_tuple_call.cpp
@@ -0,0 +1,109 @@
+#include "from_tuple_call.hpp"
+#include "llvm_types.hpp"
+#include "FN_tuple_call.hpp"
+#include "ir_utils.hpp"
+
+namespace FN {
+
+	static uint get_total_tuple_size(const SharedTupleMeta &meta)
+	{
+		return sizeof(Tuple) + meta->total_data_size() + meta->element_amount() * sizeof(bool);
+	}
+
+	static void construct_tuple(void *dst, SharedTupleMeta *meta_)
+	{
+		SharedTupleMeta &meta = *meta_;
+		void *data = ((char *)dst) + sizeof(Tuple);
+		bool *initialized = (bool *)(((char *)data) + meta->total_data_size());
+		new(dst) Tuple(meta, data, initialized, false);
+	}
+
+	static void call(TupleCallBody *body, Tuple *fn_in, Tuple *fn_out)
+	{
+		fn_in->set_all_initialized();
+		fn_out->set_all_uninitialized();
+		body->call(*fn_in, *fn_out);
+	}
+
+	class TupleCallLLVM : public LLVMGenBody {
+	private:
+		TupleCallBody *m_tuple_call;
+		SharedTupleMeta m_in_meta;
+		SharedTupleMeta m_out_meta;
+
+	public:
+		TupleCallLLVM(TupleCallBody *tuple_call)
+			: m_tuple_call(tuple_call),
+			  m_in_meta(SharedTupleMeta::New(m_tuple_call->owner()->signature().input_types())),
+			  m_out_meta(SharedTupleMeta::New(m_tuple_call->owner()->signature().output_types()))
+		{}
+
+		void build_ir(
+			llvm::IRBuilder<> &builder,
+			const LLVMValues &inputs,
+			LLVMValues &r_outputs) const override
+		{
+			Function *fn = m_tuple_call->owner();
+
+			llvm::Type *void_ty = builder.getVoidTy();
+			llvm::Type *void_ptr_ty = void_ty->getPointerTo();
+			llvm::Type *byte_ptr_ty = builder.getInt8PtrTy();
+
+			llvm::FunctionType *construct_ftype = llvm::FunctionType::get(
+				void_ty, {byte_ptr_ty, void_ptr_ty}, false);
+			llvm::FunctionType *call_ftype = llvm::FunctionType::get(
+				void_ty, {void_ptr_ty, byte_ptr_ty, byte_ptr_ty}, false);
+
+			/* Load static pointers into IR. */
+			llvm::Value *meta_in_ptr = void_ptr_to_ir(builder, (void *)&m_in_meta);
+			llvm::Value *meta_out_ptr = void_ptr_to_ir(builder, (void *)&m_out_meta);
+
+			llvm::Value *offsets_in_ptr = int_ptr_to_ir(
+				builder, (int *)m_in_meta->offsets().begin());
+			llvm::Value *offsets_out_ptr = int_ptr_to_ir(
+				builder, (int *)m_out_meta->offsets().begin());
+
+			/* Construct input and output tuple on stack. */
+			llvm::Value *tuple_in_ptr = alloca_bytes(builder, get_total_tuple_size(m_in_meta));
+			tuple_in_ptr->setName("tuple_in");
+			llvm::Value *tuple_out_ptr = alloca_bytes(builder, get_total_tuple_size(m_out_meta));
+			tuple_out_ptr->setName("tuple_out");
+
+			llvm::Value *tuple_in_data_ptr = builder.CreateConstGEP1_32(tuple_in_ptr, sizeof(Tuple));
+			llvm::Value *tuple_out_data_ptr = builder.CreateConstGEP1_32(tuple_out_ptr, sizeof(Tuple));
+
+			call_pointer(builder, (void *)construct_tuple,
+				construct_ftype, {tuple_in_ptr, meta_in_ptr});
+			call_pointer(builder, (void *)construct_tuple,
+				construct_ftype, {tuple_out_ptr, meta_out_ptr});
+
+
+			/* Write input values into tuple. */
+			for (uint i = 0; i < fn->signature().inputs().size(); i++) {
+				LLVMTypeInfo *type_info = fn->signature().inputs()[i].type()->extension<LLVMTypeInfo>();
+				llvm::Value *store_at_addr = lookup_tuple_address(builder, tuple_in_data_ptr, offsets_in_ptr, i);
+				type_info->build_store_ir__relocate(builder, inputs[i], store_at_addr);
+			}
+
+			/* Execute tuple call body. */
+			call_pointer(builder, (void *)call,
+				call_ftype, {void_ptr_to_ir(builder, m_tuple_call), tuple_in_ptr, tuple_out_ptr});
+
+			/* Read output values back into virtual registers. */
+			for (uint i = 0; i < fn->signature().outputs().size(); i++) {
+				LLVMTypeInfo *type_info = fn->signature().outputs()[i].type()->extension<LLVMTypeInfo>();
+				llvm::Value *load_from_addr = lookup_tuple_address(builder, tuple_out_data_ptr, offsets_out_ptr, i);
+				llvm::Value *out = type_info->build_load_ir__relocate(builder, load_from_addr);
+				out->setName("output");
+				r_outputs.append(out);
+			}
+		}
+	};
+
+	LLVMGenBody *llvm_body_for_tuple_call(
+		TupleCallBody *tuple_call_body)
+	{
+		return new TupleCallLLVM(tuple_call_body);
+	}
+
+} /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/backends/llvm/from_tuple_call.hpp b/source/blender/functions/backends/llvm/from_tuple_call.hpp
new file mode 100644
index 00000000000..f06862244c5
--- /dev/null
+++ b/source/blender/functions/backends/llvm/from_tuple_call.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "llvm_gen.hpp"
+#include <llvm/IR/IRBuilder.h>
+
+namespace FN {
+
+	class TupleCallBody;
+
+	LLVMGenBody *llvm_body_for_tuple_call(
+		TupleCallBody *tuple_call_body);
+
+} /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/backends/llvm/ir_utils.cpp b/source/blender/functions/backends/llvm/ir_utils.cpp
new file mode 100644
index 00000000000..647b759446e
--- /dev/null
+++ b/source/blender/functions/backends/llvm/ir_utils.cpp
@@ -0,0 +1,57 @@
+#include "ir_utils.hpp"
+
+namespace FN {
+
+	llvm::CallInst *call_pointer(
+		llvm::IRBuilder<> &builder,
+		const void *pointer,
+		llvm::FunctionType *type,
+		LLVMValues arguments)
+	{
+		auto address_int = builder.getInt64((size_t)pointer);
+		auto address = builder.CreateIntToPtr(address_int, type->getPointerTo());
+		return builder.CreateCall(address, to_array_ref(arguments));
+	}
+
+	llvm::Value *lookup_tuple_address(
+		llvm::IRBuilder<> &builder,
+		llvm::Value *data_addr,
+		llvm::Value *offsets_addr,
+		uint index)
+	{
+		llvm::Value *offset_addr = builder.CreateConstGEP1_32(offsets_addr, index);
+		llvm::Value *offset = builder.CreateLoad(offset_addr);
+		llvm::Value *value_byte_addr = builder.CreateGEP(data_addr, offset);
+		return value_byte_addr;
+	}
+
+	llvm::Value *void_ptr_to_ir(llvm::IRBuilder<> &builder, void *ptr)
+	{
+		return ptr_to_ir(builder, ptr, builder.getVoidTy()->getPointerTo());
+	}
+
+	llvm::Value *int_ptr_to_ir(llvm::IRBuilder<> &builder, int *ptr)
+	{
+		return ptr_to_ir(builder, ptr, builder.getInt32Ty()->getPointerTo());
+	}
+
+	llvm::Value *byte_ptr_to_ir(llvm::IRBuilder<> &builder, void *ptr)
+	{
+		return ptr_to_ir(builder, ptr, builder.getInt8PtrTy());
+	}
+
+	llvm::Value *ptr_to_ir(llvm::IRBuilder<> &builder, void *ptr, llvm::Type *type)
+	{
+		return builder.CreateIntToPtr(builder.getInt64((size_t)ptr), type);
+	}
+
+	llvm::Value *alloca_bytes(llvm::IRBuilder<> &builder, uint size)
+	{
+		llvm::Type *size_type = llvm::ArrayType::get(
+				builder.getInt8Ty(), size);
+
+		llvm::Value *tuple_in_ptr = builder.CreateAlloca(size_type);
+		return builder.CreatePointerCast(tuple_in_ptr, builder.getInt8PtrTy());
+	}
+
+} /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/backends/llvm/ir_utils.hpp b/source/blender/functions/backends/llvm/ir_utils.hpp
new file mode 100644
index 00000000000..73a8faa116e
--- /dev/null
+++ b/source/blender/functions/backends/llvm/ir_utils.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include "llvm_gen.hpp"
+#include <llvm/IR/IRBuilder.h>
+
+namespace FN {
+
+	template<typename T>
+	static llvm::ArrayRef<T> to_array_ref(SmallVector<T> &vector)
+	{
+		return llvm::ArrayRef<T>(vector.begin(), vector.end());
+	}
+
+	llvm::CallInst *call_pointer(
+		llvm::IRBuilder<> &builder,
+		const void *pointer,
+		llvm::FunctionType *type,
+		LLVMValues arguments);
+
+	llvm::Value *lookup_tuple_address(
+		llvm::IRBuilder<> &builder,
+		llvm::Value *data_addr,
+		llvm::Value *offsets_addr,
+		uint index);
+
+	llvm::Value *void_ptr_to_ir(llvm::IRBuilder<> &builder, void *ptr);
+	llvm::Value *int_ptr_to_ir(llvm::IRBuilder<> &builder, int *ptr);
+	llvm::Value *byte_ptr_to_ir(llvm::IRBuilder<> &builder, void *ptr);
+	llvm::Value *ptr_to_ir(llvm::IRBuilder<> &builder, void *ptr, llvm::Type *type);
+
+	llvm::Value *alloca_bytes(llvm::IRBuilder<> &builder, uint size);
+ } /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/backends/llvm/llvm_types.cpp b/source/blender/functions/backends/llvm/llvm_types.cpp
index b91e34d2c29..6484c6a9aba 100644
--- a/source/blender/functions/backends/llvm/llvm_types.cpp
+++ b/source/blender/functions/backends/llvm/llvm_types.cpp
@@ -62,4 +62,11 @@ namespace FN {
 		return builder.CreateLoad(addr);
 	}
 
+	llvm::Value *LLVMTypeInfo::build_load_ir__relocate(
+			llvm::IRBuilder<> &builder,
+			llvm::Value *byte_addr) const
+	{
+		return this->build_load_ir__copy(builder, byte_addr);
+	}
+
 };
\ No newline at end of file
diff --git a/source/blender/functions/backends/llvm/llvm_types.hpp b/source/blender/functions/backends/llvm/llvm_types.hpp
index c419b79f1ee..b346a65085b 100644
--- a/source/blender/functions/backends/llvm/llvm_types.hpp
+++ b/source/blender/functions/backends/llvm/llvm_types.hpp
@@ -38,6 +38,10 @@ namespace FN {
 			llvm::IRBuilder<> &builder,
 			llvm::Value *byte_addr) const;
 
+		virtual llvm::Value *build_load_ir__relocate(
+			llvm::IRBuilder<> &builder,
+			llvm::Value *byte_addr) const;
+
 	private:
 		mutable SmallMap<l

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list