[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