diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index 061eb01c2d..423a8b7a83 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -165,7 +165,10 @@ int emit_asr(const std::string &infile, return 2; } LFortran::ASR::TranslationUnit_t* asr = r.result; - pass_manager.apply_passes(al, asr, "f", true); + LCompilers::PassOptions pass_options; + pass_options.run_fun = "f"; + pass_options.always_run = true; + pass_manager.apply_passes(al, asr, pass_options); if (compiler_options.tree) { std::cout << LFortran::pickle_tree(*asr, compiler_options.use_colors, @@ -304,33 +307,33 @@ int get_symbols (const std::string &infile, rapidjson::Document end_detail(rapidjson::kObjectType); rapidjson::Document location_object(rapidjson::kObjectType); rapidjson::Document test_capture(rapidjson::kObjectType); - + test_output.SetArray(); - + for (auto symbol : symbol_lists) { uint32_t start_character = symbol.first_column; uint32_t start_line = symbol.first_line; uint32_t end_character = symbol.last_column; uint32_t end_line = symbol.last_line; std::string name = symbol.symbol_name; - + range_object.SetObject(); rapidjson::Document::AllocatorType &allocator = range_object.GetAllocator(); - + start_detail.SetObject(); start_detail.AddMember("character", rapidjson::Value().SetInt(start_character), allocator); start_detail.AddMember("line", rapidjson::Value().SetInt(start_line), allocator); range_object.AddMember("start", start_detail, allocator); - + end_detail.SetObject(); end_detail.AddMember("character", rapidjson::Value().SetInt(end_character), allocator); end_detail.AddMember("line", rapidjson::Value().SetInt(end_line), allocator); range_object.AddMember("end", end_detail, allocator); - + location_object.SetObject(); location_object.AddMember("range", range_object, allocator); location_object.AddMember("uri", rapidjson::Value().SetString("uri", allocator), allocator); - + test_capture.SetObject(); test_capture.AddMember("kind", rapidjson::Value().SetInt(1), allocator); test_capture.AddMember("location", location_object, allocator); @@ -342,16 +345,16 @@ int get_symbols (const std::string &infile, rapidjson::Writer writer(buffer); test_output.Accept(writer); std::string resp_str( buffer.GetString() ); - + std::cout << resp_str; } else { std::cout << "{}\n"; } - + return 0; } - + int get_errors (const std::string &infile, const std::string &runtime_library_dir, @@ -363,7 +366,7 @@ int get_errors (const std::string &infile, std::string input = LFortran::read_file(infile); lm.init_simple(input); LFortran::Result - r1 = LFortran::parse_python_file(al, runtime_library_dir, infile, + r1 = LFortran::parse_python_file(al, runtime_library_dir, infile, diagnostics, compiler_options.new_parser); if (r1.ok) { LFortran::LPython::AST::ast_t* ast = r1.result; @@ -396,7 +399,7 @@ int get_errors (const std::string &infile, } } rapidjson::Document range_obj(rapidjson::kObjectType); - rapidjson::Document start_detail(rapidjson::kObjectType); + rapidjson::Document start_detail(rapidjson::kObjectType); rapidjson::Document end_detail(rapidjson::kObjectType); rapidjson::Document diag_results(rapidjson::kArrayType); rapidjson::Document diag_capture(rapidjson::kObjectType); @@ -411,7 +414,7 @@ int get_errors (const std::string &infile, std::string msg = diag.message; range_obj.SetObject(); - rapidjson::Document::AllocatorType &allocator = range_obj.GetAllocator(); + rapidjson::Document::AllocatorType &allocator = range_obj.GetAllocator(); start_detail.SetObject(); start_detail.AddMember("line", rapidjson::Value().SetInt(start_line), allocator); diff --git a/src/libasr/codegen/asr_to_c.cpp b/src/libasr/codegen/asr_to_c.cpp index 769a4efe85..278ced37ef 100644 --- a/src/libasr/codegen/asr_to_c.cpp +++ b/src/libasr/codegen/asr_to_c.cpp @@ -655,8 +655,11 @@ Result asr_to_c(Allocator &al, ASR::TranslationUnit_t &asr, diag::Diagnostics &diagnostics, Platform &platform, int64_t default_lower_bound) { - pass_unused_functions(al, asr, true); - pass_replace_class_constructor(al, asr); + + LCompilers::PassOptions pass_options; + pass_options.always_run = true; + pass_unused_functions(al, asr, pass_options); + pass_replace_class_constructor(al, asr, pass_options); ASRToCVisitor v(diagnostics, platform, default_lower_bound); try { v.visit_asr((ASR::asr_t &)asr); diff --git a/src/libasr/codegen/asr_to_cpp.cpp b/src/libasr/codegen/asr_to_cpp.cpp index 0d544dcce1..c77dc3e428 100644 --- a/src/libasr/codegen/asr_to_cpp.cpp +++ b/src/libasr/codegen/asr_to_cpp.cpp @@ -699,7 +699,9 @@ Result asr_to_cpp(Allocator &al, ASR::TranslationUnit_t &asr, diag::Diagnostics &diagnostics, Platform &platform, int64_t default_lower_bound) { - pass_unused_functions(al, asr, true); + LCompilers::PassOptions pass_options; + pass_options.always_run = true; + pass_unused_functions(al, asr, pass_options); ASRToCPPVisitor v(diagnostics, platform, default_lower_bound); try { v.visit_asr((ASR::asr_t &)asr); diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index f3fb73441c..94c8d9f37e 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -5430,7 +5430,10 @@ Result> asr_to_llvm(ASR::TranslationUnit_t &asr, Platform platform, const std::string &run_fn) { ASRToLLVMVisitor v(al, context, platform, diagnostics); - pass_manager.apply_passes(al, &asr, run_fn, false); + LCompilers::PassOptions pass_options; + pass_options.run_fun = run_fn; + pass_options.always_run = false; + pass_manager.apply_passes(al, &asr, pass_options); // Uncomment for debugging the ASR after the transformation // std::cout << pickle(asr, true, true, true) << std::endl; diff --git a/src/libasr/codegen/asr_to_wasm.cpp b/src/libasr/codegen/asr_to_wasm.cpp index 2989a85eb8..7b3fb2078c 100644 --- a/src/libasr/codegen/asr_to_wasm.cpp +++ b/src/libasr/codegen/asr_to_wasm.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -1532,9 +1533,11 @@ Result> asr_to_wasm_bytes_stream(ASR::TranslationUnit_t &asr, Alloc ASRToWASMVisitor v(al, diagnostics); Vec wasm_bytes; - pass_unused_functions(al, asr, true); - pass_replace_do_loops(al, asr); - pass_propagate_arr_dims(al, asr); + LCompilers::PassOptions pass_options; + pass_replace_do_loops(al, asr, pass_options); + pass_array_by_data(al, asr, pass_options); + pass_options.always_run = true; + pass_unused_functions(al, asr, pass_options); // std::cout << pickle(asr, true /* use colors */, true /* indent */, // true /* with_intrinsic_modules */) << std::endl; diff --git a/src/libasr/codegen/asr_to_x86.cpp b/src/libasr/codegen/asr_to_x86.cpp index 613d940067..37cd590efe 100644 --- a/src/libasr/codegen/asr_to_x86.cpp +++ b/src/libasr/codegen/asr_to_x86.cpp @@ -532,16 +532,19 @@ Result asr_to_x86(ASR::TranslationUnit_t &asr, Allocator &al, ASRToX86Visitor v(al); + LCompilers::PassOptions pass_options; + pass_options.run_fun = "f"; + { auto t1 = std::chrono::high_resolution_clock::now(); - pass_wrap_global_stmts_into_function(al, asr, "f"); + pass_wrap_global_stmts_into_function(al, asr, pass_options); auto t2 = std::chrono::high_resolution_clock::now(); time_pass_global = std::chrono::duration_cast(t2 - t1).count(); } { auto t1 = std::chrono::high_resolution_clock::now(); - pass_replace_do_loops(al, asr); + pass_replace_do_loops(al, asr, pass_options); auto t2 = std::chrono::high_resolution_clock::now(); time_pass_do_loops = std::chrono::duration_cast(t2 - t1).count(); } diff --git a/src/libasr/pass/arr_slice.cpp b/src/libasr/pass/arr_slice.cpp index 9f7f15c221..6148ca010d 100644 --- a/src/libasr/pass/arr_slice.cpp +++ b/src/libasr/pass/arr_slice.cpp @@ -274,7 +274,8 @@ class ArrSliceVisitor : public PassUtils::PassVisitor }; void pass_replace_arr_slice(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string &rl_path) { + const LCompilers::PassOptions& pass_options) { + std::string rl_path = pass_options.runtime_library_dir; ArrSliceVisitor v(al, rl_path); v.visit_TranslationUnit(unit); LFORTRAN_ASSERT(asr_verify(unit)); diff --git a/src/libasr/pass/arr_slice.h b/src/libasr/pass/arr_slice.h index 79b0f2c38f..0393f465b1 100644 --- a/src/libasr/pass/arr_slice.h +++ b/src/libasr/pass/arr_slice.h @@ -2,11 +2,12 @@ #define LFORTRAN_PASS_ARR_SLICE_H #include +#include namespace LFortran { void pass_replace_arr_slice(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string &rl_path); + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/array_op.cpp b/src/libasr/pass/array_op.cpp index b1c59e8fba..a2c273a8c1 100644 --- a/src/libasr/pass/array_op.cpp +++ b/src/libasr/pass/array_op.cpp @@ -929,7 +929,8 @@ class ArrayOpVisitor : public PassUtils::PassVisitor }; void pass_replace_array_op(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string &rl_path) { + const LCompilers::PassOptions& pass_options) { + std::string rl_path = pass_options.runtime_library_dir; ArrayOpVisitor v(al, rl_path); v.visit_TranslationUnit(unit); LFORTRAN_ASSERT(asr_verify(unit)); diff --git a/src/libasr/pass/array_op.h b/src/libasr/pass/array_op.h index 5967cabff8..a3c888969e 100644 --- a/src/libasr/pass/array_op.h +++ b/src/libasr/pass/array_op.h @@ -2,11 +2,12 @@ #define LFORTRAN_PASS_ARRAY_OP_H #include +#include namespace LFortran { void pass_replace_array_op(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string &rl_path); + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/class_constructor.cpp b/src/libasr/pass/class_constructor.cpp index e9e38d56c7..04f299bf4a 100644 --- a/src/libasr/pass/class_constructor.cpp +++ b/src/libasr/pass/class_constructor.cpp @@ -54,7 +54,8 @@ class ClassConstructorVisitor : public PassUtils::PassVisitor +#include namespace LFortran { - void pass_replace_class_constructor(Allocator &al, ASR::TranslationUnit_t &unit); + void pass_replace_class_constructor(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/dead_code_removal.cpp b/src/libasr/pass/dead_code_removal.cpp index 7a9b93a9b3..d1dda818f1 100644 --- a/src/libasr/pass/dead_code_removal.cpp +++ b/src/libasr/pass/dead_code_removal.cpp @@ -99,7 +99,8 @@ class DeadCodeRemovalVisitor : public PassUtils::PassVisitor +#include namespace LFortran { - void pass_dead_code_removal(Allocator &al, ASR::TranslationUnit_t &unit, const std::string& rl_path); + void pass_dead_code_removal(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/div_to_mul.cpp b/src/libasr/pass/div_to_mul.cpp index a4cfeccb0e..72f48768b9 100644 --- a/src/libasr/pass/div_to_mul.cpp +++ b/src/libasr/pass/div_to_mul.cpp @@ -78,7 +78,8 @@ class DivToMulVisitor : public PassUtils::PassVisitor }; void pass_replace_div_to_mul(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string& rl_path) { + const LCompilers::PassOptions& pass_options) { + std::string rl_path = pass_options.runtime_library_dir; DivToMulVisitor v(al, rl_path); v.visit_TranslationUnit(unit); LFORTRAN_ASSERT(asr_verify(unit)); diff --git a/src/libasr/pass/div_to_mul.h b/src/libasr/pass/div_to_mul.h index 35adaf5367..fa78283ba5 100644 --- a/src/libasr/pass/div_to_mul.h +++ b/src/libasr/pass/div_to_mul.h @@ -2,10 +2,12 @@ #define LIBASR_PASS_DIV_TO_MUL_H #include +#include namespace LFortran { - void pass_replace_div_to_mul(Allocator &al, ASR::TranslationUnit_t &unit, const std::string& rl_path); + void pass_replace_div_to_mul(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/do_loops.cpp b/src/libasr/pass/do_loops.cpp index 08ff835c84..42365ff2f5 100644 --- a/src/libasr/pass/do_loops.cpp +++ b/src/libasr/pass/do_loops.cpp @@ -44,7 +44,8 @@ class DoLoopVisitor : public ASR::StatementWalkVisitor } }; -void pass_replace_do_loops(Allocator &al, ASR::TranslationUnit_t &unit) { +void pass_replace_do_loops(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& /*pass_options*/) { DoLoopVisitor v(al); // Each call transforms only one layer of nested loops, so we call it twice // to transform doubly nested loops: diff --git a/src/libasr/pass/do_loops.h b/src/libasr/pass/do_loops.h index 2e7705a8ca..e0870c2a25 100644 --- a/src/libasr/pass/do_loops.h +++ b/src/libasr/pass/do_loops.h @@ -2,10 +2,12 @@ #define LFORTRAN_PASS_DO_LOOPS_H #include +#include namespace LFortran { - void pass_replace_do_loops(Allocator &al, ASR::TranslationUnit_t &unit); + void pass_replace_do_loops(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/flip_sign.cpp b/src/libasr/pass/flip_sign.cpp index 88205d2829..885076b5ec 100644 --- a/src/libasr/pass/flip_sign.cpp +++ b/src/libasr/pass/flip_sign.cpp @@ -209,7 +209,8 @@ class FlipSignVisitor : public PassUtils::SkipOptimizationFunctionVisitor +#include namespace LFortran { - void pass_replace_flip_sign(Allocator &al, ASR::TranslationUnit_t &unit, const std::string& rl_path); + void pass_replace_flip_sign(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/fma.cpp b/src/libasr/pass/fma.cpp index 3a2e7b3e6a..f5b05ec4f1 100644 --- a/src/libasr/pass/fma.cpp +++ b/src/libasr/pass/fma.cpp @@ -166,7 +166,8 @@ class FMAVisitor : public PassUtils::SkipOptimizationFunctionVisitor }; void pass_replace_fma(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string& rl_path) { + const LCompilers::PassOptions& pass_options) { + std::string rl_path = pass_options.runtime_library_dir; FMAVisitor v(al, unit, rl_path); v.visit_TranslationUnit(unit); LFORTRAN_ASSERT(asr_verify(unit)); diff --git a/src/libasr/pass/fma.h b/src/libasr/pass/fma.h index 3e5317bd48..9721270952 100644 --- a/src/libasr/pass/fma.h +++ b/src/libasr/pass/fma.h @@ -2,10 +2,12 @@ #define LIBASR_PASS_FMA_H #include +#include namespace LFortran { - void pass_replace_fma(Allocator &al, ASR::TranslationUnit_t &unit, const std::string& rl_path); + void pass_replace_fma(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/for_all.cpp b/src/libasr/pass/for_all.cpp index 83cf461370..b467e4af5a 100644 --- a/src/libasr/pass/for_all.cpp +++ b/src/libasr/pass/for_all.cpp @@ -43,7 +43,8 @@ class ForAllVisitor : public ASR::StatementWalkVisitor } }; -void pass_replace_forall(Allocator &al, ASR::TranslationUnit_t &unit) { +void pass_replace_forall(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& /*pass_options*/) { ForAllVisitor v(al); v.visit_TranslationUnit(unit); LFORTRAN_ASSERT(asr_verify(unit)); diff --git a/src/libasr/pass/for_all.h b/src/libasr/pass/for_all.h index 7a10b48627..6fdf39fc43 100644 --- a/src/libasr/pass/for_all.h +++ b/src/libasr/pass/for_all.h @@ -2,10 +2,12 @@ #define LFORTRAN_PASS_FOR_ALL #include +#include namespace LFortran { - void pass_replace_forall(Allocator &al, ASR::TranslationUnit_t &unit); + void pass_replace_forall(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/global_stmts.cpp b/src/libasr/pass/global_stmts.cpp index c88e0ae8ba..09c863612c 100644 --- a/src/libasr/pass/global_stmts.cpp +++ b/src/libasr/pass/global_stmts.cpp @@ -18,7 +18,8 @@ using LFortran::ASRUtils::EXPR; * */ void pass_wrap_global_stmts_into_function(Allocator &al, - ASR::TranslationUnit_t &unit, const std::string &fn_name_s) { + ASR::TranslationUnit_t &unit, const LCompilers::PassOptions& pass_options) { + std::string fn_name_s = pass_options.run_fun; if (unit.n_items > 0) { // Add an anonymous function Str s; diff --git a/src/libasr/pass/global_stmts.h b/src/libasr/pass/global_stmts.h index 29725e122d..67730614db 100644 --- a/src/libasr/pass/global_stmts.h +++ b/src/libasr/pass/global_stmts.h @@ -2,11 +2,12 @@ #define LFORTRAN_PASS_GLOBAL_STMTS_H #include +#include namespace LFortran { - void pass_wrap_global_stmts_into_function(Allocator &al, - ASR::TranslationUnit_t &unit, const std::string &fn_name_s); + void pass_wrap_global_stmts_into_function(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/global_stmts_program.cpp b/src/libasr/pass/global_stmts_program.cpp index 197b1f79b7..4ced08012a 100644 --- a/src/libasr/pass/global_stmts_program.cpp +++ b/src/libasr/pass/global_stmts_program.cpp @@ -18,13 +18,14 @@ using LFortran::ASRUtils::EXPR; * */ void pass_wrap_global_stmts_into_program(Allocator &al, - ASR::TranslationUnit_t &unit, const std::string &program_fn_name) { + ASR::TranslationUnit_t &unit, const LCompilers::PassOptions& pass_options) { + std::string program_fn_name = pass_options.run_fun; SymbolTable *current_scope = al.make_new(unit.m_global_scope); std::string prog_name = "main_program"; Vec prog_body; prog_body.reserve(al, 1); if (unit.n_items > 0) { - pass_wrap_global_stmts_into_function(al, unit, program_fn_name); + pass_wrap_global_stmts_into_function(al, unit, pass_options); ASR::symbol_t *fn = unit.m_global_scope->get_symbol(program_fn_name); if (ASR::is_a(*fn) && ASR::down_cast(fn)->m_return_var == nullptr) { diff --git a/src/libasr/pass/global_stmts_program.h b/src/libasr/pass/global_stmts_program.h index 9fc17fe43d..b9547ed7aa 100644 --- a/src/libasr/pass/global_stmts_program.h +++ b/src/libasr/pass/global_stmts_program.h @@ -2,11 +2,12 @@ #define LIBASR_PASS_GLOBAL_STMTS_PROGRAM_H #include +#include namespace LFortran { - void pass_wrap_global_stmts_into_program(Allocator &al, - ASR::TranslationUnit_t &unit, const std::string &program_fn_name); + void pass_wrap_global_stmts_into_program(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/implied_do_loops.cpp b/src/libasr/pass/implied_do_loops.cpp index 2c8f3eb498..e0024f5159 100644 --- a/src/libasr/pass/implied_do_loops.cpp +++ b/src/libasr/pass/implied_do_loops.cpp @@ -244,7 +244,8 @@ class ImpliedDoLoopVisitor : public PassUtils::PassVisitor }; void pass_replace_implied_do_loops(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string &rl_path) { + const LCompilers::PassOptions& pass_options) { + std::string rl_path = pass_options.runtime_library_dir; ImpliedDoLoopVisitor v(al, unit, rl_path); v.visit_TranslationUnit(unit); LFORTRAN_ASSERT(asr_verify(unit)); diff --git a/src/libasr/pass/implied_do_loops.h b/src/libasr/pass/implied_do_loops.h index 0c1dfe5534..eef6b9ce9e 100644 --- a/src/libasr/pass/implied_do_loops.h +++ b/src/libasr/pass/implied_do_loops.h @@ -2,11 +2,12 @@ #define LFORTRAN_PASS_IMPLIED_DO_LOOPS_H #include +#include namespace LFortran { void pass_replace_implied_do_loops(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string &rl_path); + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/inline_function_calls.cpp b/src/libasr/pass/inline_function_calls.cpp index 3183092da2..491ca0b1f1 100644 --- a/src/libasr/pass/inline_function_calls.cpp +++ b/src/libasr/pass/inline_function_calls.cpp @@ -445,8 +445,9 @@ class InlineFunctionCallVisitor : public PassUtils::PassVisitor +#include namespace LFortran { void pass_inline_function_calls(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string& rl_path, - bool inline_external_symbol_calls=true); + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/loop_unroll.cpp b/src/libasr/pass/loop_unroll.cpp index d3bbec882a..139daa51ad 100644 --- a/src/libasr/pass/loop_unroll.cpp +++ b/src/libasr/pass/loop_unroll.cpp @@ -107,8 +107,9 @@ class LoopUnrollVisitor : public PassUtils::PassVisitor }; void pass_loop_unroll(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string& rl_path, - int64_t unroll_factor) { + const LCompilers::PassOptions& pass_options) { + std::string rl_path = pass_options.runtime_library_dir; + int64_t unroll_factor = pass_options.unroll_factor; LoopUnrollVisitor v(al, rl_path, unroll_factor); v.visit_TranslationUnit(unit); LFORTRAN_ASSERT(asr_verify(unit)); diff --git a/src/libasr/pass/loop_unroll.h b/src/libasr/pass/loop_unroll.h index ba8c403150..80214c8d48 100644 --- a/src/libasr/pass/loop_unroll.h +++ b/src/libasr/pass/loop_unroll.h @@ -2,11 +2,12 @@ #define LIBASR_PASS_LOOP_UNROLL_H #include +#include namespace LFortran { void pass_loop_unroll(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string& rl_path, int64_t unroll_factor=32); + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/loop_vectorise.cpp b/src/libasr/pass/loop_vectorise.cpp index c6a38a1713..f8127cc2ef 100644 --- a/src/libasr/pass/loop_vectorise.cpp +++ b/src/libasr/pass/loop_vectorise.cpp @@ -189,7 +189,8 @@ class LoopVectoriseVisitor : public PassUtils::SkipOptimizationFunctionVisitor +#include namespace LFortran { void pass_loop_vectorise(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string& rl_path); + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/param_to_const.cpp b/src/libasr/pass/param_to_const.cpp index fbf68aa093..043eed0197 100644 --- a/src/libasr/pass/param_to_const.cpp +++ b/src/libasr/pass/param_to_const.cpp @@ -194,7 +194,8 @@ class VarVisitor : public ASR::BaseWalkVisitor } }; -void pass_replace_param_to_const(Allocator &al, ASR::TranslationUnit_t &unit) { +void pass_replace_param_to_const(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& /*pass_options*/) { VarVisitor v(al); v.visit_TranslationUnit(unit); LFORTRAN_ASSERT(asr_verify(unit)); diff --git a/src/libasr/pass/param_to_const.h b/src/libasr/pass/param_to_const.h index 16b603515d..b5117cdc22 100644 --- a/src/libasr/pass/param_to_const.h +++ b/src/libasr/pass/param_to_const.h @@ -2,10 +2,12 @@ #define LFORTRAN_PASS_PARAM_TO_CONST_H #include +#include namespace LFortran { - void pass_replace_param_to_const(Allocator &al, ASR::TranslationUnit_t &unit); + void pass_replace_param_to_const(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/pass_array_by_data.cpp b/src/libasr/pass/pass_array_by_data.cpp index 5f406b0bb6..93a9e1c5e7 100644 --- a/src/libasr/pass/pass_array_by_data.cpp +++ b/src/libasr/pass/pass_array_by_data.cpp @@ -345,7 +345,8 @@ class RemoveArrayByDescriptorProceduresVisitor : public PassUtils::PassVisitor +#include namespace LFortran { - void pass_array_by_data(Allocator &al, ASR::TranslationUnit_t &unit); + void pass_array_by_data(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/pass_manager.h b/src/libasr/pass/pass_manager.h index c134e84826..5aa72d0c8f 100644 --- a/src/libasr/pass/pass_manager.h +++ b/src/libasr/pass/pass_manager.h @@ -43,133 +43,46 @@ namespace LCompilers { - enum ASRPass { - do_loops, global_stmts, implied_do_loops, array_op, - arr_slice, print_arr, class_constructor, unused_functions, - flip_sign, div_to_mul, fma, sign_from_value, - inline_function_calls, loop_unroll, dead_code_removal, - forall, select_case, loop_vectorise, - array_dim_intrinsics_update, pass_array_by_data - }; + typedef void (*pass_function)(Allocator&, LFortran::ASR::TranslationUnit_t&, + const LCompilers::PassOptions&); class PassManager { private: - std::vector _passes; - std::vector _with_optimization_passes; - std::vector _user_defined_passes; - std::map _passes_db = { - {"do_loops", ASRPass::do_loops}, - {"global_stmts", ASRPass::global_stmts}, - {"implied_do_loops", ASRPass::implied_do_loops}, - {"array_op", ASRPass::array_op}, - {"arr_slice", ASRPass::arr_slice}, - {"print_arr", ASRPass::print_arr}, - {"class_constructor", ASRPass::class_constructor}, - {"unused_functions", ASRPass::unused_functions}, - {"flip_sign", ASRPass::flip_sign}, - {"div_to_mul", ASRPass::div_to_mul}, - {"fma", ASRPass::fma}, - {"sign_from_value", ASRPass::sign_from_value}, - {"inline_function_calls", ASRPass::inline_function_calls}, - {"loop_unroll", ASRPass::loop_unroll}, - {"dead_code_removal", ASRPass::dead_code_removal}, - {"forall", ASRPass::forall}, - {"select_case", ASRPass::select_case}, - {"loop_vectorise", ASRPass::loop_vectorise}, - {"array_dim_intrinsics_update", ASRPass::array_dim_intrinsics_update}, - {"pass_array_by_data", ASRPass::pass_array_by_data} + std::vector _passes; + std::vector _with_optimization_passes; + std::vector _user_defined_passes; + std::map _passes_db = { + {"do_loops", &LFortran::pass_replace_do_loops}, + {"global_stmts", &LFortran::pass_wrap_global_stmts_into_function}, + {"implied_do_loops", &LFortran::pass_replace_implied_do_loops}, + {"array_op", &LFortran::pass_replace_array_op}, + {"arr_slice", &LFortran::pass_replace_arr_slice}, + {"print_arr", &LFortran::pass_replace_print_arr}, + {"class_constructor", &LFortran::pass_replace_class_constructor}, + {"unused_functions", &LFortran::pass_unused_functions}, + {"flip_sign", &LFortran::pass_replace_flip_sign}, + {"div_to_mul", &LFortran::pass_replace_div_to_mul}, + {"fma", &LFortran::pass_replace_fma}, + {"sign_from_value", &LFortran::pass_replace_sign_from_value}, + {"inline_function_calls", &LFortran::pass_inline_function_calls}, + {"loop_unroll", &LFortran::pass_loop_unroll}, + {"dead_code_removal", &LFortran::pass_dead_code_removal}, + {"forall", &LFortran::pass_replace_forall}, + {"select_case", &LFortran::pass_replace_select_case}, + {"loop_vectorise", &LFortran::pass_loop_vectorise}, + {"array_dim_intrinsics_update", &LFortran::pass_update_array_dim_intrinsic_calls}, + {"pass_array_by_data", &LFortran::pass_array_by_data} }; bool is_fast; bool apply_default_passes; void _apply_passes(Allocator& al, LFortran::ASR::TranslationUnit_t* asr, - std::vector& passes, std::string& run_fun, - bool always_run) { + std::vector& passes, PassOptions pass_options) { + pass_options.runtime_library_dir = LFortran::get_runtime_library_dir(); for (size_t i = 0; i < passes.size(); i++) { - switch (passes[i]) { - case (ASRPass::do_loops) : { - LFortran::pass_replace_do_loops(al, *asr); - break; - } - case (ASRPass::global_stmts) : { - LFortran::pass_wrap_global_stmts_into_function(al, *asr, run_fun); - break; - } - case (ASRPass::implied_do_loops) : { - LFortran::pass_replace_implied_do_loops(al, *asr, LFortran::get_runtime_library_dir()); - break; - } - case (ASRPass::array_op) : { - LFortran::pass_replace_array_op(al, *asr, LFortran::get_runtime_library_dir()); - break; - } - case (ASRPass::flip_sign) : { - LFortran::pass_replace_flip_sign(al, *asr, LFortran::get_runtime_library_dir()); - break; - } - case (ASRPass::fma) : { - LFortran::pass_replace_fma(al, *asr, LFortran::get_runtime_library_dir()); - break; - } - case (ASRPass::loop_unroll) : { - LFortran::pass_loop_unroll(al, *asr, LFortran::get_runtime_library_dir()); - break; - } - case (ASRPass::inline_function_calls) : { - LFortran::pass_inline_function_calls(al, *asr, LFortran::get_runtime_library_dir()); - break; - } - case (ASRPass::dead_code_removal) : { - LFortran::pass_dead_code_removal(al, *asr, LFortran::get_runtime_library_dir()); - break; - } - case (ASRPass::sign_from_value) : { - LFortran::pass_replace_sign_from_value(al, *asr, LFortran::get_runtime_library_dir()); - break; - } - case (ASRPass::div_to_mul) : { - LFortran::pass_replace_div_to_mul(al, *asr, LFortran::get_runtime_library_dir()); - break; - } - case (ASRPass::class_constructor) : { - LFortran::pass_replace_class_constructor(al, *asr); - break; - } - case (ASRPass::arr_slice) : { - LFortran::pass_replace_arr_slice(al, *asr, LFortran::get_runtime_library_dir()); - break; - } - case (ASRPass::print_arr) : { - LFortran::pass_replace_print_arr(al, *asr, LFortran::get_runtime_library_dir()); - break; - } - case (ASRPass::unused_functions) : { - LFortran::pass_unused_functions(al, *asr, always_run); - break; - } - case (ASRPass::forall) : { - LFortran::pass_replace_forall(al, *asr); - break ; - } - case (ASRPass::select_case) : { - LFortran::pass_replace_select_case(al, *asr); - break; - } - case (ASRPass::loop_vectorise) : { - LFortran::pass_loop_vectorise(al, *asr, LFortran::get_runtime_library_dir()); - break; - } - case (ASRPass::array_dim_intrinsics_update): { - LFortran::pass_update_array_dim_intrinsic_calls(al, *asr); - break ; - } - case (ASRPass::pass_array_by_data): { - LFortran::pass_array_by_data(al, *asr); - break ; - } - } + _passes_db[passes[i]](al, *asr, pass_options); } } @@ -177,41 +90,41 @@ namespace LCompilers { PassManager(): is_fast{false}, apply_default_passes{false} { _passes = { - ASRPass::global_stmts, - ASRPass::class_constructor, - ASRPass::implied_do_loops, - ASRPass::pass_array_by_data, - ASRPass::arr_slice, - ASRPass::array_op, - ASRPass::print_arr, - ASRPass::array_dim_intrinsics_update, - ASRPass::do_loops, - ASRPass::forall, - ASRPass::select_case, - ASRPass::unused_functions + "global_stmts", + "class_constructor", + "implied_do_loops", + "pass_array_by_data", + "arr_slice", + "array_op", + "print_arr", + "array_dim_intrinsics_update", + "do_loops", + "forall", + "select_case", + "unused_functions" }; _with_optimization_passes = { - ASRPass::global_stmts, - ASRPass::class_constructor, - ASRPass::implied_do_loops, - ASRPass::pass_array_by_data, - ASRPass::arr_slice, - ASRPass::array_op, - ASRPass::print_arr, - ASRPass::loop_vectorise, - ASRPass::loop_unroll, - ASRPass::array_dim_intrinsics_update, - ASRPass::do_loops, - ASRPass::forall, - ASRPass::dead_code_removal, - ASRPass::select_case, - ASRPass::unused_functions, - ASRPass::flip_sign, - ASRPass::sign_from_value, - ASRPass::div_to_mul, - ASRPass::fma, - ASRPass::inline_function_calls + "global_stmts", + "class_constructor", + "implied_do_loops", + "pass_array_by_data", + "arr_slice", + "array_op", + "print_arr", + "loop_vectorise", + "loop_unroll", + "array_dim_intrinsics_update", + "do_loops", + "forall", + "dead_code_removal", + "select_case", + "unused_functions", + "flip_sign", + "sign_from_value", + "div_to_mul", + "fma", + "inline_function_calls" }; _user_defined_passes.clear(); @@ -239,21 +152,21 @@ namespace LCompilers { } exit(1); } - _user_defined_passes.push_back(_passes_db[current_pass]); + _user_defined_passes.push_back(current_pass); current_pass.clear(); } } } void apply_passes(Allocator& al, LFortran::ASR::TranslationUnit_t* asr, - std::string run_fun, bool always_run=false) { + PassOptions& pass_options) { if( !_user_defined_passes.empty() ) { - _apply_passes(al, asr, _user_defined_passes, run_fun, always_run); + _apply_passes(al, asr, _user_defined_passes, pass_options); } else if( apply_default_passes ) { if( is_fast ) { - _apply_passes(al, asr, _with_optimization_passes, run_fun, always_run); + _apply_passes(al, asr, _with_optimization_passes, pass_options); } else { - _apply_passes(al, asr, _passes, run_fun, always_run); + _apply_passes(al, asr, _passes, pass_options); } } } @@ -273,6 +186,7 @@ namespace LCompilers { void do_not_use_default_passes() { apply_default_passes = false; } + }; } diff --git a/src/libasr/pass/print_arr.cpp b/src/libasr/pass/print_arr.cpp index fb8d978865..1cfb37fb39 100644 --- a/src/libasr/pass/print_arr.cpp +++ b/src/libasr/pass/print_arr.cpp @@ -79,7 +79,8 @@ class PrintArrVisitor : public PassUtils::PassVisitor }; void pass_replace_print_arr(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string &rl_path) { + const LCompilers::PassOptions& pass_options) { + std::string rl_path = pass_options.runtime_library_dir; PrintArrVisitor v(al, rl_path); v.visit_TranslationUnit(unit); LFORTRAN_ASSERT(asr_verify(unit)); diff --git a/src/libasr/pass/print_arr.h b/src/libasr/pass/print_arr.h index cf6e79069c..a6e34005cc 100644 --- a/src/libasr/pass/print_arr.h +++ b/src/libasr/pass/print_arr.h @@ -2,11 +2,12 @@ #define LFORTRAN_PASS_PRINT_ARR_H #include +#include namespace LFortran { void pass_replace_print_arr(Allocator &al, ASR::TranslationUnit_t &unit, - const std::string &rl_path); + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/select_case.cpp b/src/libasr/pass/select_case.cpp index c923de521a..d50ca25f36 100644 --- a/src/libasr/pass/select_case.cpp +++ b/src/libasr/pass/select_case.cpp @@ -165,7 +165,8 @@ class SelectCaseVisitor : public PassUtils::PassVisitor } }; -void pass_replace_select_case(Allocator &al, ASR::TranslationUnit_t &unit) { +void pass_replace_select_case(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& /*pass_options*/) { SelectCaseVisitor v(al); // Each call transforms only one layer of nested loops, so we call it twice // to transform doubly nested loops: diff --git a/src/libasr/pass/select_case.h b/src/libasr/pass/select_case.h index b6e5b8fed7..d513b61622 100644 --- a/src/libasr/pass/select_case.h +++ b/src/libasr/pass/select_case.h @@ -2,10 +2,12 @@ #define LFORTRAN_PASS_SELECT_CASE_H #include +#include namespace LFortran { - void pass_replace_select_case(Allocator &al, ASR::TranslationUnit_t &unit); + void pass_replace_select_case(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/sign_from_value.cpp b/src/libasr/pass/sign_from_value.cpp index f6c9ecd919..49aab9aef7 100644 --- a/src/libasr/pass/sign_from_value.cpp +++ b/src/libasr/pass/sign_from_value.cpp @@ -152,7 +152,8 @@ class SignFromValueVisitor : public PassUtils::SkipOptimizationFunctionVisitor +#include namespace LFortran { - void pass_replace_sign_from_value(Allocator &al, ASR::TranslationUnit_t &unit, const std::string& rl_path); + void pass_replace_sign_from_value(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/unused_functions.cpp b/src/libasr/pass/unused_functions.cpp index af76d7698e..b2de852951 100644 --- a/src/libasr/pass/unused_functions.cpp +++ b/src/libasr/pass/unused_functions.cpp @@ -24,7 +24,7 @@ class CollectUnusedFunctionsVisitor : std::map fn_used; // TODO: Do subroutines just like Functions: - + void visit_Function(const ASR::Function_t &x) { if (x.m_return_var) { uint64_t h = get_hash((ASR::asr_t*)&x); @@ -245,7 +245,8 @@ class UnusedFunctionsVisitor : public ASR::BaseWalkVisitor +#include namespace LFortran { void pass_unused_functions(Allocator &al, ASR::TranslationUnit_t &unit, - bool always_run); + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/pass/update_array_dim_intrinsic_calls.cpp b/src/libasr/pass/update_array_dim_intrinsic_calls.cpp index 3b811f0a60..6806eb8d0c 100644 --- a/src/libasr/pass/update_array_dim_intrinsic_calls.cpp +++ b/src/libasr/pass/update_array_dim_intrinsic_calls.cpp @@ -143,7 +143,8 @@ class ArrayDimIntrinsicCallsVisitor : public ASR::CallReplacerOnExpressionsVisit }; -void pass_update_array_dim_intrinsic_calls(Allocator &al, ASR::TranslationUnit_t &unit) { +void pass_update_array_dim_intrinsic_calls(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& /*pass_options*/) { ArrayDimIntrinsicCallsVisitor v(al); v.visit_TranslationUnit(unit); LFORTRAN_ASSERT(asr_verify(unit)); diff --git a/src/libasr/pass/update_array_dim_intrinsic_calls.h b/src/libasr/pass/update_array_dim_intrinsic_calls.h index d7371653d8..30fe6ed6a7 100644 --- a/src/libasr/pass/update_array_dim_intrinsic_calls.h +++ b/src/libasr/pass/update_array_dim_intrinsic_calls.h @@ -2,10 +2,12 @@ #define LFORTRAN_PASS_UPDATE_ARRAY_DIM_H #include +#include namespace LFortran { - void pass_update_array_dim_intrinsic_calls(Allocator &al, ASR::TranslationUnit_t &unit); + void pass_update_array_dim_intrinsic_calls(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options); } // namespace LFortran diff --git a/src/libasr/utils.h b/src/libasr/utils.h index 22d01e2d5a..158055acd8 100644 --- a/src/libasr/utils.h +++ b/src/libasr/utils.h @@ -41,11 +41,26 @@ struct CompilerOptions { CompilerOptions () : platform{get_platform()} {}; }; - bool read_file(const std::string &filename, std::string &text); bool present(Vec &v, const char* name); int initialize(); } // LFortran +namespace LCompilers { + + struct PassOptions { + std::string run_fun; // for global_stmts pass + std::string runtime_library_dir; + bool always_run; // for unused_functions pass + bool inline_external_symbol_calls; // for inline_function_calls pass + int64_t unroll_factor; // for loop_unroll pass + + PassOptions(): always_run(false), inline_external_symbol_calls(true), + unroll_factor(32) + {} + }; + +} + #endif // LIBASR_UTILS_H diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 0310f483ac..a3d66b62d1 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -4557,7 +4557,10 @@ Result python_ast_to_asr(Allocator &al, LFORTRAN_ASSERT(asr_verify(*tu)); } } else { - pass_wrap_global_stmts_into_program(al, *tu, "_lpython_main_program"); + LCompilers::PassOptions pass_options; + pass_options.run_fun = "_lpython_main_program"; + pass_options.runtime_library_dir = get_runtime_library_dir(); + pass_wrap_global_stmts_into_program(al, *tu, pass_options); LFORTRAN_ASSERT(asr_verify(*tu)); } }