Skip to content

Commit

Permalink
Merge pull request lcompilers#1636 from Smit-create/c_pass
Browse files Browse the repository at this point in the history
C: Support passes
  • Loading branch information
Smit-create authored Apr 5, 2023
2 parents 37fa041 + 5b38933 commit e859831
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 29 deletions.
23 changes: 20 additions & 3 deletions src/bin/lpython.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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(true);
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);
Expand All @@ -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);
Expand Down Expand Up @@ -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(true);
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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
17 changes: 1 addition & 16 deletions src/libasr/codegen/asr_to_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1280,27 +1280,12 @@ 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<std::string> asr_to_c(Allocator &al, ASR::TranslationUnit_t &asr,
Result<std::string> 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);
Expand Down
21 changes: 18 additions & 3 deletions src/libasr/codegen/asr_to_c_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class BaseCCPPVisitor : public ASR::BaseVisitor<Struct>
const ASR::Function_t *current_function = nullptr;
std::map<uint64_t, SymbolInfo> sym_info;
std::map<uint64_t, std::string> const_var_names;
std::map<int32_t, std::string> gotoid2name;

// Output configuration:
// Use std::string or char*
Expand Down Expand Up @@ -331,6 +332,15 @@ R"(#include <stdio.h>
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;
Expand Down Expand Up @@ -1911,9 +1921,14 @@ R"(#include <stdio.h>
}
}

void visit_GoToTarget(const ASR::GoToTarget_t & /* x */) {
// Ignore for now
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";
gotoid2name[x.m_target_id] = std::string(x.m_name);
}

void visit_GoToTarget(const ASR::GoToTarget_t &x) {
src = std::string(x.m_name) + ":\n";
}

void visit_Stop(const ASR::Stop_t &x) {
Expand Down
8 changes: 4 additions & 4 deletions src/libasr/pass/pass_list_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class ListExprReplacer : public ASR::BaseExprReplacer<ListExprReplacer>
*/

SymbolTable* list_section_symtab = al.make_new<SymbolTable>(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<ASR::List_t>(list_type)->m_type;
ASR::ttype_t* int_type = ASRUtils::TYPE(ASR::make_Integer_t(
Expand Down Expand Up @@ -409,7 +409,7 @@ class ListExprReplacer : public ASR::BaseExprReplacer<ListExprReplacer>
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);
Expand Down Expand Up @@ -437,7 +437,7 @@ class ListExprReplacer : public ASR::BaseExprReplacer<ListExprReplacer>
return result_list
*/
SymbolTable* list_concat_symtab = al.make_new<SymbolTable>(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<ASR::expr_t*> arg_exprs;
Expand Down Expand Up @@ -535,7 +535,7 @@ class ListExprReplacer : public ASR::BaseExprReplacer<ListExprReplacer>
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);
Expand Down
20 changes: 17 additions & 3 deletions src/libasr/pass/pass_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ namespace LCompilers {
std::vector<std::string> _passes;
std::vector<std::string> _with_optimization_passes;
std::vector<std::string> _user_defined_passes;
std::vector<std::string> _skip_passes;
std::vector<std::string> _skip_passes, _c_skip_passes;
std::map<std::string, pass_function> _passes_db = {
{"do_loops", &pass_replace_do_loops},
{"global_stmts", &pass_wrap_global_stmts_into_function},
Expand Down Expand Up @@ -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<std::string>& passes, PassOptions &pass_options,
Expand All @@ -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)) {
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -191,6 +196,14 @@ namespace LCompilers {
"inline_function_calls"
};

// These are re-write passes which are already handled
// appropriately in C backend.
_c_skip_passes = {
"pass_list_expr",
"print_list_tuple",
"do_loops",
"inline_function_calls"
};
_user_defined_passes.clear();
}

Expand Down Expand Up @@ -227,8 +240,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() {
Expand Down

0 comments on commit e859831

Please sign in to comment.