[Bf-blender-cvs] [dbb52fec277] functions: initial for loop builder helper

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


Commit: dbb52fec27719adc334eec10e98e099112edb2b1
Author: Jacques Lucke
Date:   Thu May 9 09:51:45 2019 +0200
Branches: functions
https://developer.blender.org/rBdbb52fec27719adc334eec10e98e099112edb2b1

initial for loop builder helper

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

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 1eda0673df9..5a2e96fdd12 100644
--- a/source/blender/functions/backends/llvm/builder.cpp
+++ b/source/blender/functions/backends/llvm/builder.cpp
@@ -112,4 +112,29 @@ void CodeBuilder::CreatePrintFloat(llvm::Value *value)
   this->CreateCallPointer((void *)simple_print_float, {value}, this->getVoidTy());
 }
 
+LLVMForLoopData CodeBuilder::CreateForLoop(std::string name)
+{
+  auto entry_block = this->NewBlockInFunction(name + " Entry");
+  auto condition_block = this->NewBlockInFunction(name + " Condition");
+  auto body_block = this->NewBlockInFunction(name + " Body");
+
+  CodeBuilder entry_builder(entry_block);
+  CodeBuilder condition_builder(condition_block);
+  CodeBuilder body_builder(body_block);
+
+  this->CreateBr(entry_block);
+
+  return LLVMForLoopData(entry_builder, condition_builder, body_builder);
+}
+
+CodeBuilder LLVMForLoopData::finalize(llvm::Value *condition)
+{
+  m_entry.CreateBr(m_condition_entry);
+  m_body.CreateBr(m_condition_entry);
+
+  auto after_block = m_entry.NewBlockInFunction("After Loop");
+  m_condition.CreateCondBr(condition, m_body_entry, after_block);
+  return CodeBuilder(after_block);
+}
+
 } /* namespace FN */
diff --git a/source/blender/functions/backends/llvm/builder.hpp b/source/blender/functions/backends/llvm/builder.hpp
index a5731ba9147..99890ef6923 100644
--- a/source/blender/functions/backends/llvm/builder.hpp
+++ b/source/blender/functions/backends/llvm/builder.hpp
@@ -10,6 +10,7 @@ using LLVMTypes = BLI::SmallVector<llvm::Type *>;
 using LLVMValuesRef = ArrayRef<llvm::Value *>;
 
 class LLVMTypeInfo;
+class LLVMForLoopData;
 
 template<typename T> static llvm::ArrayRef<T> to_llvm_array_ref(const SmallVector<T> &vector)
 {
@@ -381,6 +382,48 @@ class CodeBuilder {
     }
     return output;
   }
+
+  /* Control Flow Construction
+   **************************************/
+
+  LLVMForLoopData CreateForLoop(std::string name = "");
+};
+
+class LLVMForLoopData {
+ private:
+  CodeBuilder m_entry;
+  CodeBuilder m_condition;
+  CodeBuilder m_body;
+
+  llvm::BasicBlock *m_condition_entry;
+  llvm::BasicBlock *m_body_entry;
+
+ public:
+  LLVMForLoopData(CodeBuilder entry, CodeBuilder condition, CodeBuilder body)
+      : m_entry(entry),
+        m_condition(condition),
+        m_body(body),
+        m_condition_entry(condition.GetInsertBlock()),
+        m_body_entry(body.GetInsertBlock())
+  {
+  }
+
+  CodeBuilder &entry_builder()
+  {
+    return m_entry;
+  }
+
+  CodeBuilder &condition_builder()
+  {
+    return m_condition;
+  }
+
+  CodeBuilder &body_builder()
+  {
+    return m_body;
+  }
+
+  CodeBuilder finalize(llvm::Value *condition);
 };
 
 } /* namespace FN */
diff --git a/source/blender/functions/functions/auto_vectorization.cpp b/source/blender/functions/functions/auto_vectorization.cpp
index 3388237f8f9..ef29b1fdf81 100644
--- a/source/blender/functions/functions/auto_vectorization.cpp
+++ b/source/blender/functions/functions/auto_vectorization.cpp
@@ -64,25 +64,20 @@ class AutoVectorizationGen : public LLVMBuildIRBody {
                 CodeInterface &interface,
                 const BuildIRSettings &settings) const override
   {
-    LLVMValues input_list_lengths = this->get_input_list_lengths(builder, interface);
-    llvm::Value *max_length = builder.CreateSIntMax(input_list_lengths);
+    auto loop = builder.CreateForLoop();
+    CodeBuilder &entry_builder = loop.entry_builder();
+    CodeBuilder &condition_builder = loop.condition_builder();
+    CodeBuilder &body_builder = loop.body_builder();
 
-    LLVMValues input_data_pointers = this->get_input_data_pointers(builder, interface);
-    LLVMValues output_data_pointers = this->create_output_lists(builder, interface, max_length);
+    LLVMValues input_list_lengths = this->get_input_list_lengths(entry_builder, interface);
+    llvm::Value *max_length = entry_builder.CreateSIntMax(input_list_lengths);
 
-    auto *setup_block = builder.GetInsertBlock();
-    auto *condition_block = builder.NewBlockInFunction("Loop Condition");
-    auto *body_block = builder.NewBlockInFunction("Loop Body");
-    auto *end_block = builder.NewBlockInFunction("Loop End");
-
-    builder.CreateBr(condition_block);
-
-    CodeBuilder body_builder(body_block);
-    CodeBuilder condition_builder(condition_block);
+    LLVMValues input_data_pointers = this->get_input_data_pointers(entry_builder, interface);
+    LLVMValues output_data_pointers = this->create_output_lists(
+        entry_builder, interface, max_length);
 
     auto *iteration = condition_builder.CreatePhi(condition_builder.getInt32Ty(), 2);
     auto *condition = condition_builder.CreateICmpULT(iteration, max_length);
-    condition_builder.CreateCondBr(condition, body_block, end_block);
 
     LLVMValues main_inputs = this->prepare_main_function_inputs(
         body_builder, interface, input_data_pointers, iteration);
@@ -97,12 +92,11 @@ class AutoVectorizationGen : public LLVMBuildIRBody {
         body_builder, main_outputs, output_data_pointers, iteration);
 
     llvm::Value *next_iteration = body_builder.CreateIAdd(iteration, body_builder.getInt32(1));
-    body_builder.CreateBr(condition_block);
 
-    iteration->addIncoming(condition_builder.getInt32(0), setup_block);
-    iteration->addIncoming(next_iteration, body_block);
+    iteration->addIncoming(condition_builder.getInt32(0), entry_builder.GetInsertBlock());
+    iteration->addIncoming(next_iteration, body_builder.GetInsertBlock());
 
-    builder.SetInsertPoint(end_block);
+    builder.SetInsertPoint(loop.finalize(condition).GetInsertBlock());
     this->free_input_lists(builder, interface);
   }



More information about the Bf-blender-cvs mailing list