@@ -594,6 +594,89 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer<ReplaceArrayOp> {
594
594
replace_ArrayOpCommon<ASR::LogicalCompare_t>(x, " _logical_comp_op_res" );
595
595
}
596
596
597
+ void replace_IntrinsicFunction (ASR::IntrinsicFunction_t* x) {
598
+ LCOMPILERS_ASSERT (current_scope != nullptr );
599
+ const Location& loc = x->base .base .loc ;
600
+ std::vector<bool > array_mask (x->n_args , false );
601
+ bool at_least_one_array = false ;
602
+ for ( size_t iarg = 0 ; iarg < x->n_args ; iarg++ ) {
603
+ array_mask[iarg] = ASRUtils::is_array (
604
+ ASRUtils::expr_type (x->m_args [iarg]));
605
+ at_least_one_array = at_least_one_array || array_mask[iarg];
606
+ }
607
+ if (!at_least_one_array) {
608
+ return ;
609
+ }
610
+ std::string res_prefix = " _elemental_func_call_res" ;
611
+ ASR::expr_t * result_var_copy = result_var;
612
+ bool is_all_rank_0 = true ;
613
+ std::vector<ASR::expr_t *> operands;
614
+ ASR::expr_t * operand = nullptr ;
615
+ int common_rank = 0 ;
616
+ bool are_all_rank_same = true ;
617
+ for ( size_t iarg = 0 ; iarg < x->n_args ; iarg++ ) {
618
+ result_var = nullptr ;
619
+ ASR::expr_t ** current_expr_copy_9 = current_expr;
620
+ current_expr = &(x->m_args [iarg]);
621
+ self ().replace_expr (x->m_args [iarg]);
622
+ operand = *current_expr;
623
+ current_expr = current_expr_copy_9;
624
+ operands.push_back (operand);
625
+ int rank_operand = PassUtils::get_rank (operand);
626
+ if ( common_rank == 0 ) {
627
+ common_rank = rank_operand;
628
+ }
629
+ if ( common_rank != rank_operand &&
630
+ rank_operand > 0 ) {
631
+ are_all_rank_same = false ;
632
+ }
633
+ array_mask[iarg] = (rank_operand > 0 );
634
+ is_all_rank_0 = is_all_rank_0 && (rank_operand <= 0 );
635
+ }
636
+ if ( is_all_rank_0 ) {
637
+ return ;
638
+ }
639
+ if ( !are_all_rank_same ) {
640
+ throw LCompilersException (" Broadcasting support not yet available "
641
+ " for different shape arrays." );
642
+ }
643
+ result_var = result_var_copy;
644
+ if ( result_var == nullptr ) {
645
+ result_var = PassUtils::create_var (result_counter, res_prefix,
646
+ loc, operand, al, current_scope);
647
+ result_counter += 1 ;
648
+ }
649
+ *current_expr = result_var;
650
+
651
+ Vec<ASR::expr_t *> idx_vars, loop_vars;
652
+ std::vector<int > loop_var_indices;
653
+ Vec<ASR::stmt_t *> doloop_body;
654
+ create_do_loop (loc, common_rank,
655
+ idx_vars, loop_vars, loop_var_indices, doloop_body,
656
+ [=, &operands, &idx_vars, &doloop_body] () {
657
+ Vec<ASR::expr_t *> ref_args;
658
+ ref_args.reserve (al, x->n_args );
659
+ for ( size_t iarg = 0 ; iarg < x->n_args ; iarg++ ) {
660
+ ASR::expr_t * ref = operands[iarg];
661
+ if ( array_mask[iarg] ) {
662
+ ref = PassUtils::create_array_ref (operands[iarg], idx_vars, al);
663
+ }
664
+ ref_args.push_back (al, ref);
665
+ }
666
+ Vec<ASR::dimension_t > empty_dim;
667
+ empty_dim.reserve (al, 1 );
668
+ ASR::ttype_t * dim_less_type = ASRUtils::duplicate_type (al, x->m_type , &empty_dim);
669
+ ASR::expr_t * op_el_wise = ASRUtils::EXPR (ASR::make_IntrinsicFunction_t (al, loc,
670
+ x->m_intrinsic_id , ref_args.p , ref_args.size (), x->m_overload_id ,
671
+ dim_less_type, nullptr ));
672
+ ASR::expr_t * res = PassUtils::create_array_ref (result_var, idx_vars, al);
673
+ ASR::stmt_t * assign = ASRUtils::STMT (ASR::make_Assignment_t (al, loc, res, op_el_wise, nullptr ));
674
+ doloop_body.push_back (al, assign);
675
+ });
676
+ use_custom_loop_params = false ;
677
+ result_var = nullptr ;
678
+ }
679
+
597
680
void replace_FunctionCall (ASR::FunctionCall_t* x) {
598
681
std::string x_name;
599
682
if ( x->m_name ->type == ASR::symbolType::ExternalSymbol ) {
0 commit comments