From 128270c21a11de32704b977318b2013c8950c012 Mon Sep 17 00:00:00 2001 From: Smit-create Date: Wed, 15 Mar 2023 15:35:20 +0530 Subject: [PATCH 1/3] Use compiler options --- src/bin/lpython.cpp | 6 ++---- src/libasr/codegen/asr_to_c.h | 2 +- src/libasr/codegen/asr_to_cpp.h | 3 ++- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index cb62f8e7f3..8a3646bd1d 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -250,8 +250,7 @@ int emit_cpp(const std::string &infile, LCompilers::ASR::TranslationUnit_t* asr = r1.result; diagnostics.diagnostics.clear(); - auto res = LCompilers::asr_to_cpp(al, *asr, diagnostics, - compiler_options.platform, 0); + auto res = LCompilers::asr_to_cpp(al, *asr, diagnostics, compiler_options, 0); std::cerr << diagnostics.render(lm, compiler_options); if (!res.ok) { LCOMPILERS_ASSERT(diagnostics.has_error()) @@ -295,8 +294,7 @@ int emit_c(const std::string &infile, LCompilers::ASR::TranslationUnit_t* asr = r1.result; diagnostics.diagnostics.clear(); - auto res = LCompilers::asr_to_c(al, *asr, diagnostics, - compiler_options.platform, 0); + auto res = LCompilers::asr_to_c(al, *asr, diagnostics, compiler_options, 0); std::cerr << diagnostics.render(lm, compiler_options); if (!res.ok) { LCOMPILERS_ASSERT(diagnostics.has_error()) diff --git a/src/libasr/codegen/asr_to_c.h b/src/libasr/codegen/asr_to_c.h index b78bfc25e6..5bf90948b5 100644 --- a/src/libasr/codegen/asr_to_c.h +++ b/src/libasr/codegen/asr_to_c.h @@ -7,7 +7,7 @@ namespace LCompilers { Result asr_to_c(Allocator &al, ASR::TranslationUnit_t &asr, - diag::Diagnostics &diagnostics, Platform &platform, + diag::Diagnostics &diagnostics, CompilerOptions &co, int64_t default_lower_bound); } // namespace LCompilers diff --git a/src/libasr/codegen/asr_to_cpp.h b/src/libasr/codegen/asr_to_cpp.h index 58380852dd..e54035a391 100644 --- a/src/libasr/codegen/asr_to_cpp.h +++ b/src/libasr/codegen/asr_to_cpp.h @@ -7,7 +7,8 @@ namespace LCompilers { Result asr_to_cpp(Allocator &al, ASR::TranslationUnit_t &asr, - diag::Diagnostics &diagnostics, Platform &platform, int64_t default_lower_bound); + diag::Diagnostics &diagnostics, CompilerOptions &co, + int64_t default_lower_bound); } // namespace LCompilers From 56bd232938bb8784ded0505a721b6ff24cd0faeb Mon Sep 17 00:00:00 2001 From: Smit-create Date: Thu, 16 Mar 2023 15:41:27 +0530 Subject: [PATCH 2/3] Use value when fast is enable --- src/libasr/codegen/asr_to_c.cpp | 22 ++++++++-- src/libasr/codegen/asr_to_c_cpp.h | 70 ++++++++++++++++++------------- src/libasr/codegen/asr_to_cpp.cpp | 8 ++-- 3 files changed, 62 insertions(+), 38 deletions(-) diff --git a/src/libasr/codegen/asr_to_c.cpp b/src/libasr/codegen/asr_to_c.cpp index 95a42f4979..b5a15f637e 100644 --- a/src/libasr/codegen/asr_to_c.cpp +++ b/src/libasr/codegen/asr_to_c.cpp @@ -17,6 +17,11 @@ #include #include +#define CHECK_FAST_C(compiler_options, x) \ + if (compiler_options.fast && x.m_value != nullptr) { \ + visit_expr(*x.m_value); \ + return; \ + } \ namespace LCompilers { @@ -30,9 +35,9 @@ class ASRToCVisitor : public BaseCCPPVisitor int counter; - ASRToCVisitor(diag::Diagnostics &diag, Platform &platform, + ASRToCVisitor(diag::Diagnostics &diag, CompilerOptions &co, int64_t default_lower_bound) - : BaseCCPPVisitor(diag, platform, false, false, true, default_lower_bound), + : BaseCCPPVisitor(diag, co.platform, co, false, false, true, default_lower_bound), array_types_decls(std::string("\nstruct dimension_descriptor\n" "{\n int32_t lower_bound, length;\n};\n")), c_utils_functions{std::make_unique()}, @@ -970,15 +975,18 @@ R"( } void visit_EnumStaticMember(const ASR::EnumStaticMember_t& x) { + CHECK_FAST_C(compiler_options, x) ASR::Variable_t* enum_var = ASR::down_cast(x.m_m); src = std::string(enum_var->m_name); } void visit_EnumValue(const ASR::EnumValue_t& x) { + CHECK_FAST_C(compiler_options, x) visit_expr(*x.m_v); } void visit_EnumName(const ASR::EnumName_t& x) { + CHECK_FAST_C(compiler_options, x) int64_t min_value = INT64_MAX; ASR::Enum_t* enum_t = ASR::down_cast(x.m_enum_type); ASR::EnumType_t* enum_type = ASR::down_cast(enum_t->m_enum_type); @@ -1127,6 +1135,7 @@ R"( } void visit_ArraySize(const ASR::ArraySize_t& x) { + CHECK_FAST_C(compiler_options, x) visit_expr(*x.m_v); std::string var_name = src; std::string args = ""; @@ -1144,6 +1153,7 @@ R"( } void visit_ArrayReshape(const ASR::ArrayReshape_t& x) { + CHECK_FAST_C(compiler_options, x) visit_expr(*x.m_array); std::string array = src; visit_expr(*x.m_shape); @@ -1166,6 +1176,7 @@ R"( } void visit_ArrayBound(const ASR::ArrayBound_t& x) { + CHECK_FAST_C(compiler_options, x) visit_expr(*x.m_v); std::string var_name = src; std::string args = ""; @@ -1203,6 +1214,7 @@ R"( } void visit_ArrayItem(const ASR::ArrayItem_t &x) { + CHECK_FAST_C(compiler_options, x) this->visit_expr(*x.m_v); std::string array = src; std::string out = array; @@ -1253,6 +1265,7 @@ R"( } void visit_StringItem(const ASR::StringItem_t& x) { + CHECK_FAST_C(compiler_options, x) this->visit_expr(*x.m_idx); std::string idx = std::move(src); this->visit_expr(*x.m_arg); @@ -1261,6 +1274,7 @@ R"( } void visit_StringLen(const ASR::StringLen_t &x) { + CHECK_FAST_C(compiler_options, x) this->visit_expr(*x.m_arg); src = "strlen(" + src + ")"; } @@ -1276,7 +1290,7 @@ R"( }; Result asr_to_c(Allocator &al, ASR::TranslationUnit_t &asr, - diag::Diagnostics &diagnostics, Platform &platform, + diag::Diagnostics &diagnostics, CompilerOptions &co, int64_t default_lower_bound) { @@ -1286,7 +1300,7 @@ Result asr_to_c(Allocator &al, ASR::TranslationUnit_t &asr, pass_replace_array_op(al, asr, pass_options); pass_unused_functions(al, asr, pass_options); pass_replace_class_constructor(al, asr, pass_options); - ASRToCVisitor v(diagnostics, platform, default_lower_bound); + ASRToCVisitor v(diagnostics, co, default_lower_bound); try { v.visit_asr((ASR::asr_t &)asr); } catch (const CodeGenError &e) { diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index c7d556a628..9abd8bef5e 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -27,6 +27,12 @@ #include #include +#define CHECK_FAST_C_CPP(compiler_options, x) \ + if (compiler_options.fast && x.m_value != nullptr) { \ + self().visit_expr(*x.m_value); \ + return; \ + } \ + namespace LCompilers { @@ -86,6 +92,7 @@ class BaseCCPPVisitor : public ASR::BaseVisitor Platform platform; std::string src; std::string current_body; + CompilerOptions &compiler_options; int indentation_level; int indentation_spaces; // The precedence of the last expression, using the table: @@ -133,9 +140,9 @@ class BaseCCPPVisitor : public ASR::BaseVisitor bool is_string_concat_present; BaseCCPPVisitor(diag::Diagnostics &diag, Platform &platform, - bool gen_stdstring, bool gen_stdcomplex, bool is_c, + CompilerOptions &_compiler_options, bool gen_stdstring, bool gen_stdcomplex, bool is_c, int64_t default_lower_bound) : diag{diag}, - platform{platform}, + platform{platform}, compiler_options{_compiler_options}, gen_stdstring{gen_stdstring}, gen_stdcomplex{gen_stdcomplex}, is_c{is_c}, global_scope{nullptr}, lower_bound{default_lower_bound}, template_number{0}, c_ds_api{std::make_unique(is_c, platform)}, @@ -584,6 +591,7 @@ R"(#include } void visit_FunctionCall(const ASR::FunctionCall_t &x) { + CHECK_FAST_C_CPP(compiler_options, x) ASR::Function_t *fn = ASR::down_cast( ASRUtils::symbol_get_past_external(x.m_name)); std::string fn_name = fn->m_name; @@ -642,11 +650,13 @@ R"(#include } void visit_SizeOfType(const ASR::SizeOfType_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) std::string c_type = CUtils::get_c_type_from_ttype_t(x.m_arg); src = "sizeof(" + c_type + ")"; } void visit_StringSection(const ASR::StringSection_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); std::string arg, left, right, step, left_present, rig_present; arg = src; @@ -677,11 +687,13 @@ R"(#include } void visit_StringChr(const ASR::StringChr_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); src = "_lfortran_str_chr(" + src + ")"; } void visit_StringOrd(const ASR::StringOrd_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); if (ASR::is_a(*x.m_arg)) { src = "(int)" + src + "[0]"; @@ -691,6 +703,7 @@ R"(#include } void visit_StringRepeat(const ASR::StringRepeat_t &x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_left); std::string s = src; self().visit_expr(*x.m_right); @@ -891,10 +904,7 @@ R"(#include void visit_StringConcat(const ASR::StringConcat_t& x) { is_string_concat_present = true; - if( x.m_value ) { - self().visit_expr(*x.m_value); - return ; - } + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_left); std::string left = std::move(src); self().visit_expr(*x.m_right); @@ -1049,6 +1059,7 @@ R"(#include } void visit_ListConcat(const ASR::ListConcat_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) ASR::List_t* t = ASR::down_cast(x.m_type); std::string list_concat_func = c_ds_api->get_list_concat_func(t); bracket_open++; @@ -1067,6 +1078,7 @@ R"(#include } void visit_ListSection(const ASR::ListSection_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) std::string left, right, step, l_present, r_present; bracket_open++; if (x.m_section.m_left) { @@ -1124,6 +1136,7 @@ R"(#include } void visit_ListCompare(const ASR::ListCompare_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) ASR::ttype_t* type = ASRUtils::expr_type(x.m_left); std::string list_cmp_func = c_ds_api->get_compare_func(type); bracket_open++; @@ -1173,28 +1186,19 @@ R"(#include } void visit_ListLen(const ASR::ListLen_t& x) { - if( x.m_value ) { - self().visit_expr(*x.m_value); - return ; - } + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); src = src + ".current_end_point"; } void visit_TupleLen(const ASR::TupleLen_t& x) { - if (x.m_value) { - self().visit_expr(*x.m_value); - return ; - } + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); src = src + ".length"; } void visit_DictLen(const ASR::DictLen_t& x) { - if ( x.m_value ) { - self().visit_expr(*x.m_value); - return ; - } + CHECK_FAST_C_CPP(compiler_options, x) ASR::ttype_t* t_ttype = ASRUtils::expr_type(x.m_arg); ASR::Dict_t* t = ASR::down_cast(t_ttype); std::string dict_len_fun = c_ds_api->get_dict_len_func(t); @@ -1205,10 +1209,7 @@ R"(#include } void visit_DictPop(const ASR::DictPop_t& x) { - if ( x.m_value ) { - self().visit_expr(*x.m_value); - return ; - } + CHECK_FAST_C_CPP(compiler_options, x) ASR::ttype_t* t_ttype = ASRUtils::expr_type(x.m_a); ASR::Dict_t* t = ASR::down_cast(t_ttype); std::string dict_pop_fun = c_ds_api->get_dict_pop_func(t); @@ -1222,10 +1223,7 @@ R"(#include } void visit_ListItem(const ASR::ListItem_t& x) { - if( x.m_value ) { - self().visit_expr(*x.m_value); - return ; - } + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_a); std::string list_var = std::move(src); self().visit_expr(*x.m_pos); @@ -1235,10 +1233,7 @@ R"(#include } void visit_TupleItem(const ASR::TupleItem_t& x) { - if (x.m_value) { - self().visit_expr(*x.m_value); - return ; - } + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_a); std::string tup_var = std::move(src); ASR::expr_t *pos_val = ASRUtils::expr_value(x.m_pos); @@ -1275,6 +1270,7 @@ R"(#include } void visit_StructInstanceMember(const ASR::StructInstanceMember_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) std::string der_expr, member; this->visit_expr(*x.m_v); der_expr = std::move(src); @@ -1289,6 +1285,7 @@ R"(#include } void visit_UnionInstanceMember(const ASR::UnionInstanceMember_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) std::string der_expr, member; this->visit_expr(*x.m_v); der_expr = std::move(src); @@ -1297,6 +1294,7 @@ R"(#include } void visit_Cast(const ASR::Cast_t &x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); switch (x.m_kind) { case (ASR::cast_kindType::IntegerToReal) : { @@ -1448,6 +1446,7 @@ R"(#include } void visit_IntegerBitLen(const ASR::IntegerBitLen_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_a); int arg_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); switch (arg_kind) { @@ -1482,6 +1481,7 @@ R"(#include template void handle_Compare(const T &x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_left); std::string left = std::move(src); int left_precedence = last_expr_precedence; @@ -1516,6 +1516,7 @@ R"(#include } void visit_IntegerBitNot(const ASR::IntegerBitNot_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); int expr_precedence = last_expr_precedence; last_expr_precedence = 3; @@ -1540,6 +1541,7 @@ R"(#include template void handle_UnaryMinus(const T &x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); int expr_precedence = last_expr_precedence; last_expr_precedence = 3; @@ -1552,6 +1554,7 @@ R"(#include void visit_ComplexRe(const ASR::ComplexRe_t &x) { headers.insert("complex"); + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); if (is_c) { src = "creal(" + src + ")"; @@ -1562,6 +1565,7 @@ R"(#include void visit_ComplexIm(const ASR::ComplexIm_t &x) { headers.insert("complex"); + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); if (is_c) { src = "cimag(" + src + ")"; @@ -1571,6 +1575,7 @@ R"(#include } void visit_LogicalNot(const ASR::LogicalNot_t &x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); int expr_precedence = last_expr_precedence; last_expr_precedence = 3; @@ -1582,6 +1587,7 @@ R"(#include } void visit_GetPointer(const ASR::GetPointer_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); std::string arg_src = std::move(src); std::string addr_prefix = "&"; @@ -1593,6 +1599,7 @@ R"(#include } void visit_PointerToCPtr(const ASR::PointerToCPtr_t& x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_arg); std::string arg_src = std::move(src); if( ASRUtils::is_array(ASRUtils::expr_type(x.m_arg)) ) { @@ -1616,6 +1623,7 @@ R"(#include template void handle_BinOp(const T &x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_left); std::string left = std::move(src); int left_precedence = last_expr_precedence; @@ -1672,6 +1680,7 @@ R"(#include } void visit_LogicalBinOp(const ASR::LogicalBinOp_t &x) { + CHECK_FAST_C_CPP(compiler_options, x) self().visit_expr(*x.m_left); std::string left = std::move(src); int left_precedence = last_expr_precedence; @@ -2041,6 +2050,7 @@ R"(#include void visit_IfExp(const ASR::IfExp_t &x) { // IfExp is like a ternary operator in c++ // test ? body : orelse; + CHECK_FAST_C_CPP(compiler_options, x) std::string out = "("; self().visit_expr(*x.m_test); out += src + ") ? ("; diff --git a/src/libasr/codegen/asr_to_cpp.cpp b/src/libasr/codegen/asr_to_cpp.cpp index 9735f72845..593bebafb4 100644 --- a/src/libasr/codegen/asr_to_cpp.cpp +++ b/src/libasr/codegen/asr_to_cpp.cpp @@ -77,9 +77,9 @@ class ASRToCPPVisitor : public BaseCCPPVisitor std::map>> eltypedims2arraytype; - ASRToCPPVisitor(diag::Diagnostics &diag, Platform &platform, + ASRToCPPVisitor(diag::Diagnostics &diag, CompilerOptions &co, int64_t default_lower_bound) - : BaseCCPPVisitor(diag, platform, true, true, false, + : BaseCCPPVisitor(diag, co.platform, co, true, true, false, default_lower_bound), array_types_decls(std::string("\nstruct dimension_descriptor\n" "{\n int32_t lower_bound, length;\n};\n")) {} @@ -739,13 +739,13 @@ Kokkos::View from_std_vector(const std::vector &v) }; Result asr_to_cpp(Allocator &al, ASR::TranslationUnit_t &asr, - diag::Diagnostics &diagnostics, Platform &platform, + diag::Diagnostics &diagnostics, CompilerOptions &co, int64_t default_lower_bound) { LCompilers::PassOptions pass_options; pass_options.always_run = true; pass_unused_functions(al, asr, pass_options); - ASRToCPPVisitor v(diagnostics, platform, default_lower_bound); + ASRToCPPVisitor v(diagnostics, co, default_lower_bound); try { v.visit_asr((ASR::asr_t &)asr); } catch (const CodeGenError &e) { From b89fadfe929ab66cf326ddb7940a3e7fbb35ace7 Mon Sep 17 00:00:00 2001 From: Smit-create Date: Thu, 16 Mar 2023 18:44:12 +0530 Subject: [PATCH 3/3] Fix variable decl order --- src/bin/lpython.cpp | 2 +- src/libasr/codegen/asr_to_c_cpp.h | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index 8a3646bd1d..9c2907dc2f 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -1248,7 +1248,7 @@ EMSCRIPTEN_KEEPALIVE char* emit_cpp_from_source(char *input) { out = diagnostics.render(lm, compiler_options); if (asr.ok) { auto res = LCompilers::asr_to_cpp(al, *asr.result, diagnostics, - compiler_options.platform, 0); + compiler_options, 0); out = diagnostics.render(lm, compiler_options); if (res.ok) { out += res.result; diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index 9abd8bef5e..5c4f0d68da 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -242,6 +242,7 @@ R"(#include if (ASR::is_a(*var_sym)) { ASR::Variable_t *v = ASR::down_cast(var_sym); std::string decl = self().convert_variable_decl(*v); + decl = check_tmp_buffer() + decl; bool used_define_for_const = (ASR::is_a(*v->m_type) && v->m_intent == ASRUtils::intent_local); if (used_define_for_const) { @@ -300,11 +301,12 @@ R"(#include ASR::symbol_t* var_sym = x.m_symtab->get_symbol(item); if (ASR::is_a(*var_sym)) { ASR::Variable_t *v = ASR::down_cast(var_sym); - decl += self().convert_variable_decl(*v); + std::string d = self().convert_variable_decl(*v); if( !ASR::is_a(*v->m_type) || v->m_intent == ASRUtils::intent_return_var ) { - decl += ";\n"; + d += ";\n"; } + decl += check_tmp_buffer() + d; } } @@ -336,11 +338,12 @@ R"(#include ASR::symbol_t* var_sym = block->m_symtab->get_symbol(item); if (ASR::is_a(*var_sym)) { ASR::Variable_t *v = ASR::down_cast(var_sym); - decl += indent + self().convert_variable_decl(*v); + std::string d = indent + self().convert_variable_decl(*v); if( !ASR::is_a(*v->m_type) || v->m_intent == ASRUtils::intent_return_var ) { - decl += ";\n"; + d += ";\n"; } + decl += check_tmp_buffer() + d; } } for (size_t i=0; in_body; i++) { @@ -539,11 +542,12 @@ R"(#include ASR::Variable_t *v = ASR::down_cast(var_sym); if (v->m_intent == ASRUtils::intent_local || v->m_intent == ASRUtils::intent_return_var) { - decl += indent + self().convert_variable_decl(*v); + std::string d = indent + self().convert_variable_decl(*v); if( !ASR::is_a(*v->m_type) || v->m_intent == ASRUtils::intent_return_var ) { - decl += ";\n"; + d += ";\n"; } + decl += check_tmp_buffer() + d; } if (ASR::is_a(*v->m_type)) { has_typevar = true;