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. @@

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

Reply via email to