[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