[Bf-blender-cvs] [38463de2d9d] functions: extract some methods from llvm array execution

Jacques Lucke noreply at git.blender.org
Wed Jul 31 16:21:09 CEST 2019


Commit: 38463de2d9d29e350900636e456874f5dc701f1d
Author: Jacques Lucke
Date:   Wed Jul 31 16:09:20 2019 +0200
Branches: functions
https://developer.blender.org/rB38463de2d9d29e350900636e456874f5dc701f1d

extract some methods from llvm array execution

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

M	source/blender/functions/functions/array_execution.cpp

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

diff --git a/source/blender/functions/functions/array_execution.cpp b/source/blender/functions/functions/array_execution.cpp
index 57449ca77b4..468f7ed2f01 100644
--- a/source/blender/functions/functions/array_execution.cpp
+++ b/source/blender/functions/functions/array_execution.cpp
@@ -74,12 +74,16 @@ typedef void(CompiledFunctionSignature)(
 
 class LLVMArrayExecution : public ArrayExecution {
  private:
+  Vector<LLVMTypeInfo *> m_input_type_infos;
+  Vector<LLVMTypeInfo *> m_output_type_infos;
   std::unique_ptr<CompiledLLVM> m_compiled_function;
 
  public:
   LLVMArrayExecution(SharedFunction function) : ArrayExecution(std::move(function))
   {
     BLI_assert(m_function->has_body<LLVMBuildIRBody>());
+    m_input_type_infos = m_function->input_extensions<LLVMTypeInfo>();
+    m_output_type_infos = m_function->output_extensions<LLVMTypeInfo>();
     this->compile();
   }
 
@@ -108,25 +112,58 @@ class LLVMArrayExecution : public ArrayExecution {
   }
   llvm::Function *build_function_ir(llvm::Module *module)
   {
-    Vector<LLVMTypeInfo *> input_type_infos = m_function->input_extensions<LLVMTypeInfo>();
-    Vector<LLVMTypeInfo *> output_type_infos = m_function->output_extensions<LLVMTypeInfo>();
-
     llvm::LLVMContext &context = module->getContext();
     LLVMBuildIRBody &body = m_function->body<LLVMBuildIRBody>();
-    llvm::FunctionType *ftype = llvm::TypeBuilder<CompiledFunctionSignature, false>::get(context);
 
+    /* Create the main function. */
+    llvm::FunctionType *ftype = llvm::TypeBuilder<CompiledFunctionSignature, false>::get(context);
     llvm::Function *function = llvm::Function::Create(
         ftype, llvm::GlobalValue::LinkageTypes::ExternalLinkage, module->getName(), module);
-
     llvm::BasicBlock *bb = llvm::BasicBlock::Create(context, "entry", function);
     CodeBuilder builder(bb);
 
+    /* Take input parameters. */
     llvm::Value *size = builder.take_function_input(0, "indices_amount");
     llvm::Value *indices = builder.take_function_input(1, "indices");
     llvm::Value *input_buffers_arg = builder.take_function_input(2, "input_buffers");
     llvm::Value *output_buffers_arg = builder.take_function_input(3, "output_buffers");
     llvm::Value *context_ptr = builder.take_function_input(4, "context_ptr");
 
+    /* Extract individual input and output buffers from parameters. */
+    Vector<llvm::Value *> input_buffers = get_input_buffers(builder, input_buffers_arg);
+    Vector<llvm::Value *> output_buffers = get_output_buffers(builder, output_buffers_arg);
+
+    /* Create loop to iterate over all indices. */
+    IRConstruct_IterationsLoop loop = builder.CreateNIterationsLoop(size, "Loop");
+    CodeBuilder body_builder = loop.body_builder();
+    llvm::Value *iteration = loop.current_iteration();
+    llvm::Value *index_to_process = body_builder.CreateLoadAtIndex(indices, iteration);
+
+    /* Load inputs for the current iteration into llvm. */
+    Vector<llvm::Value *> input_values = this->get_input_values(
+        body_builder, input_buffers, index_to_process);
+    input_values.append(context_ptr);
+
+    /* Call the actual function. */
+    FunctionIRCache function_cache;
+    BuildIRSettings settings;
+    llvm::Function *actual_function = body.build_function(
+        module, m_function->name(), settings, function_cache);
+    llvm::Value *result = body_builder.CreateCall(actual_function, input_values);
+
+    /* Store the computed results in the output buffers. */
+    this->store_output_values(body_builder, output_buffers, index_to_process, result);
+
+    /* TODO(jacques): check if input values have to be freed. */
+
+    loop.finalize(builder);
+    builder.CreateRetVoid();
+
+    return function;
+  }
+
+  Vector<llvm::Value *> get_input_buffers(CodeBuilder &builder, llvm::Value *input_buffers_arg)
+  {
     Vector<llvm::Value *> input_buffers;
     for (uint i = 0; i < m_function->input_amount(); i++) {
       uint element_size = m_input_sizes[i];
@@ -136,6 +173,11 @@ class LLVMArrayExecution : public ArrayExecution {
       typed_input_buffer->setName(to_llvm(m_function->input_name(i) + " Array"));
       input_buffers.append(typed_input_buffer);
     }
+    return input_buffers;
+  }
+
+  Vector<llvm::Value *> get_output_buffers(CodeBuilder &builder, llvm::Value *output_buffers_arg)
+  {
     Vector<llvm::Value *> output_buffers;
     for (uint i = 0; i < m_function->output_amount(); i++) {
       uint element_size = m_output_sizes[i];
@@ -144,40 +186,34 @@ class LLVMArrayExecution : public ArrayExecution {
                                                                          element_size);
       output_buffers.append(typed_output_buffer);
     }
+    return output_buffers;
+  }
 
-    IRConstruct_IterationsLoop loop = builder.CreateNIterationsLoop(size, "Loop");
-    CodeBuilder body_builder = loop.body_builder();
-    llvm::Value *iteration = loop.current_iteration();
-    llvm::Value *index_to_process = body_builder.CreateLoadAtIndex(indices, iteration);
+  Vector<llvm::Value *> get_input_values(CodeBuilder &builder,
+                                         ArrayRef<llvm::Value *> input_buffers,
+                                         llvm::Value *index_to_process)
+  {
     Vector<llvm::Value *> input_values;
     for (uint i = 0; i < m_function->input_amount(); i++) {
-      llvm::Value *addr = body_builder.CreateGEP(input_buffers[i], index_to_process);
-      llvm::Value *value = input_type_infos[i]->build_load_ir__copy(body_builder, addr);
+      llvm::Value *addr = builder.CreateGEP(input_buffers[i], index_to_process);
+      llvm::Value *value = m_input_type_infos[i]->build_load_ir__copy(builder, addr);
       value->setName(to_llvm(m_function->input_name(i)));
       input_values.append(value);
     }
-    input_values.append(context_ptr);
-
-    FunctionIRCache function_cache;
-    BuildIRSettings settings;
-    llvm::Function *actual_function = body.build_function(
-        module, m_function->name(), settings, function_cache);
-
-    llvm::Value *result = body_builder.CreateCall(actual_function, input_values);
+    return input_values;
+  }
 
+  void store_output_values(CodeBuilder &builder,
+                           ArrayRef<llvm::Value *> output_buffers,
+                           llvm::Value *index_to_process,
+                           llvm::Value *computed_results)
+  {
     for (uint i = 0; i < m_function->output_amount(); i++) {
-      llvm::Value *addr = body_builder.CreateGEP(output_buffers[i], index_to_process);
-      llvm::Value *value = body_builder.CreateExtractValue(result, i);
+      llvm::Value *addr = builder.CreateGEP(output_buffers[i], index_to_process);
+      llvm::Value *value = builder.CreateExtractValue(computed_results, i);
       value->setName(to_llvm(m_function->output_name(i)));
-      output_type_infos[i]->build_store_ir__relocate(body_builder, value, addr);
+      m_output_type_infos[i]->build_store_ir__relocate(builder, value, addr);
     }
-
-    /* TODO(jacques): check if input values have to be freed. */
-
-    loop.finalize(builder);
-    builder.CreateRetVoid();
-
-    return function;
   }
 };



More information about the Bf-blender-cvs mailing list