From 2367d77fa25c0d131c30cb5f55af5739044c741c Mon Sep 17 00:00:00 2001 From: Smit-create Date: Tue, 28 Mar 2023 16:04:00 +0530 Subject: [PATCH 1/5] C: Support passes --- src/bin/lpython.cpp | 23 ++++++++++++++++++++--- src/libasr/codegen/asr_to_c.cpp | 9 +-------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index 913eadcccb..647ad5b2a5 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -262,6 +262,7 @@ int emit_cpp(const std::string &infile, int emit_c(const std::string &infile, const std::string &runtime_library_dir, + LCompilers::PassManager& pass_manager, CompilerOptions &compiler_options) { Allocator al(4*1024); @@ -293,6 +294,13 @@ int emit_c(const std::string &infile, } LCompilers::ASR::TranslationUnit_t* asr = r1.result; + // Apply ASR passes + LCompilers::PassOptions pass_options; + pass_manager.use_default_passes(); + pass_options.run_fun = "f"; + pass_options.always_run = true; + pass_manager.apply_passes(al, asr, pass_options, diagnostics); + diagnostics.diagnostics.clear(); auto res = LCompilers::asr_to_c(al, *asr, diagnostics, compiler_options, 0); std::cerr << diagnostics.render(lm, compiler_options); @@ -305,7 +313,7 @@ int emit_c(const std::string &infile, } int emit_c_to_file(const std::string &infile, const std::string &outfile, - const std::string &runtime_library_dir, + const std::string &runtime_library_dir, LCompilers::PassManager& pass_manager, CompilerOptions &compiler_options) { Allocator al(4*1024); @@ -337,6 +345,13 @@ int emit_c_to_file(const std::string &infile, const std::string &outfile, } LCompilers::ASR::TranslationUnit_t* asr = r1.result; + // Apply ASR passes + LCompilers::PassOptions pass_options; + pass_manager.use_default_passes(); + pass_options.run_fun = "f"; + pass_options.always_run = true; + pass_manager.apply_passes(al, asr, pass_options, diagnostics); + diagnostics.diagnostics.clear(); auto res = LCompilers::asr_to_c(al, *asr, diagnostics, compiler_options, 0); std::cerr << diagnostics.render(lm, compiler_options); @@ -1666,7 +1681,8 @@ int main(int argc, char *argv[]) return emit_cpp(arg_file, runtime_library_dir, compiler_options); } if (show_c) { - return emit_c(arg_file, runtime_library_dir, compiler_options); + return emit_c(arg_file, runtime_library_dir, lpython_pass_manager, + compiler_options); } if (show_wat) { return emit_wat(arg_file, runtime_library_dir, compiler_options); @@ -1741,7 +1757,8 @@ int main(int argc, char *argv[]) runtime_library_dir, compiler_options, time_report, backend); } else if (backend == Backend::c) { std::string emit_file_name = basename + "__tmp__generated__.c"; - err = emit_c_to_file(arg_file, emit_file_name, runtime_library_dir, compiler_options); + err = emit_c_to_file(arg_file, emit_file_name, runtime_library_dir, + lpython_pass_manager, compiler_options); err = link_executable({emit_file_name}, outfile, runtime_library_dir, backend, static_link, true, compiler_options, rtlib_header_dir); } else if (backend == Backend::llvm) { diff --git a/src/libasr/codegen/asr_to_c.cpp b/src/libasr/codegen/asr_to_c.cpp index ce82cb86e6..71329986ce 100644 --- a/src/libasr/codegen/asr_to_c.cpp +++ b/src/libasr/codegen/asr_to_c.cpp @@ -1290,17 +1290,10 @@ R"( } }; -Result asr_to_c(Allocator &al, ASR::TranslationUnit_t &asr, +Result asr_to_c(Allocator & /*al*/, ASR::TranslationUnit_t &asr, diag::Diagnostics &diagnostics, CompilerOptions &co, int64_t default_lower_bound) { - - LCompilers::PassOptions pass_options; - pass_options.always_run = true; - pass_create_subroutine_from_function(al, asr, pass_options); - 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, co, default_lower_bound); try { v.visit_asr((ASR::asr_t &)asr); From 8b0357d54cd0a62bd200ae2dd11c2d88d16bca35 Mon Sep 17 00:00:00 2001 From: Smit-create Date: Mon, 3 Apr 2023 12:06:23 +0530 Subject: [PATCH 2/5] C: Fix goto --- src/libasr/codegen/asr_to_c.cpp | 8 -------- src/libasr/codegen/asr_to_c_cpp.h | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/libasr/codegen/asr_to_c.cpp b/src/libasr/codegen/asr_to_c.cpp index 71329986ce..bfad7791f8 100644 --- a/src/libasr/codegen/asr_to_c.cpp +++ b/src/libasr/codegen/asr_to_c.cpp @@ -1280,14 +1280,6 @@ R"( src = "strlen(" + src + ")"; } - void visit_GoTo(const ASR::GoTo_t &x) { - std::string indent(indentation_level*indentation_spaces, ' '); - src = indent + "goto " + std::string(x.m_name) + ";\n"; - } - - void visit_GoToTarget(const ASR::GoToTarget_t &x) { - src = std::string(x.m_name) + ":\n"; - } }; Result asr_to_c(Allocator & /*al*/, ASR::TranslationUnit_t &asr, diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index fb69904bcb..fc4efa8440 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -102,6 +102,7 @@ class BaseCCPPVisitor : public ASR::BaseVisitor const ASR::Function_t *current_function = nullptr; std::map sym_info; std::map const_var_names; + std::map gotoid2name; // Output configuration: // Use std::string or char* @@ -331,6 +332,15 @@ R"(#include std::string indent(indentation_level*indentation_spaces, ' '); std::string open_paranthesis = indent + "{\n"; std::string close_paranthesis = indent + "}\n"; + if (x.m_label != -1) { + std::string b_name; + if (gotoid2name.find(x.m_label) != gotoid2name.end()) { + b_name = gotoid2name[x.m_label]; + } else { + b_name = "__" +std::to_string(x.m_label); + } + open_paranthesis = indent + b_name + ": {\n"; + } indent += std::string(indentation_spaces, ' '); indentation_level += 1; SymbolTable* current_scope_copy = current_scope; @@ -1911,6 +1921,12 @@ R"(#include } } + void visit_GoTo(const ASR::GoTo_t &x) { + std::string indent(indentation_level*indentation_spaces, ' '); + src = indent + "goto " + std::string(x.m_name) + ";\n"; + gotoid2name[x.m_target_id] = std::string(x.m_name); + } + void visit_GoToTarget(const ASR::GoToTarget_t & /* x */) { // Ignore for now src = ""; From a166236d1ccc5a9d6c49c44f7e9751223de339f1 Mon Sep 17 00:00:00 2001 From: Smit-create Date: Mon, 3 Apr 2023 12:22:31 +0530 Subject: [PATCH 3/5] Use names compatible with C --- src/libasr/pass/pass_list_expr.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libasr/pass/pass_list_expr.cpp b/src/libasr/pass/pass_list_expr.cpp index efabbd28ab..a0cf68740c 100644 --- a/src/libasr/pass/pass_list_expr.cpp +++ b/src/libasr/pass/pass_list_expr.cpp @@ -152,7 +152,7 @@ class ListExprReplacer : public ASR::BaseExprReplacer */ SymbolTable* list_section_symtab = al.make_new(global_scope); - std::string list_type_name = ASRUtils::type_to_str_python(list_type); + std::string list_type_name = ASRUtils::get_type_code(list_type, true); std::string fn_name = global_scope->get_unique_name("_lcompilers_list_section_" + list_type_name); ASR::ttype_t* item_type = ASR::down_cast(list_type)->m_type; ASR::ttype_t* int_type = ASRUtils::TYPE(ASR::make_Integer_t( @@ -409,7 +409,7 @@ class ListExprReplacer : public ASR::BaseExprReplacer call_arg.m_value = is_end_present; args.push_back(al, call_arg); - std::string list_type_name = ASRUtils::type_to_str_python(x->m_type); + std::string list_type_name = ASRUtils::get_type_code(x->m_type, true); if (list_section_func_map.find(list_type_name) == list_section_func_map.end()) { create_list_section_func(unit.base.base.loc, unit.m_global_scope, x->m_type); @@ -437,7 +437,7 @@ class ListExprReplacer : public ASR::BaseExprReplacer return result_list */ SymbolTable* list_concat_symtab = al.make_new(global_scope); - std::string list_type_name = ASRUtils::type_to_str_python(list_type); + std::string list_type_name = ASRUtils::get_type_code(list_type, true); std::string fn_name = global_scope->get_unique_name("_lcompilers_list_concat_" + list_type_name); Vec arg_exprs; @@ -535,7 +535,7 @@ class ListExprReplacer : public ASR::BaseExprReplacer right_list.loc = x->m_right->base.loc; right_list.m_value = x->m_right; args.push_back(al, right_list); - std::string list_type_name = ASRUtils::type_to_str_python(x->m_type); + std::string list_type_name = ASRUtils::get_type_code(x->m_type, true); if (list_concat_func_map.find(list_type_name) == list_concat_func_map.end()) { create_concat_function(unit.base.base.loc, unit.m_global_scope, x->m_type); From 468ff6d55aeb00d3867bb84de11658ba20f6d9f9 Mon Sep 17 00:00:00 2001 From: Smit-create Date: Mon, 3 Apr 2023 12:44:18 +0530 Subject: [PATCH 4/5] Skip passes that are re-writes and handled in C --- src/bin/lpython.cpp | 4 ++-- src/libasr/pass/pass_manager.h | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index 647ad5b2a5..91db0e112d 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -296,7 +296,7 @@ int emit_c(const std::string &infile, // Apply ASR passes LCompilers::PassOptions pass_options; - pass_manager.use_default_passes(); + pass_manager.use_default_passes(true); pass_options.run_fun = "f"; pass_options.always_run = true; pass_manager.apply_passes(al, asr, pass_options, diagnostics); @@ -347,7 +347,7 @@ int emit_c_to_file(const std::string &infile, const std::string &outfile, // Apply ASR passes LCompilers::PassOptions pass_options; - pass_manager.use_default_passes(); + pass_manager.use_default_passes(true); pass_options.run_fun = "f"; pass_options.always_run = true; pass_manager.apply_passes(al, asr, pass_options, diagnostics); diff --git a/src/libasr/pass/pass_manager.h b/src/libasr/pass/pass_manager.h index 3f3bcddb66..e66ebb650e 100644 --- a/src/libasr/pass/pass_manager.h +++ b/src/libasr/pass/pass_manager.h @@ -59,7 +59,7 @@ namespace LCompilers { std::vector _passes; std::vector _with_optimization_passes; std::vector _user_defined_passes; - std::vector _skip_passes; + std::vector _skip_passes, _c_skip_passes; std::map _passes_db = { {"do_loops", &pass_replace_do_loops}, {"global_stmts", &pass_wrap_global_stmts_into_function}, @@ -90,6 +90,7 @@ namespace LCompilers { bool is_fast; bool apply_default_passes; + bool c_skip_pass; // This will contain the passes that are to be skipped in C void _apply_passes(Allocator& al, ASR::TranslationUnit_t* asr, std::vector& passes, PassOptions &pass_options, @@ -103,6 +104,9 @@ namespace LCompilers { if (rtlib && passes[i] == "unused_functions") continue; if( std::find(_skip_passes.begin(), _skip_passes.end(), passes[i]) != _skip_passes.end()) continue; + if (c_skip_pass && std::find(_c_skip_passes.begin(), + _c_skip_passes.end(), passes[i]) != _c_skip_passes.end()) + continue; _passes_db[passes[i]](al, *asr, pass_options); #if defined(WITH_LFORTRAN_ASSERT) if (!asr_verify(*asr, true, diagnostics)) { @@ -142,7 +146,8 @@ namespace LCompilers { } } - PassManager(): is_fast{false}, apply_default_passes{false} { + PassManager(): is_fast{false}, apply_default_passes{false}, + c_skip_pass{false} { _passes = { "global_stmts", "init_expr", @@ -191,6 +196,12 @@ namespace LCompilers { "inline_function_calls" }; + // These are well re-write passes which are already handled + // appropriately in C backend. + _c_skip_passes = { + "pass_list_expr", + "print_list_tuple" + }; _user_defined_passes.clear(); } @@ -227,8 +238,9 @@ namespace LCompilers { is_fast = false; } - void use_default_passes() { + void use_default_passes(bool _c_skip_pass=false) { apply_default_passes = true; + c_skip_pass = _c_skip_pass; } void do_not_use_default_passes() { From 5b3893323a59e6dc8fc313bffc7da65265a3fdab Mon Sep 17 00:00:00 2001 From: Smit-create Date: Tue, 4 Apr 2023 18:21:33 +0530 Subject: [PATCH 5/5] Add GotoTarget, skip do_loops/inline pass --- src/libasr/codegen/asr_to_c_cpp.h | 5 ++--- src/libasr/pass/pass_manager.h | 6 ++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index fc4efa8440..aa3cbfbfb2 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -1927,9 +1927,8 @@ R"(#include gotoid2name[x.m_target_id] = std::string(x.m_name); } - void visit_GoToTarget(const ASR::GoToTarget_t & /* x */) { - // Ignore for now - src = ""; + void visit_GoToTarget(const ASR::GoToTarget_t &x) { + src = std::string(x.m_name) + ":\n"; } void visit_Stop(const ASR::Stop_t &x) { diff --git a/src/libasr/pass/pass_manager.h b/src/libasr/pass/pass_manager.h index e66ebb650e..8dfb256c7c 100644 --- a/src/libasr/pass/pass_manager.h +++ b/src/libasr/pass/pass_manager.h @@ -196,11 +196,13 @@ namespace LCompilers { "inline_function_calls" }; - // These are well re-write passes which are already handled + // These are re-write passes which are already handled // appropriately in C backend. _c_skip_passes = { "pass_list_expr", - "print_list_tuple" + "print_list_tuple", + "do_loops", + "inline_function_calls" }; _user_defined_passes.clear(); }