Skip to content

Commit ecd57c3

Browse files
authored
Merge pull request #1277 from Shaikh-Ubaid/func_order_wasm_and_x86
WASM, X86: Support functions order
2 parents b55d10b + b83e67b commit ecd57c3

File tree

8 files changed

+109
-144
lines changed

8 files changed

+109
-144
lines changed

src/libasr/codegen/asr_to_wasm.cpp

Lines changed: 11 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
7272
SymbolFuncInfo *cur_sym_info;
7373
uint32_t nesting_level;
7474
uint32_t cur_loop_nesting_level;
75-
bool is_prototype_only;
7675

7776
Vec<uint8_t> m_type_section;
7877
Vec<uint8_t> m_import_section;
@@ -98,7 +97,6 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
9897
ASRToWASMVisitor(Allocator &al, diag::Diagnostics &diagnostics)
9998
: m_al(al), diag(diagnostics) {
10099
intrinsic_module = false;
101-
is_prototype_only = false;
102100
nesting_level = 0;
103101
cur_loop_nesting_level = 0;
104102
no_of_types = 0;
@@ -253,40 +251,6 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
253251

254252
emit_imports();
255253

256-
{
257-
// Pre-declare all functions first, then generate code
258-
// Otherwise some function might not be found.
259-
is_prototype_only = true;
260-
{
261-
// Process intrinsic modules in the right order
262-
std::vector<std::string> build_order =
263-
ASRUtils::determine_module_dependencies(x);
264-
for (auto &item : build_order) {
265-
LFORTRAN_ASSERT(x.m_global_scope->get_scope().find(item) !=
266-
x.m_global_scope->get_scope().end());
267-
ASR::symbol_t *mod = x.m_global_scope->get_symbol(item);
268-
if (ASR::is_a<ASR::Module_t>(*mod)) {
269-
ASR::Module_t *m =
270-
ASR::down_cast<ASR::Module_t>(mod);
271-
declare_all_functions(*(m->m_symtab));
272-
}
273-
}
274-
275-
// Process procedures first:
276-
declare_all_functions(*x.m_global_scope);
277-
278-
// then the main program:
279-
for (auto &item : x.m_global_scope->get_scope()) {
280-
if (ASR::is_a<ASR::Program_t>(*item.second)) {
281-
ASR::Program_t *p =
282-
ASR::down_cast<ASR::Program_t>(item.second);
283-
declare_all_functions(*(p->m_symtab));
284-
}
285-
}
286-
}
287-
is_prototype_only = false;
288-
}
289-
290254
{
291255
// Process intrinsic modules in the right order
292256
std::vector<std::string> build_order =
@@ -302,19 +266,6 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
302266
// Process procedures first:
303267
declare_all_functions(*x.m_global_scope);
304268

305-
// // Then do all the modules in the right order
306-
// std::vector<std::string> build_order
307-
// = LFortran::ASRUtils::determine_module_dependencies(x);
308-
// for (auto &item : build_order) {
309-
// LFORTRAN_ASSERT(x.m_global_scope->get_scope().find(item)
310-
// != x.m_global_scope->get_scope().end());
311-
// if (!startswith(item, "lfortran_intrinsic")) {
312-
// ASR::symbol_t *mod = x.m_global_scope->get_symbol(item);
313-
// visit_symbol(*mod);
314-
// // std::cout << "I am here -2: " << src << std::endl;
315-
// }
316-
// }
317-
318269
// then the main program:
319270
for (auto &item : x.m_global_scope->get_scope()) {
320271
if (ASR::is_a<ASR::Program_t>(*item.second)) {
@@ -323,13 +274,17 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
323274
}
324275
}
325276

326-
void declare_all_functions(const SymbolTable &symtab) {
327-
for (auto &item : symtab.get_scope()) {
328-
if (ASR::is_a<ASR::Function_t>(*item.second)) {
329-
ASR::Function_t *s =
330-
ASR::down_cast<ASR::Function_t>(item.second);
331-
this->visit_Function(*s);
277+
void declare_all_functions(SymbolTable &symtab) {
278+
std::vector<std::string> func_order = ASRUtils::determine_function_definition_order(&symtab);
279+
280+
for (auto &item : func_order) {
281+
ASR::symbol_t* sym = symtab.get_symbol(item);
282+
if( !sym || ASR::is_a<ASR::ExternalSymbol_t>(*sym) ) {
283+
continue;
332284
}
285+
286+
ASR::Function_t *s = ASR::down_cast<ASR::Function_t>(sym);
287+
this->visit_Function(*s);
333288
}
334289
}
335290

@@ -656,10 +611,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
656611
if (is_unsupported_function(x)) {
657612
return;
658613
}
659-
if (is_prototype_only) {
660-
emit_function_prototype(x);
661-
return;
662-
}
614+
emit_function_prototype(x);
663615
emit_function_body(x);
664616
}
665617

src/libasr/codegen/asr_to_x86.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,21 @@ class ASRToX86Visitor : public ASR::BaseVisitor<ASRToX86Visitor>
6666
emit_print_int(m_a, "print_int");
6767
emit_exit(m_a, "exit", 0);
6868
emit_exit(m_a, "exit_error_stop", 1);
69+
70+
71+
std::vector<std::string> global_func_order = ASRUtils::determine_function_definition_order(x.m_global_scope);
72+
for (size_t i = 0; i < global_func_order.size(); i++) {
73+
ASR::symbol_t* sym = x.m_global_scope->get_symbol(global_func_order[i]);
74+
// Ignore external symbols because they are already defined by the loop above.
75+
if( !sym || ASR::is_a<ASR::ExternalSymbol_t>(*sym) ) {
76+
continue;
77+
}
78+
visit_symbol(*sym);
79+
}
80+
81+
// Then the main program:
6982
for (auto &item : x.m_global_scope->get_scope()) {
70-
if (!is_a<ASR::Variable_t>(*item.second)) {
83+
if (ASR::is_a<ASR::Program_t>(*item.second)) {
7184
visit_symbol(*item.second);
7285
}
7386
}
@@ -79,12 +92,12 @@ class ASRToX86Visitor : public ASR::BaseVisitor<ASRToX86Visitor>
7992

8093

8194

95+
std::vector<std::string> func_order = ASRUtils::determine_function_definition_order(x.m_symtab);
8296
// Generate code for nested subroutines and functions first:
83-
for (auto &item : x.m_symtab->get_scope()) {
84-
if (ASR::is_a<ASR::Function_t>(*item.second)) {
85-
ASR::Function_t *s = ASR::down_cast<ASR::Function_t>(item.second);
86-
visit_Function(*s);
87-
}
97+
for (auto &item : func_order) {
98+
ASR::symbol_t* sym = x.m_symtab->get_symbol(item);
99+
ASR::Function_t *s = ASR::down_cast<ASR::Function_t>(sym);
100+
visit_Function(*s);
88101
}
89102

90103
// Generate code for the main program

tests/reference/wat-bool1-234bcd1.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "wat-bool1-234bcd1.stdout",
9-
"stdout_hash": "235761433f3097c680ce7c54080cb3f27a131c9a9fd3aed9dd0d2fe2",
9+
"stdout_hash": "bdda8bc9b4fc26e58649491b38a6ae916c1d975dc512ba7279e67c96",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

tests/reference/wat-bool1-234bcd1.stdout

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@
1818
(import "js" "set_exit_code" (func (;6;) (type 6)))
1919
(import "js" "memory" (memory (;0;) 100 100))
2020
(func $7 (type 7) (param) (result)
21-
(local)
22-
call 8
23-
return
24-
)
25-
(func $8 (type 8) (param) (result)
2621
(local i32)
2722
i32.const 1
2823
call 0
@@ -42,14 +37,19 @@
4237
call 5
4338
return
4439
)
45-
(func $9 (type 9) (param) (result)
40+
(func $8 (type 8) (param) (result)
4641
(local)
4742
call 7
43+
return
44+
)
45+
(func $9 (type 9) (param) (result)
46+
(local)
47+
call 8
4848
i32.const 0
4949
call 6
5050
return
5151
)
52-
(export "_lpython_main_program" (func $7))
53-
(export "test_bool" (func $8))
52+
(export "test_bool" (func $7))
53+
(export "_lpython_main_program" (func $8))
5454
(export "_lcompilers_main" (func $9))
5555
)

tests/reference/wat-expr9-f73afd1.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "wat-expr9-f73afd1.stdout",
9-
"stdout_hash": "d7ac1c89f14174c429ed7c9dce64649725bb933e3108cbbc3f2a366d",
9+
"stdout_hash": "21df58f9a5b6ad2f256e8c115142c320a730fa09a762fbac2609bf53",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

tests/reference/wat-expr9-f73afd1.stdout

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
(type (;4;) (func (param i32 i32) (result)))
77
(type (;5;) (func (param) (result)))
88
(type (;6;) (func (param i32) (result)))
9-
(type (;7;) (func (param) (result)))
10-
(type (;8;) (func (param) (result)))
9+
(type (;7;) (func (param i32) (result i32)))
10+
(type (;8;) (func (param i32) (result i32)))
1111
(type (;9;) (func (param i32) (result i32)))
12-
(type (;10;) (func (param i32) (result i32)))
13-
(type (;11;) (func (param i32) (result i32)))
14-
(type (;12;) (func (param i32) (result)))
12+
(type (;10;) (func (param i32) (result)))
13+
(type (;11;) (func (param) (result)))
14+
(type (;12;) (func (param) (result)))
1515
(type (;13;) (func (param) (result)))
1616
(import "js" "print_i32" (func (;0;) (type 0)))
1717
(import "js" "print_i64" (func (;1;) (type 1)))
@@ -21,27 +21,7 @@
2121
(import "js" "flush_buf" (func (;5;) (type 5)))
2222
(import "js" "set_exit_code" (func (;6;) (type 6)))
2323
(import "js" "memory" (memory (;0;) 100 100))
24-
(func $7 (type 7) (param) (result)
25-
(local)
26-
call 8
27-
return
28-
)
29-
(func $8 (type 8) (param) (result)
30-
(local i32 i32)
31-
i32.const 4
32-
call 9
33-
local.set 0
34-
i32.const 4
35-
call 10
36-
local.set 1
37-
i32.const 4
38-
call 11
39-
local.set 0
40-
i32.const 4
41-
call 12
42-
return
43-
)
44-
(func $9 (type 9) (param i32) (result i32)
24+
(func $7 (type 7) (param i32) (result i32)
4525
(local i32 i32)
4626
i32.const 5
4727
local.set 2
@@ -50,7 +30,7 @@
5030
local.get 1
5131
return
5232
)
53-
(func $10 (type 10) (param i32) (result i32)
33+
(func $8 (type 8) (param i32) (result i32)
5434
(local i32 i32)
5535
i32.const 0
5636
local.set 2
@@ -59,7 +39,7 @@
5939
local.get 1
6040
return
6141
)
62-
(func $11 (type 11) (param i32) (result i32)
42+
(func $9 (type 9) (param i32) (result i32)
6343
(local i32)
6444
i32.const 3
6545
local.set 0
@@ -68,25 +48,45 @@
6848
local.get 1
6949
return
7050
)
71-
(func $12 (type 12) (param i32) (result)
51+
(func $10 (type 10) (param i32) (result)
7252
(local)
7353
i32.const 1
7454
local.set 0
7555
return
7656
)
57+
(func $11 (type 11) (param) (result)
58+
(local i32 i32)
59+
i32.const 4
60+
call 7
61+
local.set 0
62+
i32.const 4
63+
call 8
64+
local.set 1
65+
i32.const 4
66+
call 9
67+
local.set 0
68+
i32.const 4
69+
call 10
70+
return
71+
)
72+
(func $12 (type 12) (param) (result)
73+
(local)
74+
call 11
75+
return
76+
)
7777
(func $13 (type 13) (param) (result)
7878
(local)
79-
call 7
79+
call 12
8080
i32.const 0
8181
call 6
8282
return
8383
)
84-
(export "_lpython_main_program" (func $7))
85-
(export "main0" (func $8))
86-
(export "test_return_1" (func $9))
87-
(export "test_return_2" (func $10))
88-
(export "test_return_3" (func $11))
89-
(export "test_return_4" (func $12))
84+
(export "test_return_1" (func $7))
85+
(export "test_return_2" (func $8))
86+
(export "test_return_3" (func $9))
87+
(export "test_return_4" (func $10))
88+
(export "main0" (func $11))
89+
(export "_lpython_main_program" (func $12))
9090
(export "_lcompilers_main" (func $13))
9191
(data (;0;) (i32.const 0) "test")
9292
)

tests/reference/wat-loop1-e0046d4.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "wat-loop1-e0046d4.stdout",
9-
"stdout_hash": "f6dfe3c647ade9c3166a32025fac278f4ab5b6e04fea7f2192fb4ce7",
9+
"stdout_hash": "72c18793b437f96f1f96c9f8fc8cc253601fb360929216a4de1cb2f1",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

0 commit comments

Comments
 (0)