[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