[Bf-blender-cvs] [a2ef8e34d59] functions: support different list lengths in llvm vectorization

Jacques Lucke noreply at git.blender.org
Mon May 13 10:16:50 CEST 2019


Commit: a2ef8e34d593327f90410b11a8d27775b81dc8da
Author: Jacques Lucke
Date:   Sun May 12 17:53:41 2019 +0200
Branches: functions
https://developer.blender.org/rBa2ef8e34d593327f90410b11a8d27775b81dc8da

support different list lengths in llvm vectorization

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

M	source/blender/functions/backends/llvm/builder.cpp
M	source/blender/functions/backends/llvm/builder.hpp
M	source/blender/functions/functions/auto_vectorization.cpp

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

diff --git a/source/blender/functions/backends/llvm/builder.cpp b/source/blender/functions/backends/llvm/builder.cpp
index 847f34c2cdc..79209510538 100644
--- a/source/blender/functions/backends/llvm/builder.cpp
+++ b/source/blender/functions/backends/llvm/builder.cpp
@@ -93,6 +93,28 @@ llvm::Value *CodeBuilder::CreateCallPointer(void *func_ptr,
   return this->CreateCallPointer(func_ptr, LLVMValuesRef(args), return_type, function_name);
 }
 
+static void assert_impl(bool value, const char *message)
+{
+  if (!value) {
+    std::cout << "Assert Message: " << message << std::endl;
+    BLI_assert(false);
+  }
+}
+
+void CodeBuilder::CreateAssert(llvm::Value *condition, std::string message)
+{
+  llvm::Value *condition_as_byte = this->CreateCastIntTo8(condition, false);
+  llvm::Value *message_ptr = this->getInt8Ptr(message.c_str());
+  this->CreateCallPointer(
+      (void *)assert_impl, {condition_as_byte, message_ptr}, this->getVoidTy(), "Assert");
+}
+
+void CodeBuilder::CreateAssertFalse(std::string message)
+{
+  llvm::Value *condition = this->getInt1(false);
+  this->CreateAssert(condition, message);
+}
+
 /* Printing
  **********************************/
 
@@ -117,7 +139,7 @@ void CodeBuilder::CreatePrintf(const char *format, const LLVMValues &values)
   m_builder.CreateCall(printf_func, to_llvm_array_ref(args));
 }
 
-void print_stacktrace(ExecutionContext *context)
+static void print_stacktrace(ExecutionContext *context)
 {
   context->stack().print_traceback();
 }
diff --git a/source/blender/functions/backends/llvm/builder.hpp b/source/blender/functions/backends/llvm/builder.hpp
index 9ed18ae4a15..93de20c4033 100644
--- a/source/blender/functions/backends/llvm/builder.hpp
+++ b/source/blender/functions/backends/llvm/builder.hpp
@@ -144,6 +144,11 @@ class CodeBuilder {
     return m_builder.getInt32(value);
   }
 
+  llvm::ConstantInt *getInt1(bool value)
+  {
+    return m_builder.getInt1(value);
+  }
+
   llvm::Value *getInt8Ptr(const char *ptr)
   {
     return this->getPtr((void *)ptr, this->getInt8PtrTy());
@@ -207,6 +212,11 @@ class CodeBuilder {
     return m_builder.CreateICmpULT(a, b);
   }
 
+  llvm::Value *CreateICmpEQ(llvm::Value *a, llvm::Value *b)
+  {
+    return m_builder.CreateICmpEQ(a, b);
+  }
+
   llvm::Value *CreateFCmpOLT(llvm::Value *a, llvm::Value *b)
   {
     return m_builder.CreateFCmpOLT(a, b);
@@ -254,6 +264,11 @@ class CodeBuilder {
     return m_builder.CreateFMul(a, b);
   }
 
+  llvm::Value *CreateURem(llvm::Value *a, llvm::Value *b)
+  {
+    return m_builder.CreateURem(a, b);
+  }
+
   llvm::Value *CreateAllocaBytes_VoidPtr(uint amount)
   {
     llvm::Type *size_type = this->getFixedSizeType(amount);
@@ -388,6 +403,13 @@ class CodeBuilder {
     return max_value;
   }
 
+  llvm::SwitchInst *CreateSwitch(llvm::Value *value,
+                                 llvm::BasicBlock *default_destination,
+                                 uint case_amount)
+  {
+    return m_builder.CreateSwitch(value, default_destination, case_amount);
+  }
+
   llvm::Value *CreateStructToVector(llvm::Value *value)
   {
     llvm::Type *struct_type = value->getType();
@@ -422,6 +444,9 @@ class CodeBuilder {
     return output;
   }
 
+  void CreateAssert(llvm::Value *condition, std::string message = "");
+  void CreateAssertFalse(std::string message = "");
+
   /* Print
    **************************************/
 
diff --git a/source/blender/functions/functions/auto_vectorization.cpp b/source/blender/functions/functions/auto_vectorization.cpp
index aadc0441677..9aa8b4e20ad 100644
--- a/source/blender/functions/functions/auto_vectorization.cpp
+++ b/source/blender/functions/functions/auto_vectorization.cpp
@@ -85,7 +85,7 @@ class AutoVectorizationGen : public LLVMBuildIRBody {
     llvm::Value *iteration = loop.current_iteration();
 
     LLVMValues main_inputs = this->prepare_main_function_inputs(
-        body_builder, interface, input_data_pointers, iteration);
+        body_builder, interface, input_data_pointers, input_list_lengths, iteration);
 
     LLVMValues main_outputs(m_output_info.size());
     CodeInterface main_interface(
@@ -172,26 +172,45 @@ class AutoVectorizationGen : public LLVMBuildIRBody {
   LLVMValues prepare_main_function_inputs(CodeBuilder &builder,
                                           CodeInterface &interface,
                                           const LLVMValues &input_data_pointers,
+                                          const LLVMValues &input_list_lengths,
                                           llvm::Value *iteration) const
   {
     LLVMValues main_inputs;
 
     uint list_input_index = 0;
     for (uint i = 0; i < m_input_info.size(); i++) {
+      auto *type_info = m_input_info[i].base_llvm_type;
       if (m_input_is_list[i]) {
-
-        llvm::Value *load_address = builder.CreateGEP(input_data_pointers[list_input_index],
-                                                      iteration);
-        // TODO: handle different lengths
-        llvm::Value *value_for_main = m_input_info[i].base_llvm_type->build_load_ir__relocate(
-            builder, load_address);
-        main_inputs.append(value_for_main);
+        llvm::Value *list_length = input_list_lengths[list_input_index];
+        llvm::Value *list_is_empty = builder.CreateICmpEQ(list_length, builder.getInt32(0));
+
+        auto ifthenelse = builder.CreateIfThenElse(list_is_empty, "List is Empty");
+        CodeBuilder &then_builder = ifthenelse.then_builder();
+        CodeBuilder &else_builder = ifthenelse.else_builder();
+
+        /* Use default value when list has no elements. */
+        then_builder.CreateAssertFalse("cannot handle empty lists yet");
+        llvm::Value *default_value = then_builder.getUndef(
+            type_info->get_type(then_builder.getContext()));
+
+        /* Load value from list. */
+        llvm::Value *current_index = else_builder.CreateURem(iteration, list_length);
+        llvm::Value *load_address = else_builder.CreateGEP(input_data_pointers[list_input_index],
+                                                           current_index);
+        llvm::Value *loaded_value_for_main = type_info->build_load_ir__copy(else_builder,
+                                                                            load_address);
+
+        ifthenelse.finalize(builder);
+
+        auto *phi = builder.CreatePhi(type_info->get_type(builder.getContext()), 2);
+        phi->addIncoming(default_value, then_builder.GetInsertBlock());
+        phi->addIncoming(loaded_value_for_main, else_builder.GetInsertBlock());
+        main_inputs.append(phi);
         list_input_index++;
       }
       else {
         llvm::Value *source_value = interface.get_input(i);
-        llvm::Value *value_for_main = m_input_info[i].base_llvm_type->build_copy_ir(builder,
-                                                                                    source_value);
+        llvm::Value *value_for_main = type_info->build_copy_ir(builder, source_value);
         main_inputs.append(value_for_main);
       }
     }



More information about the Bf-blender-cvs mailing list