From 19309b8e9d3f99e15389ebdf4b872d61a4f70568 Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Fri, 4 Nov 2022 21:35:50 +0530 Subject: [PATCH 1/7] X86: Support diagnostics in asr_to_x86() --- src/bin/lpython.cpp | 2 +- src/libasr/codegen/asr_to_x86.cpp | 10 +++++++--- src/libasr/codegen/asr_to_x86.h | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index a9db92cc38..67c91fd395 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -775,7 +775,7 @@ int compile_to_binary_x86( // ASR -> X86 auto asr_to_x86_start = std::chrono::high_resolution_clock::now(); - LFortran::Result r3 = LFortran::asr_to_x86(*asr, al, outfile, time_report); + LFortran::Result r3 = LFortran::asr_to_x86(*asr, al, outfile, time_report, diagnostics); auto asr_to_x86_end = std::chrono::high_resolution_clock::now(); times.push_back(std::make_pair("ASR to X86", std::chrono::duration(asr_to_x86_end - asr_to_x86_start).count())); std::cerr << diagnostics.render(input, lm, compiler_options); diff --git a/src/libasr/codegen/asr_to_x86.cpp b/src/libasr/codegen/asr_to_x86.cpp index af0c88722c..e8f8836755 100644 --- a/src/libasr/codegen/asr_to_x86.cpp +++ b/src/libasr/codegen/asr_to_x86.cpp @@ -526,7 +526,8 @@ class ASRToX86Visitor : public ASR::BaseVisitor Result asr_to_x86(ASR::TranslationUnit_t &asr, Allocator &al, - const std::string &filename, bool time_report) + const std::string &filename, bool time_report, + diag::Diagnostics &diagnostics) { int time_pass_global=0; int time_pass_do_loops=0; @@ -558,8 +559,8 @@ Result asr_to_x86(ASR::TranslationUnit_t &asr, Allocator &al, try { v.visit_asr((ASR::asr_t &)asr); } catch (const CodeGenError &e) { - Error error; - return error; + diagnostics.diagnostics.push_back(e.d); + return Error(); } auto t2 = std::chrono::high_resolution_clock::now(); time_visit_asr = std::chrono::duration_cast(t2 - t1).count(); @@ -579,6 +580,9 @@ Result asr_to_x86(ASR::TranslationUnit_t &asr, Allocator &al, time_save = std::chrono::duration_cast(t2 - t1).count(); } + //! Helpful for debugging + // std::cout << v.m_a.get_asm() << std::endl; + if (time_report) { std::cout << "Codegen Time report:" << std::endl; std::cout << "Global: " << std::setw(5) << time_pass_global << std::endl; diff --git a/src/libasr/codegen/asr_to_x86.h b/src/libasr/codegen/asr_to_x86.h index 39b2e5803d..b4a3bce170 100644 --- a/src/libasr/codegen/asr_to_x86.h +++ b/src/libasr/codegen/asr_to_x86.h @@ -7,7 +7,8 @@ namespace LFortran { // Generates a 32-bit x86 Linux executable binary `filename` Result asr_to_x86(ASR::TranslationUnit_t &asr, Allocator &al, - const std::string &filename, bool time_report); + const std::string &filename, bool time_report, + diag::Diagnostics &diagnostics); } // namespace LFortran From 2aea75b2e96514d173a69cf5b8e9cdfc24b93c4f Mon Sep 17 00:00:00 2001 From: Ubaid Date: Fri, 4 Nov 2022 21:18:19 +0530 Subject: [PATCH 2/7] WASM: Emit else always --- src/libasr/codegen/asr_to_wasm.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libasr/codegen/asr_to_wasm.cpp b/src/libasr/codegen/asr_to_wasm.cpp index 7cd873b482..7111abfa6d 100644 --- a/src/libasr/codegen/asr_to_wasm.cpp +++ b/src/libasr/codegen/asr_to_wasm.cpp @@ -2048,11 +2048,9 @@ class ASRToWASMVisitor : public ASR::BaseVisitor { for (size_t i = 0; i < x.n_body; i++) { this->visit_stmt(*x.m_body[i]); } - if (x.n_orelse) { - wasm::emit_b8(m_code_section, m_al, 0x05); // starting of else - for (size_t i = 0; i < x.n_orelse; i++) { - this->visit_stmt(*x.m_orelse[i]); - } + wasm::emit_b8(m_code_section, m_al, 0x05); // starting of else + for (size_t i = 0; i < x.n_orelse; i++) { + this->visit_stmt(*x.m_orelse[i]); } nesting_level--; wasm::emit_expr_end(m_code_section, m_al); // emit if end @@ -2119,6 +2117,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor { } wasm::emit_i32_const(m_code_section, m_al, 1); // non-zero exit code exit(); + wasm::emit_b8(m_code_section, m_al, 0x05); // starting of else wasm::emit_expr_end(m_code_section, m_al); // emit if end } }; From 03fbb067d00d4bb105cf4c62e3042e69cff5bb69 Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Fri, 4 Nov 2022 21:47:15 +0530 Subject: [PATCH 3/7] WASM_X86: Implement Visit if-else --- src/libasr/codegen/wasm_to_x86.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/libasr/codegen/wasm_to_x86.cpp b/src/libasr/codegen/wasm_to_x86.cpp index fcd24124e4..efe701d70f 100644 --- a/src/libasr/codegen/wasm_to_x86.cpp +++ b/src/libasr/codegen/wasm_to_x86.cpp @@ -16,6 +16,7 @@ class X86Visitor : public WASMDecoder, public: X86Assembler &m_a; uint32_t cur_func_idx; + std::vector unique_id; X86Visitor(X86Assembler &m_a, Allocator &al, diag::Diagnostics &diagonostics, Vec &code) @@ -68,6 +69,27 @@ class X86Visitor : public WASMDecoder, } } + void visit_EmtpyBlockType() {} + + void visit_If() { + unique_id.push_back(offset); + m_a.asm_pop_r32(X86Reg::eax); + m_a.asm_cmp_r32_imm8(LFortran::X86Reg::eax, 1); + m_a.asm_je_label(".then_" + std::to_string(unique_id.back())); + m_a.asm_jmp_label(".else_" + std::to_string(unique_id.back())); + m_a.add_label(".then_" + std::to_string(unique_id.back())); + { + decode_instructions(); + } + m_a.add_label(".endif_" + std::to_string(unique_id.back())); + unique_id.pop_back(); + } + + void visit_Else() { + m_a.asm_jmp_label(".endif_" + std::to_string(unique_id.back())); + m_a.add_label(".else_" + std::to_string(unique_id.back())); + } + void visit_LocalGet(uint32_t localidx) { X86Reg base = X86Reg::ebp; int no_of_params = From 8fb624b12ce55b71cb59f0122f919106ce1485fd Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Fri, 4 Nov 2022 21:47:51 +0530 Subject: [PATCH 4/7] WASM_X86: Minor debugging help --- src/libasr/codegen/wasm_to_x86.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libasr/codegen/wasm_to_x86.cpp b/src/libasr/codegen/wasm_to_x86.cpp index efe701d70f..c298349a20 100644 --- a/src/libasr/codegen/wasm_to_x86.cpp +++ b/src/libasr/codegen/wasm_to_x86.cpp @@ -252,6 +252,9 @@ Result wasm_to_x86(Vec &wasm_bytes, Allocator &al, .count(); } + //! Helpful for debugging + // std::cout << x86_visitor.m_a.get_asm() << std::endl; + if (time_report) { std::cout << "Codegen Time report:" << std::endl; std::cout << "Decode wasm: " << std::setw(5) << time_decode_wasm From 4b0919144e23f664bf6c9e0729334fc8ecef8e9f Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Fri, 4 Nov 2022 21:49:46 +0530 Subject: [PATCH 5/7] TEST: WASM_X86: Add test for if-else --- integration_tests/if_01.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 integration_tests/if_01.py diff --git a/integration_tests/if_01.py b/integration_tests/if_01.py new file mode 100644 index 0000000000..82a1218d83 --- /dev/null +++ b/integration_tests/if_01.py @@ -0,0 +1,28 @@ +def Test_if_01(): + if True: + print(1) + + if False: + print(0) + + if 1 < 0: + print(0) + else: + print(1) + + if 1 > 0: + print(1) + else: + print(0) + + if 1 < 0: + print(1) + elif 1 > 0: + print(1) + else: + print(0) + +def Verify(): + Test_if_01() + +Verify() From bfa588709b4e98f7d5f3287c0e0e44e48a74c599 Mon Sep 17 00:00:00 2001 From: Ubaid Date: Fri, 4 Nov 2022 21:56:21 +0530 Subject: [PATCH 6/7] TEST: WASM_X86: Add another test for if-else --- integration_tests/if_01.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/integration_tests/if_01.py b/integration_tests/if_01.py index 82a1218d83..090928c739 100644 --- a/integration_tests/if_01.py +++ b/integration_tests/if_01.py @@ -22,7 +22,38 @@ def Test_if_01(): else: print(0) +def Test_if_02(): + if True: + print(1) + if True: + print(2) + if False: + print(3) + elif True: + print(4) + else: + print(5) + else: + print(6) + + if True: + print(7) + if False: + print(8) + if False: + print(9) + else: + print(10) + else: + if True: + print(11) + else: + print(12) + print(13) + print(14) + def Verify(): Test_if_01() + Test_if_02() Verify() From 4093db18a8b6baf1c54ad326032d3bf381b7f941 Mon Sep 17 00:00:00 2001 From: Ubaid Date: Fri, 4 Nov 2022 21:59:21 +0530 Subject: [PATCH 7/7] TEST: Update reference tests --- tests/reference/wat-loop1-e0046d4.json | 2 +- tests/reference/wat-loop1-e0046d4.stdout | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/reference/wat-loop1-e0046d4.json b/tests/reference/wat-loop1-e0046d4.json index e36e213485..1dfe8a94b6 100644 --- a/tests/reference/wat-loop1-e0046d4.json +++ b/tests/reference/wat-loop1-e0046d4.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "wat-loop1-e0046d4.stdout", - "stdout_hash": "12b741cf8600fa79f42d342a3fd339bc84963713fd1257d6d4b4141b", + "stdout_hash": "f6dfe3c647ade9c3166a32025fac278f4ab5b6e04fea7f2192fb4ce7", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/wat-loop1-e0046d4.stdout b/tests/reference/wat-loop1-e0046d4.stdout index c28ebcb195..5aec19cf8b 100644 --- a/tests/reference/wat-loop1-e0046d4.stdout +++ b/tests/reference/wat-loop1-e0046d4.stdout @@ -48,6 +48,7 @@ local.set 1 local.get 1 return + else end i32.const 1 local.set 2 @@ -119,6 +120,7 @@ local.set 1 local.get 1 return + else end i64.const 1 local.set 2