[Bf-blender-cvs] [576243ba39d] functions: Initial automatic function vectorization with llvm

Jacques Lucke noreply at git.blender.org
Wed May 1 15:27:29 CEST 2019


Commit: 576243ba39d3ac38ed0d13da6d13ce33f9dc5587
Author: Jacques Lucke
Date:   Wed May 1 15:27:00 2019 +0200
Branches: functions
https://developer.blender.org/rB576243ba39d3ac38ed0d13da6d13ce33f9dc5587

Initial automatic function vectorization with llvm

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

M	source/blender/blenlib/BLI_array_ref.hpp
M	source/blender/functions/backends/llvm/builder.cpp
M	source/blender/functions/backends/llvm/builder.hpp
M	source/blender/functions/backends/llvm/fgraph_ir_generation.cpp
M	source/blender/functions/backends/llvm/ir_for_tuple_call.cpp
M	source/blender/functions/backends/llvm/ir_to_tuple_call.cpp
M	source/blender/functions/backends/llvm/llvm_types.cpp
M	source/blender/functions/functions/auto_vectorization.cpp
M	source/blender/functions/functions/ranges.cpp
M	source/blender/functions/types/lists.hpp
M	source/blender/modifiers/intern/MOD_functionpoints.c

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

diff --git a/source/blender/blenlib/BLI_array_ref.hpp b/source/blender/blenlib/BLI_array_ref.hpp
index d04a1b04a94..5577fee85b5 100644
--- a/source/blender/blenlib/BLI_array_ref.hpp
+++ b/source/blender/blenlib/BLI_array_ref.hpp
@@ -20,6 +20,10 @@ template<typename T> class ArrayRef {
   {
   }
 
+  ArrayRef(const SmallVector<T> &vector) : m_start(vector.begin()), m_size(vector.size())
+  {
+  }
+
   ArrayRef slice(uint start, uint length) const
   {
     BLI_assert(start + length <= this->size());
diff --git a/source/blender/functions/backends/llvm/builder.cpp b/source/blender/functions/backends/llvm/builder.cpp
index eeb9f772afa..a1d4cd141b6 100644
--- a/source/blender/functions/backends/llvm/builder.cpp
+++ b/source/blender/functions/backends/llvm/builder.cpp
@@ -2,7 +2,7 @@
 
 namespace FN {
 
-LLVMTypes CodeBuilder::types_of_values(const LLVMValues &values)
+LLVMTypes CodeBuilder::types_of_values(LLVMValuesRef values)
 {
   LLVMTypes types;
   for (llvm::Value *value : values) {
@@ -11,23 +11,83 @@ LLVMTypes CodeBuilder::types_of_values(const LLVMValues &values)
   return types;
 }
 
+LLVMTypes CodeBuilder::types_of_values(const LLVMValues &values)
+{
+  return this->types_of_values(LLVMValuesRef(values));
+}
+
 llvm::Value *CodeBuilder::CreateCallPointer(void *func_ptr,
                                             llvm::FunctionType *ftype,
-                                            const LLVMValues &args)
+                                            LLVMValuesRef args)
 {
   auto address_int = m_builder.getInt64((size_t)func_ptr);
   auto address = m_builder.CreateIntToPtr(address_int, ftype->getPointerTo());
-  return m_builder.CreateCall(address, to_array_ref(args));
+  return m_builder.CreateCall(address, to_llvm_array_ref(args));
 }
 
-void CodeBuilder::CreateCallPointer_NoReturnValue(void *func_ptr, const LLVMValues &args)
+llvm::Value *CodeBuilder::CreateCallPointer(void *func_ptr,
+                                            llvm::FunctionType *ftype,
+                                            const LLVMValues &args)
 {
-  LLVMTypes arg_types = this->types_of_values(args);
+  return this->CreateCallPointer(func_ptr, ftype, LLVMValuesRef(args));
+}
 
+llvm::Value *CodeBuilder::CreateCallPointer(void *func_ptr,
+                                            LLVMValuesRef args,
+                                            llvm::Type *return_type)
+{
+  LLVMTypes arg_types = this->types_of_values(args);
   llvm::FunctionType *ftype = llvm::FunctionType::get(
-      this->getVoidTy(), to_array_ref(arg_types), false);
+      return_type, to_llvm_array_ref(arg_types), false);
+  return this->CreateCallPointer(func_ptr, ftype, args);
+}
+
+llvm::Value *CodeBuilder::CreateCallPointer(void *func_ptr,
+                                            const LLVMValues &args,
+                                            llvm::Type *return_type)
+{
+  return this->CreateCallPointer(func_ptr, LLVMValuesRef(args), return_type);
+}
 
-  this->CreateCallPointer(func_ptr, ftype, args);
+void CodeBuilder::CreateCallPointer_RetVoid(void *func_ptr, LLVMValuesRef args)
+{
+  this->CreateCallPointer(func_ptr, args, this->getVoidTy());
+}
+
+void CodeBuilder::CreateCallPointer_RetVoid(void *func_ptr, const LLVMValues &args)
+{
+  return this->CreateCallPointer_RetVoid(func_ptr, LLVMValuesRef(args));
+}
+
+llvm::Value *CodeBuilder::CreateCallPointer_RetVoidPtr(void *func_ptr, LLVMValuesRef args)
+{
+  return this->CreateCallPointer(func_ptr, args, this->getVoidPtrTy());
+}
+
+llvm::Value *CodeBuilder::CreateCallPointer_RetVoidPtr(void *func_ptr, const LLVMValues &args)
+{
+  return this->CreateCallPointer_RetVoidPtr(func_ptr, LLVMValuesRef(args));
+}
+
+static void simple_print(const char *str)
+{
+  std::cout << str << std::endl;
+}
+
+void CodeBuilder::CreatePrint(const char *str)
+{
+  this->CreateCallPointer_RetVoid((void *)simple_print, {this->getVoidPtr((void *)str)});
+}
+
+static void simple_print_float(float value)
+{
+  std::cout << value << std::endl;
+}
+
+void CodeBuilder::CreatePrintFloat(llvm::Value *value)
+{
+  BLI_assert(value->getType()->isFloatTy());
+  this->CreateCallPointer_RetVoid((void *)simple_print_float, {value});
 }
 
 } /* namespace FN */
diff --git a/source/blender/functions/backends/llvm/builder.hpp b/source/blender/functions/backends/llvm/builder.hpp
index fc74bd3657f..5dfc46c15ba 100644
--- a/source/blender/functions/backends/llvm/builder.hpp
+++ b/source/blender/functions/backends/llvm/builder.hpp
@@ -7,13 +7,20 @@ namespace FN {
 
 using LLVMValues = SmallVector<llvm::Value *>;
 using LLVMTypes = BLI::SmallVector<llvm::Type *>;
+using LLVMValuesRef = ArrayRef<llvm::Value *>;
+
 class LLVMTypeInfo;
 
-template<typename T> static llvm::ArrayRef<T> to_array_ref(const SmallVector<T> &vector)
+template<typename T> static llvm::ArrayRef<T> to_llvm_array_ref(const SmallVector<T> &vector)
 {
   return llvm::ArrayRef<T>(vector.begin(), vector.end());
 }
 
+template<typename T> static llvm::ArrayRef<T> to_llvm_array_ref(ArrayRef<T> array_ref)
+{
+  return llvm::ArrayRef<T>(array_ref.begin(), array_ref.end());
+}
+
 class CodeBuilder {
  private:
   llvm::IRBuilder<> m_builder;
@@ -45,6 +52,11 @@ class CodeBuilder {
     return m_builder.GetInsertBlock();
   }
 
+  llvm::Function *GetFunction()
+  {
+    return this->GetInsertBlock()->getParent();
+  }
+
   llvm::Type *getFloatTy()
   {
     return m_builder.getFloatTy();
@@ -65,6 +77,11 @@ class CodeBuilder {
     return this->getVoidPtrTy()->getPointerTo();
   }
 
+  llvm::Type *getInt32Ty()
+  {
+    return m_builder.getInt32Ty();
+  }
+
   llvm::Type *getFixedSizeType(uint size)
   {
     return llvm::ArrayType::get(m_builder.getInt8Ty(), size);
@@ -72,12 +89,12 @@ class CodeBuilder {
 
   llvm::Type *getStructType(LLVMTypes &types)
   {
-    return llvm::StructType::get(this->getContext(), to_array_ref(types));
+    return llvm::StructType::get(this->getContext(), to_llvm_array_ref(types));
   }
 
   llvm::FunctionType *getFunctionType(llvm::Type *ret_type, LLVMTypes &arg_types)
   {
-    return llvm::FunctionType::get(ret_type, to_array_ref(arg_types), false);
+    return llvm::FunctionType::get(ret_type, to_llvm_array_ref(arg_types), false);
   }
 
   /* Value Builders
@@ -104,9 +121,34 @@ class CodeBuilder {
     return m_builder.getInt64(value);
   }
 
+  llvm::Value *getInt32(int value)
+  {
+    return m_builder.getInt32(value);
+  }
+
+  /* Create new blocks
+     **************************************/
+
+  llvm::BasicBlock *NewBlockInFunction(std::string name)
+  {
+    auto *new_block = llvm::BasicBlock::Create(this->getContext(), name, this->GetFunction());
+    return new_block;
+  }
+
+  CodeBuilder NewBuilderInNewBlock(std::string name)
+  {
+    return CodeBuilder(this->NewBlockInFunction(name));
+  }
+
   /* Misc
      **************************************/
 
+  void SetInsertPoint(llvm::BasicBlock *block)
+  {
+    m_builder.SetInsertPoint(block);
+  }
+
+  LLVMTypes types_of_values(LLVMValuesRef values);
   LLVMTypes types_of_values(const LLVMValues &values);
 
   /* Instruction Builders
@@ -122,6 +164,31 @@ class CodeBuilder {
     m_builder.CreateRetVoid();
   }
 
+  llvm::PHINode *CreatePhi(llvm::Type *type, uint reserved_values)
+  {
+    return m_builder.CreatePHI(type, reserved_values);
+  }
+
+  llvm::Value *CreateICmpULT(llvm::Value *a, llvm::Value *b)
+  {
+    return m_builder.CreateICmpULT(a, b);
+  }
+
+  void CreatePrint(const char *str);
+  void CreatePrintFloat(llvm::Value *value);
+
+  void CreateBr(llvm::BasicBlock *destination_block)
+  {
+    m_builder.CreateBr(destination_block);
+  }
+
+  void CreateCondBr(llvm::Value *condition,
+                    llvm::BasicBlock *true_block,
+                    llvm::BasicBlock *false_block)
+  {
+    m_builder.CreateCondBr(condition, true_block, false_block);
+  }
+
   llvm::Value *CreateCastIntTo8(llvm::Value *value, bool is_signed)
   {
     return m_builder.CreateIntCast(value, m_builder.getInt8Ty(), is_signed);
@@ -132,6 +199,11 @@ class CodeBuilder {
     return m_builder.CreateIntCast(value, m_builder.getInt1Ty(), false);
   }
 
+  llvm::Value *CreateIAdd(llvm::Value *a, llvm::Value *b)
+  {
+    return m_builder.CreateAdd(a, b);
+  }
+
   llvm::Value *CreateFAdd(llvm::Value *a, llvm::Value *b)
   {
     return m_builder.CreateFAdd(a, b);
@@ -205,15 +277,20 @@ class CodeBuilder {
     return m_builder.CreateInsertElement(vector, value, index);
   }
 
+  llvm::Value *CreateCallPointer(void *func_ptr, llvm::FunctionType *ftype, LLVMValuesRef args);
   llvm::Value *CreateCallPointer(void *func_ptr,
                                  llvm::FunctionType *ftype,
                                  const LLVMValues &args);
+  llvm::Value *CreateCallPointer(void *func_ptr, LLVMValuesRef args, llvm::Type *return_type);
+  llvm::Value *CreateCallPointer(void *func_ptr, const LLVMValues &args, llvm::Type *return_type);
+  void CreateCallPointer_RetVoid(void *func_ptr, LLVMValuesRef args);
+  void CreateCallPointer_RetVoid(void *func_ptr, const LLVMValues &args);
+  llvm::Value *CreateCallPointer_RetVoidPtr(void *func_ptr, LLVMValuesRef args);
+  llvm::Value *CreateCallPointer_RetVoidPtr(void *func_ptr, const LLVMValues &args);
 
-  void CreateCallPointer_NoReturnValue(void *func_ptr, const LLVMValues &args);
-
-  llvm::Value *CreateCall(llvm::Function *function, const LLVMValues &args)
+  llvm::Value *CreateCall(llvm::Function *function, LLVMValuesRef args)
   {
-    return m_builder.CreateCall(function, to_array_ref(args));
+    return m_builder.CreateCall(function, to_llvm_array_ref(args));
   }
 
   llvm::Value *CreateConstGEP1_32(llvm::Value *addr, uint index)
@@ -233,6 +310,22 @@ class CodeBuilder {
     return m_builder.CreateCall(function, value);
   }
 
+  llvm::Value *CreateSIntMax(llvm::Value *a, llvm::Value *b)
+  {
+    llvm::Value *a_is_larger = m_builder.CreateICmpSGE(a, b);
+    return m_builder.CreateSelect(a_is_larger, a, b);
+  }
+
+  llvm::Value *CreateSIntMax(LLVMValuesRef values)
+  {
+    BLI_assert(values.size() >= 1);
+    llvm::Value *max_value = values[0];
+    for (llvm::Value *value : values.drop_front(1)) {
+      max_value = this->CreateSIntMax(max_value, value);
+    }
+    ret

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list