From 9145ef2a3272792cb2a3e15d047d29297c6cfaef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 27 Apr 2022 12:12:49 -0600 Subject: [PATCH 01/21] ASR: Split BinOp to Integer/Complex/etc/BinOp --- src/libasr/ASR.asdl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libasr/ASR.asdl b/src/libasr/ASR.asdl index aafe1d2e8f..c3ad92fb6e 100644 --- a/src/libasr/ASR.asdl +++ b/src/libasr/ASR.asdl @@ -208,9 +208,7 @@ stmt expr - = BoolOp(expr left, boolop op, expr right, ttype type, expr? value) - | BinOp(expr left, binop op, expr right, ttype type, expr? value, expr? overloaded) - | StrOp(expr left, strop op, expr right, ttype type, expr? value) + = StrOp(expr left, strop op, expr right, ttype type, expr? value) | UnaryOp(unaryop op, expr operand, ttype type, expr? value) -- Such as: (x, y+z), (3.0, 2.0) generally not known at compile time | ComplexConstructor(expr re, expr im, ttype type, expr? value) @@ -222,10 +220,14 @@ expr | DerivedTypeConstructor(symbol dt_sym, expr* args, ttype type) | ImpliedDoLoop(expr* values, expr var, expr start, expr end, expr? increment, ttype type, expr? value) + | IntegerBinOp(expr left, binop op, expr right, ttype type, expr? value) | IntegerConstant(int n, ttype type) | IntegerBOZ(int v, integerboz intboz_type, ttype? type) + | RealBinOp(expr left, binop op, expr right, ttype type, expr? value) | RealConstant(float r, ttype type) + | ComplexBinOp(expr left, binop op, expr right, ttype type, expr? value) | ComplexConstant(float re, float im, ttype type) + | LogicalBinOp(expr left, logicalbinop op, expr right, ttype type, expr? value) | LogicalConstant(bool value, ttype type) | ListConstant(expr* args, ttype type) @@ -248,6 +250,7 @@ expr | Var(symbol v) | ArrayRef(symbol v, array_index* args, ttype type, expr? value) | ArraySize(expr v, expr? dim, ttype type, expr? value) + | OverloadedBinOp(expr left, binop op, expr right, ttype type, expr? value, expr overloaded) | DerivedRef(expr v, symbol m, ttype type, expr? value) | Cast(expr arg, cast_kind kind, ttype type, expr? value) | ComplexRe(expr arg, ttype type, expr? value) @@ -274,9 +277,9 @@ ttype | Dict(ttype key_type, ttype value_type) | Pointer(ttype type) -boolop = And | Or | Xor | NEqv | Eqv binop = Add | Sub | Mul | Div | Pow +logicalbinop = And | Or | Xor | NEqv | Eqv unaryop = Invert | Not | UAdd | USub From 59fa839714dd870de1346cdceed6bd033d1d066b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 27 Apr 2022 12:21:06 -0600 Subject: [PATCH 02/21] Update the rest of the code --- src/libasr/asr_utils.h | 24 ++++++++++++++---------- src/libasr/codegen/asr_to_cpp.cpp | 25 +++++++++++++++++++------ src/libasr/codegen/asr_to_x86.cpp | 2 +- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/libasr/asr_utils.h b/src/libasr/asr_utils.h index ca4c5ffa8b..4367fc4634 100644 --- a/src/libasr/asr_utils.h +++ b/src/libasr/asr_utils.h @@ -93,8 +93,10 @@ static inline ASR::ttype_t* expr_type(const ASR::expr_t *f) { LFORTRAN_ASSERT(f != nullptr); switch (f->type) { - case ASR::exprType::BoolOp: { return ((ASR::BoolOp_t*)f)->m_type; } - case ASR::exprType::BinOp: { return ((ASR::BinOp_t*)f)->m_type; } + case ASR::exprType::LogicalBinOp: { return ((ASR::LogicalBinOp_t*)f)->m_type; } + case ASR::exprType::IntegerBinOp: { return ((ASR::IntegerBinOp_t*)f)->m_type; } + case ASR::exprType::RealBinOp: { return ((ASR::RealBinOp_t*)f)->m_type; } + case ASR::exprType::ComplexBinOp: { return ((ASR::ComplexBinOp_t*)f)->m_type; } case ASR::exprType::StrOp: { return ((ASR::StrOp_t*)f)->m_type; } case ASR::exprType::UnaryOp: { return ((ASR::UnaryOp_t*)f)->m_type; } case ASR::exprType::ComplexConstructor: { return ((ASR::ComplexConstructor_t*)f)->m_type; } @@ -251,12 +253,12 @@ static inline std::string cmpop_to_str(const ASR::cmpopType t) { } } -static inline std::string boolop_to_str(const ASR::boolopType t) { +static inline std::string boolop_to_str(const ASR::logicalbinopType t) { switch (t) { - case (ASR::boolopType::And): { return " && "; } - case (ASR::boolopType::Or): { return " || "; } - case (ASR::boolopType::Eqv): { return " == "; } - case (ASR::boolopType::NEqv): { return " != "; } + case (ASR::logicalbinopType::And): { return " && "; } + case (ASR::logicalbinopType::Or): { return " || "; } + case (ASR::logicalbinopType::Eqv): { return " == "; } + case (ASR::logicalbinopType::NEqv): { return " != "; } default : throw LFortranException("Cannot represent the boolean operator as a string"); } } @@ -264,8 +266,10 @@ static inline std::string boolop_to_str(const ASR::boolopType t) { static inline ASR::expr_t* expr_value(ASR::expr_t *f) { switch (f->type) { - case ASR::exprType::BoolOp: { return ASR::down_cast(f)->m_value; } - case ASR::exprType::BinOp: { return ASR::down_cast(f)->m_value; } + case ASR::exprType::LogicalBinOp: { return ASR::down_cast(f)->m_value; } + case ASR::exprType::IntegerBinOp: { return ASR::down_cast(f)->m_value; } + case ASR::exprType::RealBinOp: { return ASR::down_cast(f)->m_value; } + case ASR::exprType::ComplexBinOp: { return ASR::down_cast(f)->m_value; } case ASR::exprType::UnaryOp: { return ASR::down_cast(f)->m_value; } case ASR::exprType::ComplexConstructor: { return ASR::down_cast(f)->m_value; } case ASR::exprType::Compare: { return ASR::down_cast(f)->m_value; } @@ -1012,7 +1016,7 @@ inline bool is_same_type_pointer(ASR::ttype_t* source, ASR::ttype_t* dest) { a_len = -3; break; } - case ASR::exprType::BinOp: { + case ASR::exprType::IntegerBinOp: { a_len = -3; break; } diff --git a/src/libasr/codegen/asr_to_cpp.cpp b/src/libasr/codegen/asr_to_cpp.cpp index 9abbd1d34f..a3ec49d0c6 100644 --- a/src/libasr/codegen/asr_to_cpp.cpp +++ b/src/libasr/codegen/asr_to_cpp.cpp @@ -781,7 +781,20 @@ Kokkos::View from_std_vector(const std::vector &v) } } - void visit_BinOp(const ASR::BinOp_t &x) { + void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) { + handle_BinOp(x); + } + + void visit_RealBinOp(const ASR::RealBinOp_t &x) { + handle_BinOp(x); + } + + void visit_ComplexBinOp(const ASR::ComplexBinOp_t &x) { + handle_BinOp(x); + } + + template + void handle_BinOp(const T &x) { this->visit_expr(*x.m_left); std::string left = std::move(src); int left_precedence = last_expr_precedence; @@ -848,7 +861,7 @@ Kokkos::View from_std_vector(const std::vector &v) } } - void visit_BoolOp(const ASR::BoolOp_t &x) { + void visit_LogicalBinOp(const ASR::LogicalBinOp_t &x) { this->visit_expr(*x.m_left); std::string left = std::move(src); int left_precedence = last_expr_precedence; @@ -856,19 +869,19 @@ Kokkos::View from_std_vector(const std::vector &v) std::string right = std::move(src); int right_precedence = last_expr_precedence; switch (x.m_op) { - case (ASR::boolopType::And): { + case (ASR::logicalbinopType::And): { last_expr_precedence = 14; break; } - case (ASR::boolopType::Or): { + case (ASR::logicalbinopType::Or): { last_expr_precedence = 15; break; } - case (ASR::boolopType::NEqv): { + case (ASR::logicalbinopType::NEqv): { last_expr_precedence = 10; break; } - case (ASR::boolopType::Eqv): { + case (ASR::logicalbinopType::Eqv): { last_expr_precedence = 10; break; } diff --git a/src/libasr/codegen/asr_to_x86.cpp b/src/libasr/codegen/asr_to_x86.cpp index ad8f5c5024..b20894eebe 100644 --- a/src/libasr/codegen/asr_to_x86.cpp +++ b/src/libasr/codegen/asr_to_x86.cpp @@ -302,7 +302,7 @@ class ASRToX86Visitor : public ASR::BaseVisitor } } - void visit_BinOp(const ASR::BinOp_t &x) { + void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) { this->visit_expr(*x.m_right); m_a.asm_push_r32(X86Reg::eax); this->visit_expr(*x.m_left); From a31db8cca4b559cb8d12e429b2b116bae512e60e Mon Sep 17 00:00:00 2001 From: Naman Gera Date: Wed, 18 May 2022 13:50:34 +0530 Subject: [PATCH 03/21] Change all occurences of `boolop` to `logicalbinop` --- src/libasr/asr_utils.h | 2 +- src/libasr/codegen/asr_to_cpp.cpp | 2 +- src/libasr/codegen/asr_to_llvm.cpp | 12 ++++++------ src/libasr/pass/array_op.cpp | 12 ++++++------ src/lpython/semantics/python_ast_to_asr.cpp | 12 ++++++------ 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/libasr/asr_utils.h b/src/libasr/asr_utils.h index 3873c74495..5bf172c300 100644 --- a/src/libasr/asr_utils.h +++ b/src/libasr/asr_utils.h @@ -274,7 +274,7 @@ static inline std::string cmpop_to_str(const ASR::cmpopType t) { } } -static inline std::string boolop_to_str(const ASR::logicalbinopType t) { +static inline std::string logicalbinop_to_str(const ASR::logicalbinopType t) { switch (t) { case (ASR::logicalbinopType::And): { return " && "; } case (ASR::logicalbinopType::Or): { return " || "; } diff --git a/src/libasr/codegen/asr_to_cpp.cpp b/src/libasr/codegen/asr_to_cpp.cpp index 76dbbedd7a..43ac245dc0 100644 --- a/src/libasr/codegen/asr_to_cpp.cpp +++ b/src/libasr/codegen/asr_to_cpp.cpp @@ -927,7 +927,7 @@ Kokkos::View from_std_vector(const std::vector &v) } else { src += "(" + left + ")"; } - src += ASRUtils::boolop_to_str(x.m_op); + src += ASRUtils::logicalbinop_to_str(x.m_op); if (right_precedence <= last_expr_precedence) { src += right; } else { diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 4060b59821..8602cef8de 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -2878,7 +2878,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor start_new_block(target); } - void visit_BoolOp(const ASR::BoolOp_t &x) { + void visit_LogicalBinOp(const ASR::LogicalBinOp_t &x) { if (x.m_value) { this->visit_expr_wrapper(x.m_value, true); return; @@ -2889,23 +2889,23 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm::Value *right_val = tmp; if (x.m_type->type == ASR::ttypeType::Logical) { switch (x.m_op) { - case ASR::boolopType::And: { + case ASR::logicalbinopType::And: { tmp = builder->CreateAnd(left_val, right_val); break; }; - case ASR::boolopType::Or: { + case ASR::logicalbinopType::Or: { tmp = builder->CreateOr(left_val, right_val); break; }; - case ASR::boolopType::Xor: { + case ASR::logicalbinopType::Xor: { tmp = builder->CreateXor(left_val, right_val); break; }; - case ASR::boolopType::NEqv: { + case ASR::logicalbinopType::NEqv: { tmp = builder->CreateXor(left_val, right_val); break; }; - case ASR::boolopType::Eqv: { + case ASR::logicalbinopType::Eqv: { tmp = builder->CreateXor(left_val, right_val); tmp = builder->CreateNot(tmp); }; diff --git a/src/libasr/pass/array_op.cpp b/src/libasr/pass/array_op.cpp index 3d66c14d17..f66bd23111 100644 --- a/src/libasr/pass/array_op.cpp +++ b/src/libasr/pass/array_op.cpp @@ -541,10 +541,10 @@ class ArrayOpVisitor : public PassUtils::PassVisitor al, x.base.base.loc, ref_1, (ASR::cmpopType)x.m_op, ref_2, x.m_type, nullptr, nullptr)); break; - case ASR::exprType::BoolOp: - op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_BoolOp_t( + case ASR::exprType::LogicalBinOp: + op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_LogicalBinOp_t( al, x.base.base.loc, - ref_1, (ASR::boolopType)x.m_op, ref_2, x.m_type, nullptr)); + ref_1, (ASR::logicalbinopType)x.m_op, ref_2, x.m_type, nullptr)); break; default: throw LFortranException("The desired operation is not supported yet for arrays."); @@ -624,10 +624,10 @@ class ArrayOpVisitor : public PassUtils::PassVisitor al, x.base.base.loc, ref, (ASR::cmpopType)x.m_op, other_expr, x.m_type, nullptr, nullptr)); break; - case ASR::exprType::BoolOp: - op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_BoolOp_t( + case ASR::exprType::LogicalBinOp: + op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_LogicalBinOp_t( al, x.base.base.loc, - ref, (ASR::boolopType)x.m_op, other_expr, x.m_type, nullptr)); + ref, (ASR::logicalbinopType)x.m_op, other_expr, x.m_type, nullptr)); break; default: throw LFortranException("The desired operation is not supported yet for arrays."); diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 70d8fbeffe..48554c9273 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -1237,7 +1237,7 @@ class CommonVisitor : public AST::BaseVisitor { } void visit_BoolOp(const AST::BoolOp_t &x) { - ASR::boolopType op; + ASR::logicalbinopType op; if (x.n_values > 2) { throw SemanticError("Only two operands supported for boolean operations", x.base.base.loc); @@ -1247,8 +1247,8 @@ class CommonVisitor : public AST::BaseVisitor { this->visit_expr(*x.m_values[1]); ASR::expr_t *rhs = ASRUtils::EXPR(tmp); switch (x.m_op) { - case (AST::boolopType::And): { op = ASR::boolopType::And; break; } - case (AST::boolopType::Or): { op = ASR::boolopType::Or; break; } + case (AST::boolopType::And): { op = ASR::logicalbinopType::And; break; } + case (AST::boolopType::Or): { op = ASR::logicalbinopType::Or; break; } default : { throw SemanticError("Boolean operator type not supported", x.base.base.loc); @@ -1268,8 +1268,8 @@ class CommonVisitor : public AST::BaseVisitor { ASRUtils::expr_value(rhs))->m_value; bool result; switch (op) { - case (ASR::boolopType::And): { result = left_value && right_value; break; } - case (ASR::boolopType::Or): { result = left_value || right_value; break; } + case (ASR::logicalbinopType::And): { result = left_value && right_value; break; } + case (ASR::logicalbinopType::Or): { result = left_value || right_value; break; } default : { throw SemanticError("Boolean operator type not supported", x.base.base.loc); @@ -1278,7 +1278,7 @@ class CommonVisitor : public AST::BaseVisitor { value = ASR::down_cast(ASR::make_LogicalConstant_t( al, x.base.base.loc, result, dest_type)); } - tmp = ASR::make_BoolOp_t(al, x.base.base.loc, lhs, op, rhs, dest_type, value); + tmp = ASR::make_LogicalBinOp_t(al, x.base.base.loc, lhs, op, rhs, dest_type, value); } void visit_BinOp(const AST::BinOp_t &x) { From f5f7e195824ec08d293208370da918cc80dbb272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 25 May 2022 11:30:44 -0600 Subject: [PATCH 04/21] Update wasm --- src/libasr/codegen/asr_to_wasm.cpp | 46 ++++++++++++++---------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/src/libasr/codegen/asr_to_wasm.cpp b/src/libasr/codegen/asr_to_wasm.cpp index 5cbbb974c8..9b14f3f1d4 100644 --- a/src/libasr/codegen/asr_to_wasm.cpp +++ b/src/libasr/codegen/asr_to_wasm.cpp @@ -175,35 +175,31 @@ class ASRToWASMVisitor : public ASR::BaseVisitor { } } - void visit_BinOp(const ASR::BinOp_t &x) { + void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) { this->visit_expr(*x.m_left); this->visit_expr(*x.m_right); - if (ASRUtils::is_integer(*x.m_type)) { - switch (x.m_op) { - case ASR::binopType::Add: { - wasm::emit_i32_add(m_code_section, m_al); - break; - }; - case ASR::binopType::Sub: { - wasm::emit_i32_sub(m_code_section, m_al); - break; - }; - case ASR::binopType::Mul: { - wasm::emit_i32_mul(m_code_section, m_al); - break; - }; - case ASR::binopType::Div: { - wasm::emit_i32_div(m_code_section, m_al); - break; - }; - default: - throw CodeGenError( - "Binop: Pow Operation not yet implemented"); - } - } else { - throw CodeGenError("Binop: Only Integer type implemented"); + switch (x.m_op) { + case ASR::binopType::Add: { + wasm::emit_i32_add(m_code_section, m_al); + break; + }; + case ASR::binopType::Sub: { + wasm::emit_i32_sub(m_code_section, m_al); + break; + }; + case ASR::binopType::Mul: { + wasm::emit_i32_mul(m_code_section, m_al); + break; + }; + case ASR::binopType::Div: { + wasm::emit_i32_div(m_code_section, m_al); + break; + }; + default: + throw CodeGenError( + "Binop: Pow Operation not yet implemented"); } } From 113d7bc0d59cac3c2fc481539e0c0e222798b415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 25 May 2022 11:46:30 -0600 Subject: [PATCH 05/21] Create create_binop_add() --- src/libasr/asr_utils.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libasr/asr_utils.h b/src/libasr/asr_utils.h index 5bf172c300..adef64ac5e 100644 --- a/src/libasr/asr_utils.h +++ b/src/libasr/asr_utils.h @@ -1139,6 +1139,22 @@ ASR::asr_t* symbol_resolve_external_generic_procedure_without_eval( ASR::asr_t* make_Cast_t_value(Allocator &al, const Location &a_loc, ASR::expr_t* a_arg, ASR::cast_kindType a_kind, ASR::ttype_t* a_type); +ASR::expr_t* create_binop_add(Allocator &al, const Location &loc, ASR::expr_t* left, ASR::expr_t* right) { + LFORTRAN_ASSERT(expr_type(left) == expr_type(right)) + ASR::ttype_t* type = expr_type(left); + // TODO: compute `value`: + if (is_integer(*type)) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Add, right, type, nullptr)); + } else if (is_real(*type)) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Add, right, type, nullptr)); + } else if (is_complex(*type)) { + return EXPR(ASR::make_ComplexBinOp_t(al, loc, left, ASR::binopType::Add, right, type, nullptr)); + } else { + LFORTRAN_ASSERT(false); + return nullptr; + } +} + } // namespace ASRUtils } // namespace LFortran From 25ce2f71367c09215421e5bda77e0a39d9f556cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 25 May 2022 11:47:30 -0600 Subject: [PATCH 06/21] Update param_to_const --- src/libasr/pass/param_to_const.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/libasr/pass/param_to_const.cpp b/src/libasr/pass/param_to_const.cpp index 28bab387f0..847fd64d9c 100644 --- a/src/libasr/pass/param_to_const.cpp +++ b/src/libasr/pass/param_to_const.cpp @@ -74,8 +74,9 @@ class VarVisitor : public ASR::BaseWalkVisitor asr = const_cast(&(x.base)); } - void visit_BinOp(const ASR::BinOp_t& x) { - ASR::BinOp_t& x_unconst = const_cast(x); + template + void visit_BinOp(const T& x) { + T& x_unconst = const_cast(x); asr = nullptr; this->visit_expr(*x.m_left); if( asr != nullptr ) { @@ -89,6 +90,19 @@ class VarVisitor : public ASR::BaseWalkVisitor asr = const_cast(&(x.base)); } + void visit_IntegerBinOp(const ASR::IntegerBinOp_t& x) { + visit_BinOp(x); + } + void visit_RealBinOp(const ASR::RealBinOp_t& x) { + visit_BinOp(x); + } + void visit_ComplexBinOp(const ASR::ComplexBinOp_t& x) { + visit_BinOp(x); + } + void visit_LogicalBinOp(const ASR::LogicalBinOp_t& x) { + visit_BinOp(x); + } + void visit_Cast(const ASR::Cast_t& x) { /* asr = nullptr; From 697e20b313d197ac99083f93cca1a6764b4e3f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 25 May 2022 11:47:40 -0600 Subject: [PATCH 07/21] Update select_case --- src/libasr/pass/select_case.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libasr/pass/select_case.cpp b/src/libasr/pass/select_case.cpp index ec06ecf599..7dd4213a83 100644 --- a/src/libasr/pass/select_case.cpp +++ b/src/libasr/pass/select_case.cpp @@ -53,16 +53,16 @@ inline ASR::expr_t* gen_test_expr_CaseStmt(Allocator& al, const Location& loc, A if( Case_Stmt->n_test == 1 ) { test_expr = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::Eq, Case_Stmt->m_test[0], LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); } else if( Case_Stmt->n_test == 2 ) { - ASR::expr_t* left = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::Eq, Case_Stmt->m_test[0], LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); - ASR::expr_t* right = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::Eq, Case_Stmt->m_test[1], LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); - test_expr = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, loc, left, ASR::binopType::Add, right, LFortran::ASRUtils::expr_type(left), nullptr, nullptr)); + ASR::expr_t* left = ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::Eq, Case_Stmt->m_test[0], LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); + ASR::expr_t* right = ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::Eq, Case_Stmt->m_test[1], LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); + test_expr = ASRUtils::create_binop_add(al, loc, left, right); } else { ASR::expr_t* left = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::Eq, Case_Stmt->m_test[0], LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); ASR::expr_t* right = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::Eq, Case_Stmt->m_test[1], LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); - test_expr = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, loc, left, ASR::binopType::Add, right, LFortran::ASRUtils::expr_type(left), nullptr, nullptr)); + test_expr = ASRUtils::create_binop_add(al, loc, left, right); for( std::uint32_t j = 2; j < Case_Stmt->n_test; j++ ) { ASR::expr_t* newExpr = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::Eq, Case_Stmt->m_test[j], LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); - test_expr = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, loc, test_expr, ASR::binopType::Add, newExpr, LFortran::ASRUtils::expr_type(newExpr), nullptr, nullptr)); + test_expr = ASRUtils::create_binop_add(al, loc, test_expr, newExpr); } } return test_expr; @@ -77,7 +77,7 @@ inline ASR::expr_t* gen_test_expr_CaseStmt_Range(Allocator& al, const Location& } else if( Case_Stmt->m_start != nullptr && Case_Stmt->m_end != nullptr ) { ASR::expr_t* left = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, Case_Stmt->m_start, ASR::cmpopType::LtE, a_test, LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); ASR::expr_t* right = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::LtE, Case_Stmt->m_end, LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); - test_expr = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, loc, left, ASR::binopType::Mul, right, LFortran::ASRUtils::expr_type(left), nullptr, nullptr)); + test_expr = ASRUtils::create_binop_add(al, loc, left, right); } return test_expr; } From d39c71544352622c5b872ead79ebc4102ce56086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 25 May 2022 11:51:25 -0600 Subject: [PATCH 08/21] Update implied_do_loops --- src/libasr/pass/implied_do_loops.cpp | 30 ++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/libasr/pass/implied_do_loops.cpp b/src/libasr/pass/implied_do_loops.cpp index 4047600d38..15a7fb6473 100644 --- a/src/libasr/pass/implied_do_loops.cpp +++ b/src/libasr/pass/implied_do_loops.cpp @@ -62,7 +62,8 @@ class ImpliedDoLoopVisitor : public PassUtils::PassVisitor contains_array = false; } - void visit_BinOp(const ASR::BinOp_t& x) { + template + void visit_BinOp(const T& x) { if( contains_array ) { return ; } @@ -74,6 +75,19 @@ class ImpliedDoLoopVisitor : public PassUtils::PassVisitor contains_array = left_array || right_array; } + void visit_IntegerBinOp(const ASR::IntegerBinOp_t& x) { + visit_BinOp(x); + } + void visit_RealBinOp(const ASR::RealBinOp_t& x) { + visit_BinOp(x); + } + void visit_ComplexBinOp(const ASR::ComplexBinOp_t& x) { + visit_BinOp(x); + } + void visit_LogicalBinOp(const ASR::LogicalBinOp_t& x) { + visit_BinOp(x); + } + void create_do_loop(ASR::ImpliedDoLoop_t* idoloop, ASR::Var_t* arr_var, ASR::expr_t* arr_idx=nullptr) { ASR::do_loop_head_t head; head.m_v = idoloop->m_var; @@ -90,9 +104,9 @@ class ImpliedDoLoopVisitor : public PassUtils::PassVisitor const_n = offset = num_grps = grp_start = nullptr; if( arr_idx == nullptr ) { const_n = LFortran::ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, arr_var->base.base.loc, idoloop->n_values, _type)); - offset = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, arr_var->base.base.loc, idoloop->m_var, ASR::binopType::Sub, idoloop->m_start, _type, nullptr, nullptr)); - num_grps = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, arr_var->base.base.loc, offset, ASR::binopType::Mul, const_n, _type, nullptr, nullptr)); - grp_start = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, arr_var->base.base.loc, num_grps, ASR::binopType::Add, const_1, _type, nullptr, nullptr)); + offset = LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, arr_var->base.base.loc, idoloop->m_var, ASR::binopType::Sub, idoloop->m_start, _type, nullptr)); + num_grps = LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, arr_var->base.base.loc, offset, ASR::binopType::Mul, const_n, _type, nullptr)); + grp_start = LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, arr_var->base.base.loc, num_grps, ASR::binopType::Add, const_1, _type, nullptr)); } for( size_t i = 0; i < idoloop->n_values; i++ ) { Vec args; @@ -101,9 +115,9 @@ class ImpliedDoLoopVisitor : public PassUtils::PassVisitor ai.m_left = nullptr; if( arr_idx == nullptr ) { ASR::expr_t* const_i = LFortran::ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, arr_var->base.base.loc, i, _type)); - ASR::expr_t* idx = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, arr_var->base.base.loc, + ASR::expr_t* idx = LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, arr_var->base.base.loc, grp_start, ASR::binopType::Add, const_i, - _type, nullptr, nullptr)); + _type, nullptr)); ai.m_right = idx; } else { ai.m_right = arr_idx; @@ -120,7 +134,7 @@ class ImpliedDoLoopVisitor : public PassUtils::PassVisitor ASR::stmt_t* doloop_stmt = LFortran::ASRUtils::STMT(ASR::make_Assignment_t(al, arr_var->base.base.loc, array_ref, idoloop->m_values[i], nullptr)); doloop_body.push_back(al, doloop_stmt); if( arr_idx != nullptr ) { - ASR::expr_t* increment = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, arr_var->base.base.loc, arr_idx, ASR::binopType::Add, const_1, LFortran::ASRUtils::expr_type(arr_idx), nullptr, nullptr)); + ASR::expr_t* increment = LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, arr_var->base.base.loc, arr_idx, ASR::binopType::Add, const_1, LFortran::ASRUtils::expr_type(arr_idx), nullptr)); ASR::stmt_t* assign_stmt = LFortran::ASRUtils::STMT(ASR::make_Assignment_t(al, arr_var->base.base.loc, arr_idx, increment, nullptr)); doloop_body.push_back(al, assign_stmt); } @@ -176,7 +190,7 @@ class ImpliedDoLoopVisitor : public PassUtils::PassVisitor LFortran::ASRUtils::expr_type(LFortran::ASRUtils::EXPR((ASR::asr_t*)arr_var)), nullptr)); ASR::stmt_t* assign_stmt = LFortran::ASRUtils::STMT(ASR::make_Assignment_t(al, arr_var->base.base.loc, array_ref, arr_init->m_args[k], nullptr)); pass_result.push_back(al, assign_stmt); - ASR::expr_t* increment = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, arr_var->base.base.loc, idx_var, ASR::binopType::Add, const_1, LFortran::ASRUtils::expr_type(idx_var), nullptr, nullptr)); + ASR::expr_t* increment = LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, arr_var->base.base.loc, idx_var, ASR::binopType::Add, const_1, LFortran::ASRUtils::expr_type(idx_var), nullptr)); assign_stmt = LFortran::ASRUtils::STMT(ASR::make_Assignment_t(al, arr_var->base.base.loc, idx_var, increment, nullptr)); pass_result.push_back(al, assign_stmt); } From 7629bb2ba2691626fb07d5b71259a1bab9fe2344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 25 May 2022 11:57:38 -0600 Subject: [PATCH 09/21] Update array_op --- src/libasr/pass/array_op.cpp | 62 ++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/src/libasr/pass/array_op.cpp b/src/libasr/pass/array_op.cpp index f66bd23111..86b5ca025b 100644 --- a/src/libasr/pass/array_op.cpp +++ b/src/libasr/pass/array_op.cpp @@ -530,11 +530,23 @@ class ArrayOpVisitor : public PassUtils::PassVisitor ASR::expr_t* res = PassUtils::create_array_ref(result_var, idx_vars, al); ASR::expr_t* op_el_wise = nullptr; switch( x.class_type ) { - case ASR::exprType::BinOp: - op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t( + case ASR::exprType::IntegerBinOp: + op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t( al, x.base.base.loc, ref_1, (ASR::binopType)x.m_op, ref_2, - x.m_type, nullptr, nullptr)); + x.m_type, nullptr)); + break; + case ASR::exprType::RealBinOp: + op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_RealBinOp_t( + al, x.base.base.loc, + ref_1, (ASR::binopType)x.m_op, ref_2, + x.m_type, nullptr)); + break; + case ASR::exprType::ComplexBinOp: + op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_ComplexBinOp_t( + al, x.base.base.loc, + ref_1, (ASR::binopType)x.m_op, ref_2, + x.m_type, nullptr)); break; case ASR::exprType::Compare: op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_Compare_t( @@ -556,9 +568,7 @@ class ArrayOpVisitor : public PassUtils::PassVisitor doloop_body.push_back(al, set_to_one); doloop_body.push_back(al, doloop); } - ASR::expr_t* inc_expr = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, x.base.base.loc, idx_vars_value[i], - ASR::binopType::Add, const_1, int32_type, - nullptr, nullptr)); + ASR::expr_t* inc_expr = ASRUtils::create_binop_add(al, x.base.base.loc, idx_vars_value[i], const_1); ASR::stmt_t* assign_stmt = LFortran::ASRUtils::STMT(ASR::make_Assignment_t(al, x.base.base.loc, idx_vars_value[i], inc_expr, nullptr)); doloop_body.push_back(al, assign_stmt); doloop = LFortran::ASRUtils::STMT(ASR::make_DoLoop_t(al, x.base.base.loc, head, doloop_body.p, doloop_body.size())); @@ -613,11 +623,23 @@ class ArrayOpVisitor : public PassUtils::PassVisitor ASR::expr_t* res = PassUtils::create_array_ref(result_var, idx_vars, al); ASR::expr_t* op_el_wise = nullptr; switch( x.class_type ) { - case ASR::exprType::BinOp: - op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t( + case ASR::exprType::IntegerBinOp: + op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t( + al, x.base.base.loc, + ref, (ASR::binopType)x.m_op, other_expr, + x.m_type, nullptr)); + break; + case ASR::exprType::RealBinOp: + op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_RealBinOp_t( + al, x.base.base.loc, + ref, (ASR::binopType)x.m_op, other_expr, + x.m_type, nullptr)); + break; + case ASR::exprType::ComplexBinOp: + op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_ComplexBinOp_t( al, x.base.base.loc, ref, (ASR::binopType)x.m_op, other_expr, - x.m_type, nullptr, nullptr)); + x.m_type, nullptr)); break; case ASR::exprType::Compare: op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_Compare_t( @@ -639,7 +661,7 @@ class ArrayOpVisitor : public PassUtils::PassVisitor doloop_body.push_back(al, set_to_one); doloop_body.push_back(al, doloop); } - ASR::expr_t* inc_expr = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, x.base.base.loc, idx_vars_value[i], ASR::binopType::Add, const_1, int32_type, nullptr, nullptr)); + ASR::expr_t* inc_expr = ASRUtils::create_binop_add(al, x.base.base.loc, idx_vars_value[i], const_1); ASR::stmt_t* assign_stmt = LFortran::ASRUtils::STMT(ASR::make_Assignment_t(al, x.base.base.loc, idx_vars_value[i], inc_expr, nullptr)); doloop_body.push_back(al, assign_stmt); doloop = LFortran::ASRUtils::STMT(ASR::make_DoLoop_t(al, x.base.base.loc, head, doloop_body.p, doloop_body.size())); @@ -650,16 +672,24 @@ class ArrayOpVisitor : public PassUtils::PassVisitor } } - void visit_BinOp(const ASR::BinOp_t &x) { - visit_ArrayOpCommon(x, "_bin_op_res"); + void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) { + visit_ArrayOpCommon(x, "_bin_op_res"); } - void visit_Compare(const ASR::Compare_t &x) { - visit_ArrayOpCommon(x, "_comp_op_res"); + void visit_RealBinOp(const ASR::RealBinOp_t &x) { + visit_ArrayOpCommon(x, "_bin_op_res"); + } + + void visit_ComplexBinOp(const ASR::ComplexBinOp_t &x) { + visit_ArrayOpCommon(x, "_bin_op_res"); + } + + void visit_LogicalBinOp(const ASR::LogicalBinOp_t &x) { + visit_ArrayOpCommon(x, "_bool_op_res"); } - void visit_BoolOp(const ASR::BoolOp_t &x) { - visit_ArrayOpCommon(x, "_bool_op_res"); + void visit_Compare(const ASR::Compare_t &x) { + visit_ArrayOpCommon(x, "_comp_op_res"); } void visit_ArraySize(const ASR::ArraySize_t& x) { From c75d04d611bed474dc69c3c2825dd160ce9207fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 25 May 2022 12:01:59 -0600 Subject: [PATCH 10/21] Update arr_slice --- src/libasr/pass/arr_slice.cpp | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/libasr/pass/arr_slice.cpp b/src/libasr/pass/arr_slice.cpp index c58ccac9e0..b9df99215f 100644 --- a/src/libasr/pass/arr_slice.cpp +++ b/src/libasr/pass/arr_slice.cpp @@ -83,18 +83,15 @@ class ArrSliceVisitor : public PassUtils::PassVisitor end = PassUtils::to_int32(end, int32_type, al); step = PassUtils::to_int32(step, int32_type, al); - ASR::expr_t* gap = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, x.base.base.loc, + ASR::expr_t* gap = LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, x.base.base.loc, end, ASR::binopType::Sub, start, - int32_type, nullptr, nullptr)); - // ASR::expr_t* slice_size = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, x.base.base.loc, - // gap, ASR::binopType::Add, const_1, - // int64_type, nullptr)); - ASR::expr_t* slice_size = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, x.base.base.loc, + int32_type, nullptr)); + ASR::expr_t* slice_size = LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, x.base.base.loc, gap, ASR::binopType::Div, step, - int32_type, nullptr, nullptr)); - ASR::expr_t* actual_size = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, x.base.base.loc, + int32_type, nullptr)); + ASR::expr_t* actual_size = LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, x.base.base.loc, slice_size, ASR::binopType::Add, const_1, - int32_type, nullptr, nullptr)); + int32_type, nullptr)); ASR::dimension_t curr_dim; curr_dim.loc = x.base.base.loc; curr_dim.m_start = const_1; @@ -205,7 +202,7 @@ class ArrSliceVisitor : public PassUtils::PassVisitor doloop_body.push_back(al, set_to_one); doloop_body.push_back(al, doloop); } - ASR::expr_t* inc_expr = LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, x.base.base.loc, idx_vars_target[i], ASR::binopType::Add, const_1, int32_type, nullptr, nullptr)); + ASR::expr_t* inc_expr = LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, x.base.base.loc, idx_vars_target[i], ASR::binopType::Add, const_1, int32_type, nullptr)); ASR::stmt_t* assign_stmt = LFortran::ASRUtils::STMT(ASR::make_Assignment_t(al, x.base.base.loc, idx_vars_target[i], inc_expr, nullptr)); doloop_body.push_back(al, assign_stmt); doloop = LFortran::ASRUtils::STMT(ASR::make_DoLoop_t(al, x.base.base.loc, head, doloop_body.p, doloop_body.size())); @@ -226,8 +223,9 @@ class ArrSliceVisitor : public PassUtils::PassVisitor } } - void visit_BinOp(const ASR::BinOp_t& x) { - ASR::BinOp_t& xx = const_cast(x); + template + void visit_BinOp(const T& x) { + T& xx = const_cast(x); create_slice_var = true; slice_var = nullptr; this->visit_expr(*x.m_left); @@ -243,6 +241,19 @@ class ArrSliceVisitor : public PassUtils::PassVisitor create_slice_var = false; } + void visit_IntegerBinOp(const ASR::IntegerBinOp_t& x) { + visit_BinOp(x); + } + void visit_RealBinOp(const ASR::RealBinOp_t& x) { + visit_BinOp(x); + } + void visit_ComplexBinOp(const ASR::ComplexBinOp_t& x) { + visit_BinOp(x); + } + void visit_LogicalBinOp(const ASR::LogicalBinOp_t& x) { + visit_BinOp(x); + } + void visit_Print(const ASR::Print_t& x) { ASR::Print_t& xx = const_cast(x); for( size_t i = 0; i < xx.n_values; i++ ) { From bafe186aab261a276daee893133032815e834a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 25 May 2022 12:02:46 -0600 Subject: [PATCH 11/21] Update pass_utils --- src/libasr/pass/pass_utils.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libasr/pass/pass_utils.cpp b/src/libasr/pass/pass_utils.cpp index 292043197e..5c5a769a0d 100644 --- a/src/libasr/pass/pass_utils.cpp +++ b/src/libasr/pass/pass_utils.cpp @@ -517,15 +517,15 @@ namespace LFortran { ASR::expr_t *target = loop.m_head.m_v; ASR::ttype_t *type = LFortran::ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4, nullptr, 0)); stmt1 = LFortran::ASRUtils::STMT(ASR::make_Assignment_t(al, loc, target, - LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, loc, a, ASR::binopType::Sub, c, type, nullptr, nullptr)), + LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc, a, ASR::binopType::Sub, c, type, nullptr)), nullptr)); cond = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, - LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, loc, target, ASR::binopType::Add, c, type, nullptr, nullptr)), + LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc, target, ASR::binopType::Add, c, type, nullptr)), cmp_op, b, type, nullptr, nullptr)); inc_stmt = LFortran::ASRUtils::STMT(ASR::make_Assignment_t(al, loc, target, - LFortran::ASRUtils::EXPR(ASR::make_BinOp_t(al, loc, target, ASR::binopType::Add, c, type, nullptr, nullptr)), + LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc, target, ASR::binopType::Add, c, type, nullptr)), nullptr)); } Vec body; From 36e586a87e64d6febd80e21ad7cef98ef1ce071c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 25 May 2022 12:03:45 -0600 Subject: [PATCH 12/21] Update div_to_mul --- src/libasr/pass/div_to_mul.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libasr/pass/div_to_mul.cpp b/src/libasr/pass/div_to_mul.cpp index 0833e18a00..a4cfeccb0e 100644 --- a/src/libasr/pass/div_to_mul.cpp +++ b/src/libasr/pass/div_to_mul.cpp @@ -46,7 +46,7 @@ class DivToMulVisitor : public PassUtils::PassVisitor pass_result.reserve(al, 1); } - void visit_BinOp(const ASR::BinOp_t& x) { + void visit_RealBinOp(const ASR::RealBinOp_t& x) { visit_expr(*x.m_left); visit_expr(*x.m_right); if( x.m_op == ASR::binopType::Div ) { @@ -66,7 +66,7 @@ class DivToMulVisitor : public PassUtils::PassVisitor break; } if( is_feasible ) { - ASR::BinOp_t& xx = const_cast(x); + ASR::RealBinOp_t& xx = const_cast(x); xx.m_op = ASR::binopType::Mul; xx.m_right = right_inverse; } From 6c264089f041b60f970805d658e03fb1bd022ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 25 May 2022 12:10:48 -0600 Subject: [PATCH 13/21] Update fma --- src/libasr/pass/fma.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/libasr/pass/fma.cpp b/src/libasr/pass/fma.cpp index bffc9b790f..c2127e93c6 100644 --- a/src/libasr/pass/fma.cpp +++ b/src/libasr/pass/fma.cpp @@ -53,23 +53,25 @@ class FMAVisitor : public PassUtils::SkipOptimizationFunctionVisitor } bool is_BinOpMul(ASR::expr_t* expr) { - if( expr->type == ASR::exprType::BinOp ) { - ASR::BinOp_t* expr_binop = ASR::down_cast(expr); + if (ASR::is_a(*expr)) { + ASR::RealBinOp_t* expr_binop = ASR::down_cast(expr); return expr_binop->m_op == ASR::binopType::Mul; } return false; } - void visit_BinOp(const ASR::BinOp_t& x_const) { + void visit_IntegerBinOp(const ASR::IntegerBinOp_t& /*x*/) { } + void visit_ComplexBinOp(const ASR::ComplexBinOp_t& /*x*/) { } + void visit_LogicalBinOp(const ASR::LogicalBinOp_t& /*x*/) { } + + void visit_RealBinOp(const ASR::RealBinOp_t& x_const) { if( !from_fma ) { return ; } from_fma = true; - if( x_const.m_type->type != ASR::ttypeType::Real ) { - return ; - } - ASR::BinOp_t& x = const_cast(x_const); + LFORTRAN_ASSERT(ASRUtils::is_real(*x_const.m_type)) + ASR::RealBinOp_t& x = const_cast(x_const); fma_var = nullptr; visit_expr(*x.m_left); @@ -107,7 +109,7 @@ class FMAVisitor : public PassUtils::SkipOptimizationFunctionVisitor nullptr)); } - ASR::BinOp_t* mul_binop = ASR::down_cast(mul_expr); + ASR::RealBinOp_t* mul_binop = ASR::down_cast(mul_expr); ASR::expr_t *first_arg = mul_binop->m_left, *second_arg = mul_binop->m_right; if( is_mul_expr_negative ) { From 381b54e5d4f7b4364b9fc3d24c3c7b887d048397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 25 May 2022 12:14:37 -0600 Subject: [PATCH 14/21] Update sign_from_value --- src/libasr/pass/sign_from_value.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libasr/pass/sign_from_value.cpp b/src/libasr/pass/sign_from_value.cpp index a21b2876a7..414653c4ca 100644 --- a/src/libasr/pass/sign_from_value.cpp +++ b/src/libasr/pass/sign_from_value.cpp @@ -80,13 +80,14 @@ class SignFromValueVisitor : public PassUtils::SkipOptimizationFunctionVisitor + void visit_BinOp(const T& x_const) { if( !from_sign_from_value ) { return ; } from_sign_from_value = true; - ASR::BinOp_t& x = const_cast(x_const); + T& x = const_cast(x_const); sign_from_value_var = nullptr; visit_expr(*x.m_left); @@ -124,6 +125,16 @@ class SignFromValueVisitor : public PassUtils::SkipOptimizationFunctionVisitor(x); From df73574bbad02ddea5af512f879c5cfca14d46a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 25 May 2022 12:15:24 -0600 Subject: [PATCH 15/21] Update inline_function_calls --- src/libasr/pass/inline_function_calls.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/libasr/pass/inline_function_calls.cpp b/src/libasr/pass/inline_function_calls.cpp index b6d72627fc..b45ccb1eb9 100644 --- a/src/libasr/pass/inline_function_calls.cpp +++ b/src/libasr/pass/inline_function_calls.cpp @@ -349,8 +349,9 @@ class InlineFunctionCallVisitor : public PassUtils::PassVisitor(x); + template + void visit_BinOp(const T& x) { + T& xx = const_cast(x); from_inline_function_call = true; function_result_var = nullptr; visit_expr(*x.m_left); @@ -366,6 +367,19 @@ class InlineFunctionCallVisitor : public PassUtils::PassVisitor Date: Wed, 25 May 2022 12:18:12 -0600 Subject: [PATCH 16/21] Update LLVM --- src/libasr/codegen/asr_to_llvm.cpp | 293 +++++++++++++++-------------- 1 file changed, 154 insertions(+), 139 deletions(-) diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 8602cef8de..09cc40056e 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -2950,11 +2950,60 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor tmp = lfortran_str_len(parg); } - void visit_BinOp(const ASR::BinOp_t &x) { - if( x.m_overloaded ) { - this->visit_expr(*x.m_overloaded); - return ; + void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) { + if (x.m_value) { + this->visit_expr_wrapper(x.m_value, true); + return; + } + this->visit_expr_wrapper(x.m_left, true); + llvm::Value *left_val = tmp; + this->visit_expr_wrapper(x.m_right, true); + llvm::Value *right_val = tmp; + LFORTRAN_ASSERT(ASRUtils::is_integer(*x.m_type)) + switch (x.m_op) { + case ASR::binopType::Add: { + tmp = builder->CreateAdd(left_val, right_val); + break; + }; + case ASR::binopType::Sub: { + tmp = builder->CreateSub(left_val, right_val); + break; + }; + case ASR::binopType::Mul: { + tmp = builder->CreateMul(left_val, right_val); + break; + }; + case ASR::binopType::Div: { + tmp = builder->CreateUDiv(left_val, right_val); + break; + }; + case ASR::binopType::Pow: { + llvm::Type *type; + int a_kind; + a_kind = down_cast(ASRUtils::type_get_past_pointer(x.m_type))->m_kind; + type = getFPType(a_kind); + llvm::Value *fleft = builder->CreateSIToFP(left_val, + type); + llvm::Value *fright = builder->CreateSIToFP(right_val, + type); + std::string func_name = a_kind == 4 ? "llvm.pow.f32" : "llvm.pow.f64"; + llvm::Function *fn_pow = module->getFunction(func_name); + if (!fn_pow) { + llvm::FunctionType *function_type = llvm::FunctionType::get( + type, { type, type}, false); + fn_pow = llvm::Function::Create(function_type, + llvm::Function::ExternalLinkage, func_name, + module.get()); + } + tmp = builder->CreateCall(fn_pow, {fleft, fright}); + type = getIntType(a_kind); + tmp = builder->CreateFPToSI(tmp, type); + break; + }; } + } + + void visit_RealBinOp(const ASR::RealBinOp_t &x) { if (x.m_value) { this->visit_expr_wrapper(x.m_value, true); return; @@ -2963,142 +3012,108 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm::Value *left_val = tmp; this->visit_expr_wrapper(x.m_right, true); llvm::Value *right_val = tmp; - if (ASRUtils::is_integer(*x.m_type)) { - switch (x.m_op) { - case ASR::binopType::Add: { - tmp = builder->CreateAdd(left_val, right_val); - break; - }; - case ASR::binopType::Sub: { - tmp = builder->CreateSub(left_val, right_val); - break; - }; - case ASR::binopType::Mul: { - tmp = builder->CreateMul(left_val, right_val); - break; - }; - case ASR::binopType::Div: { - tmp = builder->CreateUDiv(left_val, right_val); - break; - }; - case ASR::binopType::Pow: { - llvm::Type *type; - int a_kind; - a_kind = down_cast(ASRUtils::type_get_past_pointer(x.m_type))->m_kind; - type = getFPType(a_kind); - llvm::Value *fleft = builder->CreateSIToFP(left_val, - type); - llvm::Value *fright = builder->CreateSIToFP(right_val, - type); - std::string func_name = a_kind == 4 ? "llvm.pow.f32" : "llvm.pow.f64"; - llvm::Function *fn_pow = module->getFunction(func_name); - if (!fn_pow) { - llvm::FunctionType *function_type = llvm::FunctionType::get( - type, { type, type}, false); - fn_pow = llvm::Function::Create(function_type, - llvm::Function::ExternalLinkage, func_name, - module.get()); - } - tmp = builder->CreateCall(fn_pow, {fleft, fright}); - type = getIntType(a_kind); - tmp = builder->CreateFPToSI(tmp, type); - break; - }; - } - } else if (ASRUtils::is_real(*x.m_type)) { - switch (x.m_op) { - case ASR::binopType::Add: { - tmp = builder->CreateFAdd(left_val, right_val); - break; - }; - case ASR::binopType::Sub: { - tmp = builder->CreateFSub(left_val, right_val); - break; - }; - case ASR::binopType::Mul: { - tmp = builder->CreateFMul(left_val, right_val); - break; - }; - case ASR::binopType::Div: { - tmp = builder->CreateFDiv(left_val, right_val); - break; - }; - case ASR::binopType::Pow: { - llvm::Type *type; - int a_kind; - a_kind = down_cast(ASRUtils::type_get_past_pointer(x.m_type))->m_kind; - type = getFPType(a_kind); - std::string func_name = a_kind == 4 ? "llvm.pow.f32" : "llvm.pow.f64"; - llvm::Function *fn_pow = module->getFunction(func_name); - if (!fn_pow) { - llvm::FunctionType *function_type = llvm::FunctionType::get( - type, { type, type }, false); - fn_pow = llvm::Function::Create(function_type, - llvm::Function::ExternalLinkage, func_name, - module.get()); - } - tmp = builder->CreateCall(fn_pow, {left_val, right_val}); - break; - }; - } - } else if (ASRUtils::is_complex(*x.m_type)) { - llvm::Type *type; - int a_kind; - a_kind = down_cast(ASRUtils::type_get_past_pointer(x.m_type))->m_kind; - type = getComplexType(a_kind); - if( left_val->getType()->isPointerTy() ) { - left_val = CreateLoad(left_val); - } - if( right_val->getType()->isPointerTy() ) { - right_val = CreateLoad(right_val); - } - std::string fn_name; - switch (x.m_op) { - case ASR::binopType::Add: { - if (a_kind == 4) { - fn_name = "_lfortran_complex_add_32"; - } else { - fn_name = "_lfortran_complex_add_64"; - } - break; - }; - case ASR::binopType::Sub: { - if (a_kind == 4) { - fn_name = "_lfortran_complex_sub_32"; - } else { - fn_name = "_lfortran_complex_sub_64"; - } - break; - }; - case ASR::binopType::Mul: { - if (a_kind == 4) { - fn_name = "_lfortran_complex_mul_32"; - } else { - fn_name = "_lfortran_complex_mul_64"; - } - break; - }; - case ASR::binopType::Div: { - if (a_kind == 4) { - fn_name = "_lfortran_complex_div_32"; - } else { - fn_name = "_lfortran_complex_div_64"; - } - break; - }; - case ASR::binopType::Pow: { - if (a_kind == 4) { - fn_name = "_lfortran_complex_pow_32"; - } else { - fn_name = "_lfortran_complex_pow_64"; - } - break; - }; - } - tmp = lfortran_complex_bin_op(left_val, right_val, fn_name, type); - } else { - throw CodeGenError("Binop: Only Real, Integer and Complex types are allowed"); + LFORTRAN_ASSERT(ASRUtils::is_real(*x.m_type)) + switch (x.m_op) { + case ASR::binopType::Add: { + tmp = builder->CreateFAdd(left_val, right_val); + break; + }; + case ASR::binopType::Sub: { + tmp = builder->CreateFSub(left_val, right_val); + break; + }; + case ASR::binopType::Mul: { + tmp = builder->CreateFMul(left_val, right_val); + break; + }; + case ASR::binopType::Div: { + tmp = builder->CreateFDiv(left_val, right_val); + break; + }; + case ASR::binopType::Pow: { + llvm::Type *type; + int a_kind; + a_kind = down_cast(ASRUtils::type_get_past_pointer(x.m_type))->m_kind; + type = getFPType(a_kind); + std::string func_name = a_kind == 4 ? "llvm.pow.f32" : "llvm.pow.f64"; + llvm::Function *fn_pow = module->getFunction(func_name); + if (!fn_pow) { + llvm::FunctionType *function_type = llvm::FunctionType::get( + type, { type, type }, false); + fn_pow = llvm::Function::Create(function_type, + llvm::Function::ExternalLinkage, func_name, + module.get()); + } + tmp = builder->CreateCall(fn_pow, {left_val, right_val}); + break; + }; + } + } + + void visit_ComplexBinOp(const ASR::ComplexBinOp_t &x) { + if (x.m_value) { + this->visit_expr_wrapper(x.m_value, true); + return; + } + this->visit_expr_wrapper(x.m_left, true); + llvm::Value *left_val = tmp; + this->visit_expr_wrapper(x.m_right, true); + llvm::Value *right_val = tmp; + LFORTRAN_ASSERT(ASRUtils::is_complex(*x.m_type)); + llvm::Type *type; + int a_kind; + a_kind = down_cast(ASRUtils::type_get_past_pointer(x.m_type))->m_kind; + type = getComplexType(a_kind); + if( left_val->getType()->isPointerTy() ) { + left_val = CreateLoad(left_val); + } + if( right_val->getType()->isPointerTy() ) { + right_val = CreateLoad(right_val); + } + std::string fn_name; + switch (x.m_op) { + case ASR::binopType::Add: { + if (a_kind == 4) { + fn_name = "_lfortran_complex_add_32"; + } else { + fn_name = "_lfortran_complex_add_64"; + } + break; + }; + case ASR::binopType::Sub: { + if (a_kind == 4) { + fn_name = "_lfortran_complex_sub_32"; + } else { + fn_name = "_lfortran_complex_sub_64"; + } + break; + }; + case ASR::binopType::Mul: { + if (a_kind == 4) { + fn_name = "_lfortran_complex_mul_32"; + } else { + fn_name = "_lfortran_complex_mul_64"; + } + break; + }; + case ASR::binopType::Div: { + if (a_kind == 4) { + fn_name = "_lfortran_complex_div_32"; + } else { + fn_name = "_lfortran_complex_div_64"; + } + break; + }; + case ASR::binopType::Pow: { + if (a_kind == 4) { + fn_name = "_lfortran_complex_pow_32"; + } else { + fn_name = "_lfortran_complex_pow_64"; + } + break; + }; } + tmp = lfortran_complex_bin_op(left_val, right_val, fn_name, type); } void visit_UnaryOp(const ASR::UnaryOp_t &x) { From a6613bcc961d17eeefd50674ee296481894bc64b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Wed, 25 May 2022 12:19:47 -0600 Subject: [PATCH 17/21] Update index_add_one --- src/lpython/semantics/python_ast_to_asr.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 48554c9273..1fa2d62015 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -746,15 +746,14 @@ class CommonVisitor : public AST::BaseVisitor { ASR::expr_t *index_add_one(const Location &loc, ASR::expr_t *idx) { // Add 1 to the index `idx`, assumes `idx` is of type Integer 4 - ASR::expr_t *overloaded = nullptr; ASR::expr_t *comptime_value = nullptr; ASR::ttype_t *a_type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4, nullptr, 0)); ASR::expr_t *constant_one = ASR::down_cast(ASR::make_IntegerConstant_t( al, loc, 1, a_type)); - return ASRUtils::EXPR(ASR::make_BinOp_t(al, loc, idx, + return ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc, idx, ASR::binopType::Add, constant_one, a_type, - comptime_value, overloaded)); + comptime_value)); } // Casts `right` if needed to the type of `left` From f74ee54b474f9bc5493c2a1061c0c729f229a4ba Mon Sep 17 00:00:00 2001 From: Naman Gera Date: Thu, 26 May 2022 12:44:22 +0530 Subject: [PATCH 18/21] Update python_ast_to_asr.cpp --- src/lpython/semantics/python_ast_to_asr.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 1fa2d62015..2c09f1a3b3 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -1116,6 +1116,7 @@ class CommonVisitor : public AST::BaseVisitor { } value = ASR::down_cast(ASR::make_IntegerConstant_t( al, loc, result, dest_type)); + tmp = ASR::make_IntegerBinOp_t(al, loc, left, op, right, dest_type, value); } else if (ASRUtils::is_real(*dest_type)) { double left_value = ASR::down_cast( @@ -1133,6 +1134,7 @@ class CommonVisitor : public AST::BaseVisitor { } value = ASR::down_cast(ASR::make_RealConstant_t( al, loc, result, dest_type)); + tmp = ASR::make_RealBinOp_t(al, loc, left, op, right, dest_type, value); } else if (ASRUtils::is_complex(*dest_type)) { ASR::ComplexConstant_t *left0 = ASR::down_cast( @@ -1152,6 +1154,7 @@ class CommonVisitor : public AST::BaseVisitor { } value = ASR::down_cast(ASR::make_ComplexConstant_t(al, loc, std::real(result), std::imag(result), dest_type)); + tmp = ASR::make_ComplexBinOp_t(al, loc, left, op, right, dest_type, value); } else if (ASRUtils::is_logical(*dest_type)) { int8_t left_value = ASR::down_cast( @@ -1169,12 +1172,9 @@ class CommonVisitor : public AST::BaseVisitor { } value = ASR::down_cast(ASR::make_IntegerConstant_t( al, loc, result, int_type)); - dest_type = int_type; + tmp = ASR::make_IntegerBinOp_t(al, loc, left, op, right, int_type, value); } } - ASR::expr_t *overloaded = nullptr; - tmp = ASR::make_BinOp_t(al, loc, left, op, right, dest_type, - value, overloaded); } void visit_Name(const AST::Name_t &x) { From 8b99414bba1f0ef5a93e4fe11daa9ac25e6dba85 Mon Sep 17 00:00:00 2001 From: Naman Gera Date: Thu, 26 May 2022 12:59:59 +0530 Subject: [PATCH 19/21] Update asr_to_c_cpp.h --- src/libasr/codegen/asr_to_c_cpp.h | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index 0a5eb0c170..b40028c30f 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -663,7 +663,20 @@ R"(#include } } - void visit_BinOp(const ASR::BinOp_t &x) { + void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) { + handle_BinOp(x); + } + + void visit_RealBinOp(const ASR::RealBinOp_t &x) { + handle_BinOp(x); + } + + void visit_ComplexBinOp(const ASR::ComplexBinOp_t &x) { + handle_BinOp(x); + } + + template + void handle_BinOp(const T &x) { self().visit_expr(*x.m_left); std::string left = std::move(src); int left_precedence = last_expr_precedence; @@ -710,7 +723,7 @@ R"(#include } } - void visit_BoolOp(const ASR::BoolOp_t &x) { + void visit_LogicalBinOp(const ASR::LogicalBinOp_t &x) { self().visit_expr(*x.m_left); std::string left = std::move(src); int left_precedence = last_expr_precedence; @@ -718,19 +731,19 @@ R"(#include std::string right = std::move(src); int right_precedence = last_expr_precedence; switch (x.m_op) { - case (ASR::boolopType::And): { + case (ASR::logicalbinopType::And): { last_expr_precedence = 14; break; } - case (ASR::boolopType::Or): { + case (ASR::logicalbinopType::Or): { last_expr_precedence = 15; break; } - case (ASR::boolopType::NEqv): { + case (ASR::logicalbinopType::NEqv): { last_expr_precedence = 10; break; } - case (ASR::boolopType::Eqv): { + case (ASR::logicalbinopType::Eqv): { last_expr_precedence = 10; break; } @@ -742,7 +755,7 @@ R"(#include } else { src += "(" + left + ")"; } - src += ASRUtils::boolop_to_str(x.m_op); + src += ASRUtils::logicalbinop_to_str(x.m_op); if (right_precedence <= last_expr_precedence) { src += right; } else { From 94d73f89f9de7c1c84dbc1b12b4b91764a86f726 Mon Sep 17 00:00:00 2001 From: Naman Gera Date: Thu, 26 May 2022 13:09:41 +0530 Subject: [PATCH 20/21] Remove common parts from asr_to_cpp --- src/libasr/codegen/asr_to_cpp.cpp | 200 ------------------------------ 1 file changed, 200 deletions(-) diff --git a/src/libasr/codegen/asr_to_cpp.cpp b/src/libasr/codegen/asr_to_cpp.cpp index 7b64255e00..be4fcaee46 100644 --- a/src/libasr/codegen/asr_to_cpp.cpp +++ b/src/libasr/codegen/asr_to_cpp.cpp @@ -370,166 +370,6 @@ Kokkos::View from_std_vector(const std::vector &v) last_expr_precedence = 2; } - void visit_Compare(const ASR::Compare_t &x) { - this->visit_expr(*x.m_left); - std::string left = std::move(src); - int left_precedence = last_expr_precedence; - this->visit_expr(*x.m_right); - std::string right = std::move(src); - int right_precedence = last_expr_precedence; - switch (x.m_op) { - case (ASR::cmpopType::Eq) : { last_expr_precedence = 10; break; } - case (ASR::cmpopType::Gt) : { last_expr_precedence = 9; break; } - case (ASR::cmpopType::GtE) : { last_expr_precedence = 9; break; } - case (ASR::cmpopType::Lt) : { last_expr_precedence = 9; break; } - case (ASR::cmpopType::LtE) : { last_expr_precedence = 9; break; } - case (ASR::cmpopType::NotEq): { last_expr_precedence = 10; break; } - default : LFORTRAN_ASSERT(false); // should never happen - } - if (left_precedence <= last_expr_precedence) { - src += left; - } else { - src += "(" + left + ")"; - } - src += ASRUtils::cmpop_to_str(x.m_op); - if (right_precedence <= last_expr_precedence) { - src += right; - } else { - src += "(" + right + ")"; - } - } - - void visit_UnaryOp(const ASR::UnaryOp_t &x) { - this->visit_expr(*x.m_operand); - int expr_precedence = last_expr_precedence; - if (x.m_type->type == ASR::ttypeType::Integer) { - if (x.m_op == ASR::unaryopType::UAdd) { - // src = src; - // Skip unary plus, keep the previous precedence - } else if (x.m_op == ASR::unaryopType::USub) { - last_expr_precedence = 3; - if (expr_precedence <= last_expr_precedence) { - src = "-" + src; - } else { - src = "-(" + src + ")"; - } - } else if (x.m_op == ASR::unaryopType::Invert) { - last_expr_precedence = 3; - if (expr_precedence <= last_expr_precedence) { - src = "~" + src; - } else { - src = "~(" + src + ")"; - } - - } else if (x.m_op == ASR::unaryopType::Not) { - last_expr_precedence = 3; - if (expr_precedence <= last_expr_precedence) { - src = "!" + src; - } else { - src = "!(" + src + ")"; - } - } else { - throw CodeGenError("Unary type not implemented yet for Integer"); - } - return; - } else if (x.m_type->type == ASR::ttypeType::Real) { - if (x.m_op == ASR::unaryopType::UAdd) { - // src = src; - // Skip unary plus, keep the previous precedence - } else if (x.m_op == ASR::unaryopType::USub) { - last_expr_precedence = 3; - if (expr_precedence <= last_expr_precedence) { - src = "-" + src; - } else { - src = "-(" + src + ")"; - } - } else if (x.m_op == ASR::unaryopType::Not) { - last_expr_precedence = 3; - if (expr_precedence <= last_expr_precedence) { - src = "!" + src; - } else { - src = "!(" + src + ")"; - } - } else { - throw CodeGenError("Unary type not implemented yet for Real"); - } - return; - } else if (x.m_type->type == ASR::ttypeType::Logical) { - if (x.m_op == ASR::unaryopType::Not) { - last_expr_precedence = 3; - if (expr_precedence <= last_expr_precedence) { - src = "!" + src; - } else { - src = "!(" + src + ")"; - } - return; - } else { - throw CodeGenError("Unary type not implemented yet for Logical"); - } - } else { - throw CodeGenError("UnaryOp: type not supported yet"); - } - } - - void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) { - handle_BinOp(x); - } - - void visit_RealBinOp(const ASR::RealBinOp_t &x) { - handle_BinOp(x); - } - - void visit_ComplexBinOp(const ASR::ComplexBinOp_t &x) { - handle_BinOp(x); - } - - template - void handle_BinOp(const T &x) { - this->visit_expr(*x.m_left); - std::string left = std::move(src); - int left_precedence = last_expr_precedence; - this->visit_expr(*x.m_right); - std::string right = std::move(src); - int right_precedence = last_expr_precedence; - switch (x.m_op) { - case (ASR::binopType::Add) : { last_expr_precedence = 6; break; } - case (ASR::binopType::Sub) : { last_expr_precedence = 6; break; } - case (ASR::binopType::Mul) : { last_expr_precedence = 5; break; } - case (ASR::binopType::Div) : { last_expr_precedence = 5; break; } - case (ASR::binopType::Pow) : { - src = "std::pow(" + left + ", " + right + ")"; - return; - } - default: throw CodeGenError("BinOp: operator not implemented yet"); - } - src = ""; - if (left_precedence == 3) { - src += "(" + left + ")"; - } else { - if (left_precedence <= last_expr_precedence) { - src += left; - } else { - src += "(" + left + ")"; - } - } - src += ASRUtils::binop_to_str(x.m_op); - if (right_precedence == 3) { - src += "(" + right + ")"; - } else if (x.m_op == ASR::binopType::Sub) { - if (right_precedence < last_expr_precedence) { - src += right; - } else { - src += "(" + right + ")"; - } - } else { - if (right_precedence <= last_expr_precedence) { - src += right; - } else { - src += "(" + right + ")"; - } - } - } - void visit_StringConcat(const ASR::StringConcat_t &x) { this->visit_expr(*x.m_left); std::string left = std::move(src); @@ -551,46 +391,6 @@ Kokkos::View from_std_vector(const std::vector &v) } } - void visit_LogicalBinOp(const ASR::LogicalBinOp_t &x) { - this->visit_expr(*x.m_left); - std::string left = std::move(src); - int left_precedence = last_expr_precedence; - this->visit_expr(*x.m_right); - std::string right = std::move(src); - int right_precedence = last_expr_precedence; - switch (x.m_op) { - case (ASR::logicalbinopType::And): { - last_expr_precedence = 14; - break; - } - case (ASR::logicalbinopType::Or): { - last_expr_precedence = 15; - break; - } - case (ASR::logicalbinopType::NEqv): { - last_expr_precedence = 10; - break; - } - case (ASR::logicalbinopType::Eqv): { - last_expr_precedence = 10; - break; - } - default : throw CodeGenError("Unhandled switch case"); - } - - if (left_precedence <= last_expr_precedence) { - src += left; - } else { - src += "(" + left + ")"; - } - src += ASRUtils::logicalbinop_to_str(x.m_op); - if (right_precedence <= last_expr_precedence) { - src += right; - } else { - src += "(" + right + ")"; - } - } - void visit_ArrayConstant(const ASR::ArrayConstant_t &x) { std::string out = "from_std_vector({"; for (size_t i=0; i Date: Thu, 26 May 2022 13:39:59 +0530 Subject: [PATCH 21/21] Move create_binop_add() from ASRUtils to PassUtils --- src/libasr/asr_utils.h | 16 ---------------- src/libasr/pass/array_op.cpp | 4 ++-- src/libasr/pass/pass_utils.cpp | 16 ++++++++++++++++ src/libasr/pass/pass_utils.h | 2 ++ src/libasr/pass/select_case.cpp | 8 ++++---- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/libasr/asr_utils.h b/src/libasr/asr_utils.h index adef64ac5e..5bf172c300 100644 --- a/src/libasr/asr_utils.h +++ b/src/libasr/asr_utils.h @@ -1139,22 +1139,6 @@ ASR::asr_t* symbol_resolve_external_generic_procedure_without_eval( ASR::asr_t* make_Cast_t_value(Allocator &al, const Location &a_loc, ASR::expr_t* a_arg, ASR::cast_kindType a_kind, ASR::ttype_t* a_type); -ASR::expr_t* create_binop_add(Allocator &al, const Location &loc, ASR::expr_t* left, ASR::expr_t* right) { - LFORTRAN_ASSERT(expr_type(left) == expr_type(right)) - ASR::ttype_t* type = expr_type(left); - // TODO: compute `value`: - if (is_integer(*type)) { - return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Add, right, type, nullptr)); - } else if (is_real(*type)) { - return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Add, right, type, nullptr)); - } else if (is_complex(*type)) { - return EXPR(ASR::make_ComplexBinOp_t(al, loc, left, ASR::binopType::Add, right, type, nullptr)); - } else { - LFORTRAN_ASSERT(false); - return nullptr; - } -} - } // namespace ASRUtils } // namespace LFortran diff --git a/src/libasr/pass/array_op.cpp b/src/libasr/pass/array_op.cpp index 86b5ca025b..6aaad2fae7 100644 --- a/src/libasr/pass/array_op.cpp +++ b/src/libasr/pass/array_op.cpp @@ -568,7 +568,7 @@ class ArrayOpVisitor : public PassUtils::PassVisitor doloop_body.push_back(al, set_to_one); doloop_body.push_back(al, doloop); } - ASR::expr_t* inc_expr = ASRUtils::create_binop_add(al, x.base.base.loc, idx_vars_value[i], const_1); + ASR::expr_t* inc_expr = PassUtils::create_binop_add(al, x.base.base.loc, idx_vars_value[i], const_1); ASR::stmt_t* assign_stmt = LFortran::ASRUtils::STMT(ASR::make_Assignment_t(al, x.base.base.loc, idx_vars_value[i], inc_expr, nullptr)); doloop_body.push_back(al, assign_stmt); doloop = LFortran::ASRUtils::STMT(ASR::make_DoLoop_t(al, x.base.base.loc, head, doloop_body.p, doloop_body.size())); @@ -661,7 +661,7 @@ class ArrayOpVisitor : public PassUtils::PassVisitor doloop_body.push_back(al, set_to_one); doloop_body.push_back(al, doloop); } - ASR::expr_t* inc_expr = ASRUtils::create_binop_add(al, x.base.base.loc, idx_vars_value[i], const_1); + ASR::expr_t* inc_expr = PassUtils::create_binop_add(al, x.base.base.loc, idx_vars_value[i], const_1); ASR::stmt_t* assign_stmt = LFortran::ASRUtils::STMT(ASR::make_Assignment_t(al, x.base.base.loc, idx_vars_value[i], inc_expr, nullptr)); doloop_body.push_back(al, assign_stmt); doloop = LFortran::ASRUtils::STMT(ASR::make_DoLoop_t(al, x.base.base.loc, head, doloop_body.p, doloop_body.size())); diff --git a/src/libasr/pass/pass_utils.cpp b/src/libasr/pass/pass_utils.cpp index 5c5a769a0d..62f644a122 100644 --- a/src/libasr/pass/pass_utils.cpp +++ b/src/libasr/pass/pass_utils.cpp @@ -179,6 +179,22 @@ namespace LFortran { return array_ref; } + ASR::expr_t* create_binop_add(Allocator &al, const Location &loc, ASR::expr_t* left, ASR::expr_t* right) { + LFORTRAN_ASSERT(ASRUtils::expr_type(left) == ASRUtils::expr_type(right)) + ASR::ttype_t* type = ASRUtils::expr_type(left); + // TODO: compute `value`: + if (ASRUtils::is_integer(*type)) { + return ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Add, right, type, nullptr)); + } else if (ASRUtils::is_real(*type)) { + return ASRUtils::EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Add, right, type, nullptr)); + } else if (ASRUtils::is_complex(*type)) { + return ASRUtils::EXPR(ASR::make_ComplexBinOp_t(al, loc, left, ASR::binopType::Add, right, type, nullptr)); + } else { + LFORTRAN_ASSERT(false); + return nullptr; + } + } + void create_idx_vars(Vec& idx_vars, int n_dims, const Location& loc, Allocator& al, SymbolTable*& current_scope, std::string suffix) { idx_vars.reserve(al, n_dims); diff --git a/src/libasr/pass/pass_utils.h b/src/libasr/pass/pass_utils.h index e4cab450a0..fd1553822f 100644 --- a/src/libasr/pass/pass_utils.h +++ b/src/libasr/pass/pass_utils.h @@ -22,6 +22,8 @@ namespace LFortran { ASR::expr_t* create_array_ref(ASR::symbol_t* arr, Vec& idx_vars, Allocator& al, const Location& loc, ASR::ttype_t* _type); + ASR::expr_t* create_binop_add(Allocator &al, const Location &loc, ASR::expr_t* left, ASR::expr_t* right); + void create_idx_vars(Vec& idx_vars, int n_dims, const Location& loc, Allocator& al, SymbolTable*& current_scope, std::string suffix="_k"); diff --git a/src/libasr/pass/select_case.cpp b/src/libasr/pass/select_case.cpp index 7dd4213a83..60068b768f 100644 --- a/src/libasr/pass/select_case.cpp +++ b/src/libasr/pass/select_case.cpp @@ -55,14 +55,14 @@ inline ASR::expr_t* gen_test_expr_CaseStmt(Allocator& al, const Location& loc, A } else if( Case_Stmt->n_test == 2 ) { ASR::expr_t* left = ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::Eq, Case_Stmt->m_test[0], LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); ASR::expr_t* right = ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::Eq, Case_Stmt->m_test[1], LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); - test_expr = ASRUtils::create_binop_add(al, loc, left, right); + test_expr = PassUtils::create_binop_add(al, loc, left, right); } else { ASR::expr_t* left = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::Eq, Case_Stmt->m_test[0], LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); ASR::expr_t* right = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::Eq, Case_Stmt->m_test[1], LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); - test_expr = ASRUtils::create_binop_add(al, loc, left, right); + test_expr = PassUtils::create_binop_add(al, loc, left, right); for( std::uint32_t j = 2; j < Case_Stmt->n_test; j++ ) { ASR::expr_t* newExpr = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::Eq, Case_Stmt->m_test[j], LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); - test_expr = ASRUtils::create_binop_add(al, loc, test_expr, newExpr); + test_expr = PassUtils::create_binop_add(al, loc, test_expr, newExpr); } } return test_expr; @@ -77,7 +77,7 @@ inline ASR::expr_t* gen_test_expr_CaseStmt_Range(Allocator& al, const Location& } else if( Case_Stmt->m_start != nullptr && Case_Stmt->m_end != nullptr ) { ASR::expr_t* left = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, Case_Stmt->m_start, ASR::cmpopType::LtE, a_test, LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); ASR::expr_t* right = LFortran::ASRUtils::EXPR(ASR::make_Compare_t(al, loc, a_test, ASR::cmpopType::LtE, Case_Stmt->m_end, LFortran::ASRUtils::expr_type(a_test), nullptr, nullptr)); - test_expr = ASRUtils::create_binop_add(al, loc, left, right); + test_expr = PassUtils::create_binop_add(al, loc, left, right); } return test_expr; }