Commit: 21fc76b50d3157c94dda1630b6d6356adf857c20
Author: Jacques Lucke
Date:   Sun Mar 3 20:13:24 2019 +0100
Branches: functions
https://developer.blender.org/rB21fc76b50d3157c94dda1630b6d6356adf857c20

precompiled llvm function body

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

M       source/blender/functions/CMakeLists.txt
M       source/blender/functions/FN_llvm.hpp
A       source/blender/functions/backends/llvm/compiled_body.cpp
A       source/blender/functions/backends/llvm/compiled_body.hpp
A       source/blender/functions/backends/llvm/initialize.cpp
A       source/blender/functions/backends/llvm/initialize.hpp
M       source/blender/functions/backends/llvm/ir_utils.cpp
M       source/blender/functions/backends/llvm/ir_utils.hpp
M       source/blender/functions/backends/llvm/to_tuple_call.cpp
M       source/blender/functions/backends/llvm/to_tuple_call.hpp
M       source/blender/functions/c_wrapper.cpp
M       source/blender/functions/functions/scalar_math.cpp

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

diff --git a/source/blender/functions/CMakeLists.txt 
b/source/blender/functions/CMakeLists.txt
index 0dd2cb2d89d..cdc051a7bbc 100644
--- a/source/blender/functions/CMakeLists.txt
+++ b/source/blender/functions/CMakeLists.txt
@@ -50,6 +50,8 @@ set(SRC
        backends/dependencies/fgraph_dependencies.hpp
        backends/dependencies/fgraph_dependencies.cpp
 
+       backends/llvm/initialize.hpp
+       backends/llvm/initialize.cpp
        backends/llvm/llvm_types.hpp
        backends/llvm/llvm_types.cpp
        backends/llvm/llvm_gen.hpp
@@ -58,6 +60,8 @@ set(SRC
        backends/llvm/to_tuple_call.cpp
        backends/llvm/from_tuple_call.hpp
        backends/llvm/from_tuple_call.cpp
+       backends/llvm/compiled_body.hpp
+       backends/llvm/compiled_body.cpp
        backends/llvm/ir_utils.hpp
        backends/llvm/ir_utils.cpp
 
diff --git a/source/blender/functions/FN_llvm.hpp 
b/source/blender/functions/FN_llvm.hpp
index 0aec30ca896..ebdaf347f45 100644
--- a/source/blender/functions/FN_llvm.hpp
+++ b/source/blender/functions/FN_llvm.hpp
@@ -1,6 +1,8 @@
 #pragma once
 
+#include "backends/llvm/initialize.hpp"
 #include "backends/llvm/llvm_types.hpp"
 #include "backends/llvm/llvm_gen.hpp"
 #include "backends/llvm/to_tuple_call.hpp"
-#include "backends/llvm/from_tuple_call.hpp"
\ No newline at end of file
+#include "backends/llvm/from_tuple_call.hpp"
+#include "backends/llvm/compiled_body.hpp"
\ No newline at end of file
diff --git a/source/blender/functions/backends/llvm/compiled_body.cpp 
b/source/blender/functions/backends/llvm/compiled_body.cpp
new file mode 100644
index 00000000000..e3d23e8d676
--- /dev/null
+++ b/source/blender/functions/backends/llvm/compiled_body.cpp
@@ -0,0 +1,110 @@
+#include "FN_llvm.hpp"
+#include "ir_utils.hpp"
+
+#include <llvm/IR/Verifier.h>
+#include <llvm/ExecutionEngine/ExecutionEngine.h>
+
+namespace FN {
+
+       const char *CompiledLLVMBody::identifier_in_composition()
+       {
+               return "Compiled LLVM Body";
+       }
+
+       void CompiledLLVMBody::free_self(void *value)
+       {
+               CompiledLLVMBody *v = (CompiledLLVMBody *)value;
+               delete v;
+       }
+
+       CompiledLLVMBody::~CompiledLLVMBody()
+       {
+               delete m_engine;
+       }
+
+       CompiledLLVMBody *CompiledLLVMBody::FromIR(
+               llvm::Module *module,
+               llvm::Function *main_func)
+       {
+               BLI_assert(!llvm::verifyModule(*module, &llvm::outs()));
+
+               llvm::ExecutionEngine *ee = llvm::EngineBuilder(
+                       std::unique_ptr<llvm::Module>(module)).create();
+               ee->finalizeObject();
+               ee->generateCodeForModule(module);
+
+               module->print(llvm::outs(), nullptr);
+
+               uint64_t function_ptr = ee->getFunctionAddress(
+                       main_func->getName().str());
+
+               auto body = new CompiledLLVMBody();
+               body->m_engine = ee;
+               body->m_func_ptr = (void *)function_ptr;
+               return body;
+       }
+
+       static CompiledLLVMBody *compile_llvm_body(
+               SharedFunction &fn,
+               llvm::LLVMContext &context)
+       {
+               auto input_type_infos = 
fn->signature().input_extensions<LLVMTypeInfo>();
+               auto output_type_infos = 
fn->signature().output_extensions<LLVMTypeInfo>();
+               LLVMTypes input_types = types_of_type_infos(input_type_infos, 
context);
+               LLVMTypes output_types = types_of_type_infos(output_type_infos, 
context);
+
+               llvm::Type *output_type = llvm::StructType::get(context, 
to_array_ref(output_types));
+
+               llvm::FunctionType *function_type = llvm::FunctionType::get(
+                       output_type, to_array_ref(input_types), false);
+
+               llvm::Module *module = new llvm::Module(fn->name(), context);
+
+               llvm::Function *function = llvm::Function::Create(
+                       function_type,
+                       llvm::GlobalValue::LinkageTypes::ExternalLinkage,
+                       fn->name(),
+                       module);
+
+               LLVMValues input_values;
+               for (llvm::Value &value : function->args()) {
+                       input_values.append(&value);
+               }
+
+               llvm::BasicBlock *bb = llvm::BasicBlock::Create(context, 
"entry", function);
+               llvm::IRBuilder<> builder(bb);
+
+               LLVMGenBody *gen_body = fn->body<LLVMGenBody>();
+               BLI_assert(gen_body);
+
+               LLVMValues output_values;
+               gen_body->build_ir(builder, input_values, output_values);
+               BLI_assert(output_values.size() == output_types.size());
+
+               llvm::Value *return_value = llvm::UndefValue::get(output_type);
+               for (uint i = 0; i < output_values.size(); i++) {
+                       return_value = builder.CreateInsertValue(return_value, 
output_values[i], i);
+               }
+               builder.CreateRet(return_value);
+
+               return CompiledLLVMBody::FromIR(
+                       module, function);
+       }
+
+       bool try_ensure_CompiledLLVMBody(
+               SharedFunction &fn,
+               llvm::LLVMContext &context)
+       {
+               if (fn->body<CompiledLLVMBody>() != nullptr) {
+                       return true;
+               }
+
+               if (fn->body<LLVMGenBody>() != nullptr) {
+                       fn->add_body(compile_llvm_body(fn, context));
+                       return true;
+               }
+
+               return false;
+       }
+
+} /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/backends/llvm/compiled_body.hpp 
b/source/blender/functions/backends/llvm/compiled_body.hpp
new file mode 100644
index 00000000000..479da64489f
--- /dev/null
+++ b/source/blender/functions/backends/llvm/compiled_body.hpp
@@ -0,0 +1,41 @@
+#pragma once
+
+#include "FN_core.hpp"
+
+namespace llvm {
+       class ExecutionEngine;
+       class Module;
+       class LLVMContext;
+       class FunctionType;
+}
+
+namespace FN {
+
+       class CompiledLLVMBody : public FunctionBody {
+       private:
+               void *m_func_ptr;
+               llvm::ExecutionEngine *m_engine;
+
+               CompiledLLVMBody() = default;
+
+       public:
+               static const char *identifier_in_composition();
+               static void free_self(void *value);
+
+               static CompiledLLVMBody *FromIR(
+                       llvm::Module *module,
+                       llvm::Function *main_func);
+
+               ~CompiledLLVMBody();
+
+               void *function_ptr()
+               {
+                       return m_func_ptr;
+               }
+       };
+
+       bool try_ensure_CompiledLLVMBody(
+               SharedFunction &fn,
+               llvm::LLVMContext &context);
+
+} /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/backends/llvm/initialize.cpp 
b/source/blender/functions/backends/llvm/initialize.cpp
new file mode 100644
index 00000000000..e3cd36584e9
--- /dev/null
+++ b/source/blender/functions/backends/llvm/initialize.cpp
@@ -0,0 +1,14 @@
+#include "initialize.hpp"
+
+#include <llvm/Support/TargetSelect.h>
+
+namespace FN {
+
+       void initialize_llvm()
+       {
+               llvm::InitializeNativeTarget();
+               llvm::InitializeNativeTargetAsmPrinter();
+               llvm::InitializeNativeTargetAsmParser();
+       }
+
+} /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/backends/llvm/initialize.hpp 
b/source/blender/functions/backends/llvm/initialize.hpp
new file mode 100644
index 00000000000..9800f164c49
--- /dev/null
+++ b/source/blender/functions/backends/llvm/initialize.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace FN {
+
+       void initialize_llvm();
+
+} /* 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
index a232af3416b..f4caf4b1ff0 100644
--- a/source/blender/functions/backends/llvm/ir_utils.cpp
+++ b/source/blender/functions/backends/llvm/ir_utils.cpp
@@ -63,4 +63,25 @@ namespace FN {
                return types;
        }
 
+       LLVMTypes types_of_type_infos(
+               const SmallVector<LLVMTypeInfo *> &type_infos,
+               llvm::LLVMContext &context)
+       {
+               LLVMTypes types;
+               for (auto info : type_infos) {
+                       types.append(info->get_type(context));
+               }
+               return types;
+       }
+
+       llvm::FunctionType *function_type_from_signature(
+               const Signature &signature,
+               llvm::LLVMContext &context)
+       {
+               auto input_types = 
types_of_type_infos(signature.input_extensions<LLVMTypeInfo>(), context);
+               auto output_types = 
types_of_type_infos(signature.output_extensions<LLVMTypeInfo>(), context);
+               llvm::Type *output_type = llvm::StructType::get(context, 
to_array_ref(output_types));
+               return llvm::FunctionType::get(output_type, 
to_array_ref(input_types), false);
+       }
+
 } /* 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
index 843b746b9ad..d4b429d0473 100644
--- a/source/blender/functions/backends/llvm/ir_utils.hpp
+++ b/source/blender/functions/backends/llvm/ir_utils.hpp
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "llvm_gen.hpp"
+#include "FN_llvm.hpp"
 #include <llvm/IR/IRBuilder.h>
 
 namespace FN {
@@ -29,6 +29,14 @@ namespace FN {
        llvm::Value *ptr_to_ir(llvm::IRBuilder<> &builder, void *ptr, 
llvm::Type *type);
 
        LLVMTypes types_of_values(const LLVMValues &values);
+       LLVMTypes types_of_type_infos(
+               const SmallVector<LLVMTypeInfo *> &type_infos,
+               llvm::LLVMContext &context);
 
        llvm::Value *alloca_bytes(llvm::IRBuilder<> &builder, uint size);
+
+       llvm::FunctionType *function_type_from_signature(
+               const Signature &signature,
+               llvm::LLVMContext &context);
+
  } /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/backends/llvm/to_tuple_call.cpp 
b/source/blender/functions/backends/llvm/to_tuple_call.cpp
index 34a672e758d..db01077ee8f 100644
--- a/source/blender/functions/backends/llvm/to_tuple_call.cpp
+++ b/source/blender/functions/backends/llvm/to_tuple_call.cpp
@@ -1,9 +1,6 @@
-#include "to_tuple_call.hpp"
-#include "llvm_types.hpp"
-#include "llvm_gen.hpp"
-#include "ir_utils.hpp"
-
+#include "FN_llvm.hpp"
 #include "FN_tuple_call.hpp"
+#include "ir_utils.hpp"
 
 #include <llvm/IR/Verifier.h>
 #include <llvm/Support/TargetSelect.h>
@@ -11,9 +8,14 @@
 
 namespace FN {
 
+       typedef std::function<void (
+               llvm::IRBuilder<> &builder,
+               const LLVMValues &inputs,
+               LLVMValues &outputs)> BuildIRFunction;
+
        static llvm::Function *insert_tuple_call_function(
-               Function *fn,
-               LLVMGenBody *llvm_body,
+               SharedFunction &fn,
+               BuildIRFunction build_ir,
                llvm::Module *module)
        {
                llvm::LLVMContext &context = module->getContext();
@@ -61,7 +63,8 @@ namespace FN {
                }
 
                LLVMValues output_values;
-               llvm_body->build_ir(builder, input_values, output_values);
+               build_ir(builder, input_values, output_values);
+               BLI_assert(output_values.size() == 
fn->signature().outputs().size());
 
                for (uint i = 0; i < output_values.size(); i++) {
                        llvm::Value *value_byte_addr = lookup_tuple_address(
@@ -106,24 +109,19 @@ namespace FN {
                }
        };
 
-       TupleCallBody *compile_llvm_to_tuple_call(
-               LLVMGenBody *llvm_body,
-               llvm::LLVMContext &context)
+       static TupleCallBody *compile_ir_to_tuple_call(
+               SharedFunction &

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