Skip to content

Commit e859831

Browse files
authored
Merge pull request #1636 from Smit-create/c_pass
C: Support passes
2 parents 37fa041 + 5b38933 commit e859831

File tree

5 files changed

+60
-29
lines changed

5 files changed

+60
-29
lines changed

src/bin/lpython.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ int emit_cpp(const std::string &infile,
262262

263263
int emit_c(const std::string &infile,
264264
const std::string &runtime_library_dir,
265+
LCompilers::PassManager& pass_manager,
265266
CompilerOptions &compiler_options)
266267
{
267268
Allocator al(4*1024);
@@ -293,6 +294,13 @@ int emit_c(const std::string &infile,
293294
}
294295
LCompilers::ASR::TranslationUnit_t* asr = r1.result;
295296

297+
// Apply ASR passes
298+
LCompilers::PassOptions pass_options;
299+
pass_manager.use_default_passes(true);
300+
pass_options.run_fun = "f";
301+
pass_options.always_run = true;
302+
pass_manager.apply_passes(al, asr, pass_options, diagnostics);
303+
296304
diagnostics.diagnostics.clear();
297305
auto res = LCompilers::asr_to_c(al, *asr, diagnostics, compiler_options, 0);
298306
std::cerr << diagnostics.render(lm, compiler_options);
@@ -305,7 +313,7 @@ int emit_c(const std::string &infile,
305313
}
306314

307315
int emit_c_to_file(const std::string &infile, const std::string &outfile,
308-
const std::string &runtime_library_dir,
316+
const std::string &runtime_library_dir, LCompilers::PassManager& pass_manager,
309317
CompilerOptions &compiler_options)
310318
{
311319
Allocator al(4*1024);
@@ -337,6 +345,13 @@ int emit_c_to_file(const std::string &infile, const std::string &outfile,
337345
}
338346
LCompilers::ASR::TranslationUnit_t* asr = r1.result;
339347

348+
// Apply ASR passes
349+
LCompilers::PassOptions pass_options;
350+
pass_manager.use_default_passes(true);
351+
pass_options.run_fun = "f";
352+
pass_options.always_run = true;
353+
pass_manager.apply_passes(al, asr, pass_options, diagnostics);
354+
340355
diagnostics.diagnostics.clear();
341356
auto res = LCompilers::asr_to_c(al, *asr, diagnostics, compiler_options, 0);
342357
std::cerr << diagnostics.render(lm, compiler_options);
@@ -1666,7 +1681,8 @@ int main(int argc, char *argv[])
16661681
return emit_cpp(arg_file, runtime_library_dir, compiler_options);
16671682
}
16681683
if (show_c) {
1669-
return emit_c(arg_file, runtime_library_dir, compiler_options);
1684+
return emit_c(arg_file, runtime_library_dir, lpython_pass_manager,
1685+
compiler_options);
16701686
}
16711687
if (show_wat) {
16721688
return emit_wat(arg_file, runtime_library_dir, compiler_options);
@@ -1741,7 +1757,8 @@ int main(int argc, char *argv[])
17411757
runtime_library_dir, compiler_options, time_report, backend);
17421758
} else if (backend == Backend::c) {
17431759
std::string emit_file_name = basename + "__tmp__generated__.c";
1744-
err = emit_c_to_file(arg_file, emit_file_name, runtime_library_dir, compiler_options);
1760+
err = emit_c_to_file(arg_file, emit_file_name, runtime_library_dir,
1761+
lpython_pass_manager, compiler_options);
17451762
err = link_executable({emit_file_name}, outfile, runtime_library_dir,
17461763
backend, static_link, true, compiler_options, rtlib_header_dir);
17471764
} else if (backend == Backend::llvm) {

src/libasr/codegen/asr_to_c.cpp

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,27 +1280,12 @@ R"(
12801280
src = "strlen(" + src + ")";
12811281
}
12821282

1283-
void visit_GoTo(const ASR::GoTo_t &x) {
1284-
std::string indent(indentation_level*indentation_spaces, ' ');
1285-
src = indent + "goto " + std::string(x.m_name) + ";\n";
1286-
}
1287-
1288-
void visit_GoToTarget(const ASR::GoToTarget_t &x) {
1289-
src = std::string(x.m_name) + ":\n";
1290-
}
12911283
};
12921284

1293-
Result<std::string> asr_to_c(Allocator &al, ASR::TranslationUnit_t &asr,
1285+
Result<std::string> asr_to_c(Allocator & /*al*/, ASR::TranslationUnit_t &asr,
12941286
diag::Diagnostics &diagnostics, CompilerOptions &co,
12951287
int64_t default_lower_bound)
12961288
{
1297-
1298-
LCompilers::PassOptions pass_options;
1299-
pass_options.always_run = true;
1300-
pass_create_subroutine_from_function(al, asr, pass_options);
1301-
pass_replace_array_op(al, asr, pass_options);
1302-
pass_unused_functions(al, asr, pass_options);
1303-
pass_replace_class_constructor(al, asr, pass_options);
13041289
ASRToCVisitor v(diagnostics, co, default_lower_bound);
13051290
try {
13061291
v.visit_asr((ASR::asr_t &)asr);

src/libasr/codegen/asr_to_c_cpp.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class BaseCCPPVisitor : public ASR::BaseVisitor<Struct>
102102
const ASR::Function_t *current_function = nullptr;
103103
std::map<uint64_t, SymbolInfo> sym_info;
104104
std::map<uint64_t, std::string> const_var_names;
105+
std::map<int32_t, std::string> gotoid2name;
105106

106107
// Output configuration:
107108
// Use std::string or char*
@@ -331,6 +332,15 @@ R"(#include <stdio.h>
331332
std::string indent(indentation_level*indentation_spaces, ' ');
332333
std::string open_paranthesis = indent + "{\n";
333334
std::string close_paranthesis = indent + "}\n";
335+
if (x.m_label != -1) {
336+
std::string b_name;
337+
if (gotoid2name.find(x.m_label) != gotoid2name.end()) {
338+
b_name = gotoid2name[x.m_label];
339+
} else {
340+
b_name = "__" +std::to_string(x.m_label);
341+
}
342+
open_paranthesis = indent + b_name + ": {\n";
343+
}
334344
indent += std::string(indentation_spaces, ' ');
335345
indentation_level += 1;
336346
SymbolTable* current_scope_copy = current_scope;
@@ -1911,9 +1921,14 @@ R"(#include <stdio.h>
19111921
}
19121922
}
19131923

1914-
void visit_GoToTarget(const ASR::GoToTarget_t & /* x */) {
1915-
// Ignore for now
1916-
src = "";
1924+
void visit_GoTo(const ASR::GoTo_t &x) {
1925+
std::string indent(indentation_level*indentation_spaces, ' ');
1926+
src = indent + "goto " + std::string(x.m_name) + ";\n";
1927+
gotoid2name[x.m_target_id] = std::string(x.m_name);
1928+
}
1929+
1930+
void visit_GoToTarget(const ASR::GoToTarget_t &x) {
1931+
src = std::string(x.m_name) + ":\n";
19171932
}
19181933

19191934
void visit_Stop(const ASR::Stop_t &x) {

src/libasr/pass/pass_list_expr.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class ListExprReplacer : public ASR::BaseExprReplacer<ListExprReplacer>
152152
*/
153153

154154
SymbolTable* list_section_symtab = al.make_new<SymbolTable>(global_scope);
155-
std::string list_type_name = ASRUtils::type_to_str_python(list_type);
155+
std::string list_type_name = ASRUtils::get_type_code(list_type, true);
156156
std::string fn_name = global_scope->get_unique_name("_lcompilers_list_section_" + list_type_name);
157157
ASR::ttype_t* item_type = ASR::down_cast<ASR::List_t>(list_type)->m_type;
158158
ASR::ttype_t* int_type = ASRUtils::TYPE(ASR::make_Integer_t(
@@ -409,7 +409,7 @@ class ListExprReplacer : public ASR::BaseExprReplacer<ListExprReplacer>
409409
call_arg.m_value = is_end_present;
410410
args.push_back(al, call_arg);
411411

412-
std::string list_type_name = ASRUtils::type_to_str_python(x->m_type);
412+
std::string list_type_name = ASRUtils::get_type_code(x->m_type, true);
413413
if (list_section_func_map.find(list_type_name) == list_section_func_map.end()) {
414414
create_list_section_func(unit.base.base.loc,
415415
unit.m_global_scope, x->m_type);
@@ -437,7 +437,7 @@ class ListExprReplacer : public ASR::BaseExprReplacer<ListExprReplacer>
437437
return result_list
438438
*/
439439
SymbolTable* list_concat_symtab = al.make_new<SymbolTable>(global_scope);
440-
std::string list_type_name = ASRUtils::type_to_str_python(list_type);
440+
std::string list_type_name = ASRUtils::get_type_code(list_type, true);
441441
std::string fn_name = global_scope->get_unique_name("_lcompilers_list_concat_" + list_type_name);
442442

443443
Vec<ASR::expr_t*> arg_exprs;
@@ -535,7 +535,7 @@ class ListExprReplacer : public ASR::BaseExprReplacer<ListExprReplacer>
535535
right_list.loc = x->m_right->base.loc;
536536
right_list.m_value = x->m_right;
537537
args.push_back(al, right_list);
538-
std::string list_type_name = ASRUtils::type_to_str_python(x->m_type);
538+
std::string list_type_name = ASRUtils::get_type_code(x->m_type, true);
539539
if (list_concat_func_map.find(list_type_name) == list_concat_func_map.end()) {
540540
create_concat_function(unit.base.base.loc,
541541
unit.m_global_scope, x->m_type);

src/libasr/pass/pass_manager.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ namespace LCompilers {
5959
std::vector<std::string> _passes;
6060
std::vector<std::string> _with_optimization_passes;
6161
std::vector<std::string> _user_defined_passes;
62-
std::vector<std::string> _skip_passes;
62+
std::vector<std::string> _skip_passes, _c_skip_passes;
6363
std::map<std::string, pass_function> _passes_db = {
6464
{"do_loops", &pass_replace_do_loops},
6565
{"global_stmts", &pass_wrap_global_stmts_into_function},
@@ -90,6 +90,7 @@ namespace LCompilers {
9090

9191
bool is_fast;
9292
bool apply_default_passes;
93+
bool c_skip_pass; // This will contain the passes that are to be skipped in C
9394

9495
void _apply_passes(Allocator& al, ASR::TranslationUnit_t* asr,
9596
std::vector<std::string>& passes, PassOptions &pass_options,
@@ -103,6 +104,9 @@ namespace LCompilers {
103104
if (rtlib && passes[i] == "unused_functions") continue;
104105
if( std::find(_skip_passes.begin(), _skip_passes.end(), passes[i]) != _skip_passes.end())
105106
continue;
107+
if (c_skip_pass && std::find(_c_skip_passes.begin(),
108+
_c_skip_passes.end(), passes[i]) != _c_skip_passes.end())
109+
continue;
106110
_passes_db[passes[i]](al, *asr, pass_options);
107111
#if defined(WITH_LFORTRAN_ASSERT)
108112
if (!asr_verify(*asr, true, diagnostics)) {
@@ -142,7 +146,8 @@ namespace LCompilers {
142146
}
143147
}
144148

145-
PassManager(): is_fast{false}, apply_default_passes{false} {
149+
PassManager(): is_fast{false}, apply_default_passes{false},
150+
c_skip_pass{false} {
146151
_passes = {
147152
"global_stmts",
148153
"init_expr",
@@ -191,6 +196,14 @@ namespace LCompilers {
191196
"inline_function_calls"
192197
};
193198

199+
// These are re-write passes which are already handled
200+
// appropriately in C backend.
201+
_c_skip_passes = {
202+
"pass_list_expr",
203+
"print_list_tuple",
204+
"do_loops",
205+
"inline_function_calls"
206+
};
194207
_user_defined_passes.clear();
195208
}
196209

@@ -227,8 +240,9 @@ namespace LCompilers {
227240
is_fast = false;
228241
}
229242

230-
void use_default_passes() {
243+
void use_default_passes(bool _c_skip_pass=false) {
231244
apply_default_passes = true;
245+
c_skip_pass = _c_skip_pass;
232246
}
233247

234248
void do_not_use_default_passes() {

0 commit comments

Comments
 (0)