Skip to content

Commit 5c4f1cd

Browse files
[LLVM] Implement SIMDArray
See, LFortran: lfortran/lfortran#2873
1 parent c5f6087 commit 5c4f1cd

File tree

1 file changed

+65
-5
lines changed

1 file changed

+65
-5
lines changed

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
8888
std::string current_der_type_name;
8989

9090
//! Helpful for debugging while testing LLVM code
91-
void print_util(llvm::Value* v, std::string fmt_chars, std::string endline="\t") {
91+
void print_util(llvm::Value* v, std::string fmt_chars, std::string endline) {
9292
// Usage:
93-
// print_util(tmp, "%d") // `tmp` to be an integer type
93+
// print_util(tmp, "%d", "\n") // `tmp` is an integer type to match the format specifiers
9494
std::vector<llvm::Value *> args;
9595
std::vector<std::string> fmt;
9696
args.push_back(v);
@@ -2320,7 +2320,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
23202320
Vec<llvm::Value*> llvm_diminfo;
23212321
llvm_diminfo.reserve(al, 2 * x.n_args + 1);
23222322
if( array_t->m_physical_type == ASR::array_physical_typeType::PointerToDataArray ||
2323-
array_t->m_physical_type == ASR::array_physical_typeType::FixedSizeArray ) {
2323+
array_t->m_physical_type == ASR::array_physical_typeType::FixedSizeArray ||
2324+
array_t->m_physical_type == ASR::array_physical_typeType::SIMDArray ) {
23242325
int ptr_loads_copy = ptr_loads;
23252326
for( size_t idim = 0; idim < x.n_args; idim++ ) {
23262327
ptr_loads = 2 - !LLVM::is_llvm_pointer(*ASRUtils::expr_type(m_dims[idim].m_start));
@@ -2354,7 +2355,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
23542355
} else {
23552356
tmp = arr_descr->get_single_element(array, indices, x.n_args,
23562357
array_t->m_physical_type == ASR::array_physical_typeType::PointerToDataArray,
2357-
array_t->m_physical_type == ASR::array_physical_typeType::FixedSizeArray,
2358+
array_t->m_physical_type == ASR::array_physical_typeType::FixedSizeArray || array_t->m_physical_type == ASR::array_physical_typeType::SIMDArray,
23582359
llvm_diminfo.p, is_polymorphic, current_select_type_block_type);
23592360
}
23602361
}
@@ -4705,10 +4706,14 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
47054706
}
47064707
ASR::ttype_t* target_type = ASRUtils::expr_type(x.m_target);
47074708
ASR::ttype_t* value_type = ASRUtils::expr_type(x.m_value);
4709+
ASR::expr_t *m_value = x.m_value;
4710+
if (ASRUtils::is_simd_array(x.m_target) && ASR::is_a<ASR::ArraySection_t>(*m_value)) {
4711+
m_value = ASR::down_cast<ASR::ArraySection_t>(m_value)->m_v;
4712+
}
47084713
int ptr_loads_copy = ptr_loads;
47094714
ptr_loads = 2 - (ASRUtils::is_character(*value_type) ||
47104715
ASRUtils::is_array(value_type));
4711-
this->visit_expr_wrapper(x.m_value, true);
4716+
this->visit_expr_wrapper(m_value, true);
47124717
ptr_loads = ptr_loads_copy;
47134718
if( ASR::is_a<ASR::Var_t>(*x.m_value) &&
47144719
ASR::is_a<ASR::Union_t>(*value_type) ) {
@@ -4752,6 +4757,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
47524757
bool is_value_data_only_array = (value_ptype == ASR::array_physical_typeType::PointerToDataArray);
47534758
bool is_target_fixed_sized_array = (target_ptype == ASR::array_physical_typeType::FixedSizeArray);
47544759
bool is_value_fixed_sized_array = (value_ptype == ASR::array_physical_typeType::FixedSizeArray);
4760+
bool is_target_simd_array = (target_ptype == ASR::array_physical_typeType::SIMDArray);
47554761
// bool is_target_descriptor_based_array = (target_ptype == ASR::array_physical_typeType::DescriptorArray);
47564762
bool is_value_descriptor_based_array = (value_ptype == ASR::array_physical_typeType::DescriptorArray);
47574763
if( is_value_fixed_sized_array && is_target_fixed_sized_array ) {
@@ -4844,6 +4850,27 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
48444850
arr_descr->copy_array_data_only(value_data, target_data, module.get(),
48454851
llvm_data_type, llvm_size);
48464852
}
4853+
} else if ( is_target_simd_array ) {
4854+
if (ASR::is_a<ASR::ArraySection_t>(*x.m_value)) {
4855+
int idx = 1;
4856+
ASR::ArraySection_t *arr = down_cast<ASR::ArraySection_t>(x.m_value);
4857+
(void) ASRUtils::extract_value(arr->m_args->m_left, idx);
4858+
value = llvm_utils->create_gep(value, idx-1);
4859+
target = llvm_utils->create_gep(target, 0);
4860+
ASR::dimension_t* asr_dims = nullptr;
4861+
size_t asr_n_dims = ASRUtils::extract_dimensions_from_ttype(target_type, asr_dims);
4862+
int64_t size = ASRUtils::get_fixed_size_of_array(asr_dims, asr_n_dims);
4863+
llvm::Type* llvm_data_type = llvm_utils->get_type_from_ttype_t_util(ASRUtils::type_get_past_array(
4864+
ASRUtils::type_get_past_allocatable(ASRUtils::type_get_past_pointer(target_type))), module.get());
4865+
llvm::DataLayout data_layout(module.get());
4866+
uint64_t data_size = data_layout.getTypeAllocSize(llvm_data_type);
4867+
llvm::Value* llvm_size = llvm::ConstantInt::get(context, llvm::APInt(32, size));
4868+
llvm_size = builder->CreateMul(llvm_size,
4869+
llvm::ConstantInt::get(context, llvm::APInt(32, data_size)));
4870+
builder->CreateMemCpy(target, llvm::MaybeAlign(), value, llvm::MaybeAlign(), llvm_size);
4871+
} else {
4872+
builder->CreateStore(value, target);
4873+
}
48474874
} else {
48484875
arr_descr->copy_array(value, target, module.get(),
48494876
target_type, false, false);
@@ -4929,6 +4956,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
49294956
ASRUtils::expr_value(m_arg) == nullptr ) {
49304957
tmp = llvm_utils->create_gep(tmp, 0);
49314958
}
4959+
} else if (
4960+
m_new == ASR::array_physical_typeType::SIMDArray &&
4961+
m_old == ASR::array_physical_typeType::FixedSizeArray) {
4962+
// pass
49324963
} else if(
49334964
m_new == ASR::array_physical_typeType::DescriptorArray &&
49344965
m_old == ASR::array_physical_typeType::FixedSizeArray) {
@@ -5988,6 +6019,12 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
59886019
llvm::Value *right_val = tmp;
59896020
lookup_enum_value_for_nonints = false;
59906021
LCOMPILERS_ASSERT(ASRUtils::is_real(*x.m_type))
6022+
if (ASRUtils::is_simd_array(x.m_right) && is_a<ASR::Var_t>(*x.m_right)) {
6023+
right_val = CreateLoad(right_val);
6024+
}
6025+
if (ASRUtils::is_simd_array(x.m_left) && is_a<ASR::Var_t>(*x.m_left)) {
6026+
left_val = CreateLoad(left_val);
6027+
}
59916028
switch (x.m_op) {
59926029
case ASR::binopType::Add: {
59936030
tmp = builder->CreateFAdd(left_val, right_val);
@@ -9149,6 +9186,15 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
91499186
tmp = LLVM::CreateLoad(*builder, target);
91509187
break;
91519188
}
9189+
case ASR::array_physical_typeType::SIMDArray: {
9190+
if( x.m_bound == ASR::arrayboundType::LBound ) {
9191+
tmp = llvm::ConstantInt::get(context, llvm::APInt(32, 1));
9192+
} else if( x.m_bound == ASR::arrayboundType::UBound ) {
9193+
int64_t size = ASRUtils::get_fixed_size_of_array(ASRUtils::expr_type(x.m_v));
9194+
tmp = llvm::ConstantInt::get(context, llvm::APInt(32, size));
9195+
}
9196+
break;
9197+
}
91529198
default: {
91539199
LCOMPILERS_ASSERT(false);
91549200
}
@@ -9178,6 +9224,20 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
91789224
}
91799225
}
91809226

9227+
void visit_ArrayBroadcast(const ASR::ArrayBroadcast_t &x) {
9228+
this->visit_expr_wrapper(x.m_array, true);
9229+
llvm::Value *value = tmp;
9230+
llvm::Type* ele_type = llvm_utils->get_type_from_ttype_t_util(
9231+
ASRUtils::type_get_past_array(x.m_type), module.get());
9232+
size_t n_eles = ASRUtils::get_fixed_size_of_array(x.m_type);
9233+
llvm::Type* vec_type = FIXED_VECTOR_TYPE::get(ele_type, n_eles);
9234+
llvm::AllocaInst *vec = builder->CreateAlloca(vec_type, nullptr);
9235+
for (size_t i=0; i < n_eles; i++) {
9236+
builder->CreateStore(value, llvm_utils->create_gep(vec, i));
9237+
}
9238+
tmp = CreateLoad(vec);
9239+
}
9240+
91819241
};
91829242

91839243

0 commit comments

Comments
 (0)