diff --git a/src/libasr/asr_utils.cpp b/src/libasr/asr_utils.cpp index 3e393875a4..bfb718216d 100644 --- a/src/libasr/asr_utils.cpp +++ b/src/libasr/asr_utils.cpp @@ -190,7 +190,7 @@ void update_call_args(Allocator &al, SymbolTable *current_scope, bool implicit_i } return sym; } - + void handle_Var(ASR::expr_t* arg_expr, ASR::expr_t** expr_to_replace) { if (ASR::is_a(*arg_expr)) { ASR::Var_t* arg_var = ASR::down_cast(arg_expr); @@ -1521,7 +1521,12 @@ void make_ArrayBroadcast_t_util(Allocator& al, const Location& loc, if (ret_type == nullptr) { // TODO: Construct appropriate return type here // For now simply coping the type from expr1 - ret_type = expr1_type; + if (ASRUtils::is_simd_array(expr1)) { + // TODO: Make this more general; do not check for SIMDArray + ret_type = ASRUtils::duplicate_type(al, expr1_type); + } else { + ret_type = expr1_type; + } } expr2 = ASRUtils::EXPR(ASR::make_ArrayBroadcast_t(al, loc, expr2, dest_shape, ret_type, value)); diff --git a/src/libasr/asr_utils.h b/src/libasr/asr_utils.h index 3a6092ecdc..51337784d5 100644 --- a/src/libasr/asr_utils.h +++ b/src/libasr/asr_utils.h @@ -4731,6 +4731,12 @@ inline ASR::ttype_t* make_Pointer_t_util(Allocator& al, const Location& loc, ASR int64_t compute_trailing_zeros(int64_t number); +static inline bool is_simd_array(ASR::expr_t *v) { + return (ASR::is_a(*expr_type(v)) && + ASR::down_cast(expr_type(v))->m_physical_type + == ASR::array_physical_typeType::SIMDArray); +} + } // namespace ASRUtils } // namespace LCompilers diff --git a/src/libasr/codegen/asr_to_c.cpp b/src/libasr/codegen/asr_to_c.cpp index 00bb14ce19..c7e1fc3682 100644 --- a/src/libasr/codegen/asr_to_c.cpp +++ b/src/libasr/codegen/asr_to_c.cpp @@ -1204,7 +1204,7 @@ R"( // Initialise Numpy src = this->check_tmp_buffer() + out; } - void visit_ArrayBroadcast(const ASR::ArrayBroadcast_t& x) { + void visit_ArrayBroadcast(const ASR::ArrayBroadcast_t &x) { /* !LF$ attributes simd :: A real :: A(8) @@ -1212,24 +1212,16 @@ R"( // Initialise Numpy We need to generate: a = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; */ - CHECK_FAST_C(compiler_options, x) - if (x.m_value) { - ASR::expr_t* value = x.m_value; - LCOMPILERS_ASSERT(ASR::is_a(*value)); - ASR::ArrayConstant_t* array_const = ASR::down_cast(value); - std::string array_const_str = "{"; - for( size_t i = 0; i < array_const->n_args; i++ ) { - ASR::expr_t* array_const_arg = array_const->m_args[i]; - this->visit_expr(*array_const_arg); - array_const_str += src + ", "; - } - array_const_str.pop_back(); - array_const_str.pop_back(); - array_const_str += "}"; - - src = array_const_str; + size_t size = ASRUtils::get_fixed_size_of_array(x.m_type); + std::string array_const_str = "{"; + for( size_t i = 0; i < size; i++ ) { + this->visit_expr(*x.m_array); + array_const_str += src; + if (i < size - 1) array_const_str += ", "; } + array_const_str += "}"; + src = array_const_str; } void visit_ArraySize(const ASR::ArraySize_t& x) { diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index 9cda6714b1..15e40ab39b 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -1049,13 +1049,14 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) { } void visit_ArrayPhysicalCast(const ASR::ArrayPhysicalCast_t& x) { - src = ""; - this->visit_expr(*x.m_arg); - if (x.m_old == ASR::array_physical_typeType::FixedSizeArray && + src = ""; + this->visit_expr(*x.m_arg); + if (x.m_old == ASR::array_physical_typeType::FixedSizeArray && x.m_new == ASR::array_physical_typeType::SIMDArray) { std::string arr_element_type = CUtils::get_c_type_from_ttype_t(ASRUtils::expr_type(x.m_arg)); int64_t size = ASRUtils::get_fixed_size_of_array(ASRUtils::expr_type(x.m_arg)); - std::string cast = arr_element_type + " __attribute__ (( vector_size(sizeof(" + arr_element_type + ") * " + std::to_string(size) + ") ))"; + std::string cast = arr_element_type + " __attribute__ (( vector_size(sizeof(" + + arr_element_type + ") * " + std::to_string(size) + ") ))"; src = "(" + cast + ") " + src; } } @@ -1245,7 +1246,37 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) { bool is_value_dict = ASR::is_a(*m_value_type); bool alloc_return_var = false; std::string indent(indentation_level*indentation_spaces, ' '); - if (ASR::is_a(*x.m_target)) { + if (ASRUtils::is_simd_array(x.m_target)) { + this->visit_expr(*x.m_target); + target = src; + if (ASR::is_a(*x.m_value) || + ASR::is_a(*x.m_value)) { + std::string arr_element_type = CUtils::get_c_type_from_ttype_t( + ASRUtils::expr_type(x.m_value)); + std::string size = std::to_string(ASRUtils::get_fixed_size_of_array( + ASRUtils::expr_type(x.m_target))); + std::string value; + if (ASR::is_a(*x.m_value)) { + ASR::ArraySection_t *arr = ASR::down_cast(x.m_value); + this->visit_expr(*arr->m_v); + value = src; + if(!ASR::is_a(*arr->m_args->m_left)) { + this->visit_expr(*arr->m_args->m_left); + int n_dims = ASRUtils::extract_n_dims_from_ttype(arr->m_type) - 1; + value += "->data + (" + src + " - "+ value +"->dims[" + + std::to_string(n_dims) +"].lower_bound)"; + } else { + value += "->data"; + } + } else if (ASR::is_a(*x.m_value)) { + this->visit_expr(*x.m_value); + value = src + "->data"; + } + src = indent + "memcpy(&"+ target +", "+ value +", sizeof(" + + arr_element_type + ") * "+ size +");\n"; + return; + } + } else if (ASR::is_a(*x.m_target)) { ASR::Var_t* x_m_target = ASR::down_cast(x.m_target); visit_Var(*x_m_target); target = src; @@ -1398,6 +1429,7 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) { } void visit_Associate(const ASR::Associate_t &x) { + std::string indent(indentation_level*indentation_spaces, ' '); if (ASR::is_a(*x.m_value)) { self().visit_expr(*x.m_target); std::string target = std::move(src); @@ -1422,7 +1454,7 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) { } c += left + ":" + right + ":" + step + ","; } - src = target + "= " + value + "; // TODO: " + value + "(" + c + ")\n"; + src = indent + target + "= " + value + "; // TODO: " + value + "(" + c + ")\n"; } else { throw CodeGenError("Associate only implemented for ArraySection so far"); } diff --git a/src/libasr/pass/array_op.cpp b/src/libasr/pass/array_op.cpp index d3336cee96..0cdb27a569 100644 --- a/src/libasr/pass/array_op.cpp +++ b/src/libasr/pass/array_op.cpp @@ -1586,9 +1586,7 @@ class ArrayOpVisitor : public ASR::CallReplacerOnExpressionsVisitor(*ASRUtils::expr_type(x.m_target)) && - ASR::down_cast(ASRUtils::expr_type(x.m_target))->m_physical_type - == ASR::array_physical_typeType::SIMDArray) { + if (ASRUtils::is_simd_array(x.m_target)) { return; } if( (ASR::is_a(*ASRUtils::expr_type(x.m_target)) && diff --git a/src/libasr/pass/print_arr.cpp b/src/libasr/pass/print_arr.cpp index 2d1a03ea19..2ce1887f16 100644 --- a/src/libasr/pass/print_arr.cpp +++ b/src/libasr/pass/print_arr.cpp @@ -134,7 +134,7 @@ class PrintArrVisitor : public PassUtils::PassVisitor std::vector print_body; ASR::stmt_t* empty_print_endl; ASR::stmt_t* print_stmt; - if (x.m_values[0] != nullptr && ASR::is_a(*x.m_values[0])) { + if (x.n_values > 0 && ASR::is_a(*x.m_values[0])) { empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc, nullptr, 0, nullptr, nullptr)); ASR::StringFormat_t* format = ASR::down_cast(x.m_values[0]);