From a9189cca88ca06ba2d066649cd10643a3652566a Mon Sep 17 00:00:00 2001 From: Tanay Manerikar Date: Sun, 18 Feb 2024 15:23:01 +0530 Subject: [PATCH 1/5] Implemented mangling for c backend --- src/bin/lpython.cpp | 2 ++ src/libasr/pass/unique_symbols.cpp | 57 ++++++++++++++++++++++++++---- src/libasr/utils.h | 1 + 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index d5afe1fb8c..5b4472c570 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -318,6 +318,7 @@ int emit_c(const std::string &infile, pass_manager.use_default_passes(true); compiler_options.po.always_run = true; compiler_options.po.run_fun = "f"; + compiler_options.po.c_mangling = true; pass_manager.apply_passes(al, asr, compiler_options.po, diagnostics); @@ -367,6 +368,7 @@ int emit_c_to_file(const std::string &infile, const std::string &outfile, compiler_options.po.run_fun = "f"; compiler_options.po.always_run = true; + compiler_options.po.c_mangling = true; pass_manager.use_default_passes(true); pass_manager.apply_passes(al, asr, compiler_options.po, diagnostics); diff --git a/src/libasr/pass/unique_symbols.cpp b/src/libasr/pass/unique_symbols.cpp index 5a4aab01e3..ba44ebafa3 100644 --- a/src/libasr/pass/unique_symbols.cpp +++ b/src/libasr/pass/unique_symbols.cpp @@ -7,7 +7,7 @@ #include #include #include - +#include extern std::string lcompilers_unique_ID; @@ -46,16 +46,29 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { bool all_symbols_mangling; bool bindc_mangling = false; bool fortran_mangling; + bool c_mangling; bool should_mangle = false; std::vector parent_function_name; std::string module_name = ""; SymbolTable* current_scope = nullptr; - SymbolRenameVisitor(bool mm, bool gm, bool im, bool am, bool bcm, bool fm) : + SymbolRenameVisitor(bool mm, bool gm, bool im, bool am, bool bcm, bool fm, bool cm) : module_name_mangling(mm), global_symbols_mangling(gm), intrinsic_symbols_mangling(im), - all_symbols_mangling(am), bindc_mangling(bcm), fortran_mangling(fm) {} + all_symbols_mangling(am), bindc_mangling(bcm), fortran_mangling(fm) , c_mangling(cm){} + + const std::unordered_set restricted_keywords_c = { + "_Alignas", "_Alignof", "_Atomic", "_Bool", "_Complex", "_Generic", "_Imaginary", "_Noreturn", "_Static_assert", "_Thread_local", "auto", "break", "case", "char", "_Bool", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while" + }; + bool is_restricted_c(const std::string& name) { + // Check if the name is a restricted keyword + if (restricted_keywords_c.find(name) != restricted_keywords_c.end()) { + return true; + } else { + return false; + } + } std::string update_name(std::string curr_name) { if (startswith(curr_name, "_lpython") || startswith(curr_name, "_lfortran") ) { return curr_name; @@ -147,6 +160,12 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { sym_to_renamed[sym] = current_scope->parent->get_unique_name( "f" + std::string(x.m_name)); } + } + } + if ( c_mangling ) { + if(is_restricted_c(x.m_name)){ + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = "_xx_"+std::string(x.m_name)+"_xx_"; } } for (auto &a : x.m_symtab->get_scope()) { @@ -178,6 +197,12 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { std::string(x.m_name)); } } + + if ( c_mangling ) { + if(is_restricted_c(x.m_name)){ + sym_to_renamed[sym] = "_xx_"+std::string(x.m_name)+"_xx_"; + } + } } void visit_GenericProcedure(const ASR::GenericProcedure_t &x) { @@ -204,6 +229,12 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { sym_to_renamed[sym] = update_name(x.m_name); } } + if ( c_mangling ) { + if(is_restricted_c(x.m_name)){ + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = "_xx_"+std::string(x.m_name)+"_xx_"; + } + } for (auto &a : x.m_symtab->get_scope()) { this->visit_symbol(*a.second); } @@ -232,6 +263,12 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { sym_to_renamed[sym] = update_name(x.m_name); } } + if (c_mangling ) { + if(is_restricted_c(x.m_name)){ + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = "_xx_"+std::string(x.m_name)+"_xx_"; + } + } } template @@ -240,6 +277,12 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); sym_to_renamed[sym] = update_name(x.m_name); } + if ( c_mangling ) { + if(is_restricted_c(x.m_name)){ + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = "_xx_"+std::string(x.m_name)+"_xx_"; + } + } for (auto &a : x.m_symtab->get_scope()) { this->visit_symbol(*a.second); } @@ -521,8 +564,9 @@ void pass_unique_symbols(Allocator &al, ASR::TranslationUnit_t &unit, if (pass_options.mangle_underscore) { lcompilers_unique_ID = ""; } - if (!any_present || (!(pass_options.mangle_underscore || - pass_options.fortran_mangling) && lcompilers_unique_ID.empty())) { + if ((!any_present || (!(pass_options.mangle_underscore || + pass_options.fortran_mangling) && lcompilers_unique_ID.empty())) && + !pass_options.c_mangling) { // `--mangle-underscore` doesn't require `lcompilers_unique_ID` // `lcompilers_unique_ID` is not mandatory for `--apply-fortran-mangling` return; @@ -532,7 +576,8 @@ void pass_unique_symbols(Allocator &al, ASR::TranslationUnit_t &unit, pass_options.intrinsic_symbols_mangling, pass_options.all_symbols_mangling, pass_options.bindc_mangling, - pass_options.fortran_mangling); + pass_options.fortran_mangling, + pass_options.c_mangling); v.visit_TranslationUnit(unit); UniqueSymbolVisitor u(al, v.sym_to_renamed); u.visit_TranslationUnit(unit); diff --git a/src/libasr/utils.h b/src/libasr/utils.h index 073a7bebe1..e65f1ce76f 100644 --- a/src/libasr/utils.h +++ b/src/libasr/utils.h @@ -55,6 +55,7 @@ struct PassOptions { bool visualize = false; bool tree = false; bool with_intrinsic_mods = false; + bool c_mangling = false; }; struct CompilerOptions { From 2f63dff5651274165a32bd8335235419661d4188 Mon Sep 17 00:00:00 2001 From: tanay-man Date: Tue, 20 Feb 2024 22:38:23 +0530 Subject: [PATCH 2/5] Refactor --- src/bin/lpython.cpp | 3 +-- src/libasr/pass/unique_symbols.cpp | 43 ++++++++++++------------------ 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index 5b4472c570..b5d20927d5 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -318,7 +318,6 @@ int emit_c(const std::string &infile, pass_manager.use_default_passes(true); compiler_options.po.always_run = true; compiler_options.po.run_fun = "f"; - compiler_options.po.c_mangling = true; pass_manager.apply_passes(al, asr, compiler_options.po, diagnostics); @@ -368,7 +367,6 @@ int emit_c_to_file(const std::string &infile, const std::string &outfile, compiler_options.po.run_fun = "f"; compiler_options.po.always_run = true; - compiler_options.po.c_mangling = true; pass_manager.use_default_passes(true); pass_manager.apply_passes(al, asr, compiler_options.po, diagnostics); @@ -1713,6 +1711,7 @@ int main(int argc, char *argv[]) backend = Backend::llvm; } else if (arg_backend == "c") { backend = Backend::c; + compiler_options.po.c_mangling = true; } else if (arg_backend == "cpp") { backend = Backend::cpp; } else if (arg_backend == "x86") { diff --git a/src/libasr/pass/unique_symbols.cpp b/src/libasr/pass/unique_symbols.cpp index ba44ebafa3..485a0df478 100644 --- a/src/libasr/pass/unique_symbols.cpp +++ b/src/libasr/pass/unique_symbols.cpp @@ -57,18 +57,19 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { all_symbols_mangling(am), bindc_mangling(bcm), fortran_mangling(fm) , c_mangling(cm){} - const std::unordered_set restricted_keywords_c = { + const std::unordered_set reserved_keywords_c = { "_Alignas", "_Alignof", "_Atomic", "_Bool", "_Complex", "_Generic", "_Imaginary", "_Noreturn", "_Static_assert", "_Thread_local", "auto", "break", "case", "char", "_Bool", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while" }; - bool is_restricted_c(const std::string& name) { - // Check if the name is a restricted keyword - if (restricted_keywords_c.find(name) != restricted_keywords_c.end()) { - return true; - } else { - return false; + + void mangle_c(ASR::symbol_t* sym, const std::string& name){ + + if (reserved_keywords_c.find(name) != reserved_keywords_c.end()) { + sym_to_renamed[sym] = "_xx_"+std::string(name)+"_xx_"; } + return; } + std::string update_name(std::string curr_name) { if (startswith(curr_name, "_lpython") || startswith(curr_name, "_lfortran") ) { return curr_name; @@ -163,10 +164,8 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { } } if ( c_mangling ) { - if(is_restricted_c(x.m_name)){ - ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); - sym_to_renamed[sym] = "_xx_"+std::string(x.m_name)+"_xx_"; - } + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + mangle_c(sym , std::string(x.m_name)); } for (auto &a : x.m_symtab->get_scope()) { bool nested_function = is_nested_function(a.second); @@ -199,9 +198,7 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { } if ( c_mangling ) { - if(is_restricted_c(x.m_name)){ - sym_to_renamed[sym] = "_xx_"+std::string(x.m_name)+"_xx_"; - } + mangle_c(sym , std::string(x.m_name)); } } @@ -230,10 +227,8 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { } } if ( c_mangling ) { - if(is_restricted_c(x.m_name)){ - ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); - sym_to_renamed[sym] = "_xx_"+std::string(x.m_name)+"_xx_"; - } + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + mangle_c(sym , std::string(x.m_name)); } for (auto &a : x.m_symtab->get_scope()) { this->visit_symbol(*a.second); @@ -264,10 +259,8 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { } } if (c_mangling ) { - if(is_restricted_c(x.m_name)){ - ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); - sym_to_renamed[sym] = "_xx_"+std::string(x.m_name)+"_xx_"; - } + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + mangle_c(sym , std::string(x.m_name)); } } @@ -278,10 +271,8 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { sym_to_renamed[sym] = update_name(x.m_name); } if ( c_mangling ) { - if(is_restricted_c(x.m_name)){ - ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); - sym_to_renamed[sym] = "_xx_"+std::string(x.m_name)+"_xx_"; - } + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + mangle_c(sym , std::string(x.m_name)); } for (auto &a : x.m_symtab->get_scope()) { this->visit_symbol(*a.second); From 78c757fccb3578e7e170270212c5b187b7f48b7f Mon Sep 17 00:00:00 2001 From: tanay-man Date: Mon, 11 Mar 2024 00:23:43 +0530 Subject: [PATCH 3/5] Refactor --- src/bin/lpython.cpp | 3 ++- src/libasr/pass/unique_symbols.cpp | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index b5d20927d5..50befca23b 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -1711,7 +1711,6 @@ int main(int argc, char *argv[]) backend = Backend::llvm; } else if (arg_backend == "c") { backend = Backend::c; - compiler_options.po.c_mangling = true; } else if (arg_backend == "cpp") { backend = Backend::cpp; } else if (arg_backend == "x86") { @@ -1787,6 +1786,7 @@ int main(int argc, char *argv[]) return emit_cpp(arg_file, runtime_library_dir, compiler_options); } if (show_c) { + compiler_options.po.c_mangling = true; return emit_c(arg_file, runtime_library_dir, lpython_pass_manager, compiler_options); } @@ -1862,6 +1862,7 @@ int main(int argc, char *argv[]) err = compile_to_binary_wasm_to_x86(arg_file, outfile, runtime_library_dir, compiler_options, time_report, backend); } else if (backend == Backend::c) { + compiler_options.po.c_mangling = true; std::string emit_file_name = basename + "__tmp__generated__.c"; err = emit_c_to_file(arg_file, emit_file_name, runtime_library_dir, lpython_pass_manager, compiler_options); diff --git a/src/libasr/pass/unique_symbols.cpp b/src/libasr/pass/unique_symbols.cpp index 485a0df478..1d08cb179a 100644 --- a/src/libasr/pass/unique_symbols.cpp +++ b/src/libasr/pass/unique_symbols.cpp @@ -61,9 +61,8 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { "_Alignas", "_Alignof", "_Atomic", "_Bool", "_Complex", "_Generic", "_Imaginary", "_Noreturn", "_Static_assert", "_Thread_local", "auto", "break", "case", "char", "_Bool", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while" }; - - void mangle_c(ASR::symbol_t* sym, const std::string& name){ - +//TODO: Implement other backends mangling when refactoring the pass infrastructure + void mangle_c(ASR::symbol_t* sym, const std::string& name){ if (reserved_keywords_c.find(name) != reserved_keywords_c.end()) { sym_to_renamed[sym] = "_xx_"+std::string(name)+"_xx_"; } From c38df49a884e29f44f5ea9da6ab5ebc01245023e Mon Sep 17 00:00:00 2001 From: tanay-man Date: Tue, 12 Mar 2024 01:15:07 +0530 Subject: [PATCH 4/5] Added integration test --- integration_tests/CMakeLists.txt | 2 ++ integration_tests/c_mangling.py | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 integration_tests/c_mangling.py diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 1177bb5266..4feeffb0bb 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -810,6 +810,8 @@ RUN(NAME callback_03 LABELS cpython llvm c) RUN(NAME lambda_01 LABELS cpython llvm) +RUN(NAME c_mangling LABELS c)#Only for c backend + # callback_04 is to test emulation. So just run with cpython RUN(NAME callback_04 IMPORT_PATH .. LABELS cpython) diff --git a/integration_tests/c_mangling.py b/integration_tests/c_mangling.py new file mode 100644 index 0000000000..5acc099f41 --- /dev/null +++ b/integration_tests/c_mangling.py @@ -0,0 +1,23 @@ +def f(): + int : str + int = "abc" + print(int) + + char : str + char = "char_variable" + print(char) + + void : str + void = "void_variable" + print(void) + + auto : str + auto = "auto_variable" + print(auto) + + + case : str + case = "case_variable" + print(case) + +f() From 863b382ebbf39d4c598d732439ff4d5bb7d33639 Mon Sep 17 00:00:00 2001 From: Thirumalai Shaktivel <74826228+Thirumalai-Shaktivel@users.noreply.github.com> Date: Sat, 23 Mar 2024 11:27:39 +0530 Subject: [PATCH 5/5] Update integration_tests/CMakeLists.txt --- integration_tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 11ec38d852..a36ef5e2b6 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -812,7 +812,7 @@ RUN(NAME callback_03 LABELS cpython llvm c) RUN(NAME lambda_01 LABELS cpython llvm) -RUN(NAME c_mangling LABELS c)#Only for c backend +RUN(NAME c_mangling LABELS cpython llvm c) # callback_04 is to test emulation. So just run with cpython RUN(NAME callback_04 IMPORT_PATH .. LABELS cpython)