Skip to content

Commit 78c8347

Browse files
authored
Merge pull request #1384 from Thirumalai-Shaktivel/global_stmts
Initial support for global Lists
2 parents 9da3fce + f86901d commit 78c8347

11 files changed

+83
-13
lines changed

integration_tests/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,4 +432,5 @@ RUN(NAME bit_operations_i32 LABELS cpython llvm wasm wasm_x64)
432432
RUN(NAME bit_operations_i64 LABELS cpython llvm wasm)
433433

434434
RUN(NAME test_argv_01 LABELS llvm) # TODO: Test using CPython
435-
RUN(NAME global_syms_01 LABELS cpython)
435+
RUN(NAME global_syms_01 LABELS cpython llvm)
436+
RUN(NAME global_syms_02 LABELS cpython llvm)

integration_tests/global_syms_02.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from ltypes import i32
2+
3+
x: list[i32]
4+
x = [0, 1]
5+
x.append(3)
6+
7+
def test_global_symbols():
8+
assert len(x) == 3
9+
x.insert(2, 2)
10+
11+
test_global_symbols()
12+
13+
i: i32
14+
for i in range(len(x)):
15+
assert i == x[i]
16+
17+
tmp: list[i32]
18+
tmp = x
19+
20+
tmp.remove(0)
21+
assert len(tmp) == 3
22+
tmp.clear()
23+
assert len(tmp) == 0

src/libasr/asr_scopes.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,11 @@ std::string SymbolTable::get_unique_name(const std::string &name) {
137137

138138
void SymbolTable::move_symbols_from_global_scope(Allocator &al,
139139
SymbolTable *module_scope, Vec<char *> &syms,
140-
Vec<char *> &mod_dependencies) {
140+
Vec<char *> &mod_dependencies, Vec<ASR::stmt_t*> &var_init) {
141141
// TODO: This isn't scalable. We have write a visitor in asdl_cpp.py
142142
syms.reserve(al, 4);
143143
mod_dependencies.reserve(al, 4);
144+
var_init.reserve(al, 4);
144145
for (auto &a : scope) {
145146
switch (a.second->type) {
146147
case (ASR::symbolType::Module): {
@@ -225,6 +226,21 @@ void SymbolTable::move_symbols_from_global_scope(Allocator &al,
225226
} case (ASR::symbolType::Variable) : {
226227
ASR::Variable_t *v = ASR::down_cast<ASR::Variable_t>(a.second);
227228
v->m_parent_symtab = module_scope;
229+
if (v->m_symbolic_value && !ASR::is_a<ASR::Const_t>(*v->m_type)) {
230+
ASR::expr_t* v_expr = ASRUtils::EXPR(ASR::make_Var_t(
231+
al, v->base.base.loc, (ASR::symbol_t *) v));
232+
ASR::asr_t* assign = ASR::make_Assignment_t(al,
233+
v->base.base.loc, v_expr, v->m_symbolic_value, nullptr);
234+
var_init.push_back(al, ASRUtils::STMT(assign));
235+
v->m_symbolic_value = nullptr;
236+
v->m_value = nullptr;
237+
Vec<char*> v_dependencies;
238+
v_dependencies.reserve(al, 1);
239+
ASRUtils::collect_variable_dependencies(al,
240+
v_dependencies, v->m_type);
241+
v->m_dependencies = v_dependencies.p;
242+
v->n_dependencies = v_dependencies.size();
243+
}
228244
module_scope->add_symbol(a.first, (ASR::symbol_t *) v);
229245
syms.push_back(al, s2c(al, a.first));
230246
break;

src/libasr/asr_scopes.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace LCompilers {
1010

1111
namespace ASR {
1212
struct asr_t;
13+
struct stmt_t;
1314
struct symbol_t;
1415
}
1516

@@ -84,7 +85,7 @@ struct SymbolTable {
8485

8586
void move_symbols_from_global_scope(Allocator &al,
8687
SymbolTable *module_scope, Vec<char *> &syms,
87-
Vec<char *> &mod_dependencies);
88+
Vec<char *> &mod_dependencies, Vec<ASR::stmt_t*> &var_init);
8889
};
8990

9091
} // namespace LCompilers

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2296,6 +2296,14 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
22962296
}
22972297
}
22982298
llvm_symtab[h] = ptr;
2299+
} else if (x.m_type->type == ASR::ttypeType::List) {
2300+
llvm::StructType* list_type = static_cast<llvm::StructType*>(
2301+
get_type_from_ttype_t_util(x.m_type));
2302+
llvm::Constant *ptr = module->getOrInsertGlobal(x.m_name, list_type);
2303+
module->getNamedGlobal(x.m_name)->setInitializer(
2304+
llvm::ConstantStruct::get(list_type,
2305+
llvm::Constant::getNullValue(list_type)));
2306+
llvm_symtab[h] = ptr;
22992307
} else if (x.m_type->type == ASR::ttypeType::TypeParameter) {
23002308
// Ignore type variables
23012309
} else {
@@ -7015,7 +7023,7 @@ Result<std::unique_ptr<LLVMModule>> asr_to_llvm(ASR::TranslationUnit_t &asr,
70157023
pass_manager.apply_passes(al, &asr, pass_options, diagnostics);
70167024

70177025
// Uncomment for debugging the ASR after the transformation
7018-
// std::cout << pickle(asr, true, true, true) << std::endl;
7026+
// std::cout << LPython::pickle(asr, true, true, true) << std::endl;
70197027

70207028
v.nested_func_types = pass_find_nested_vars(asr, context,
70217029
v.nested_globals, v.nested_call_out, v.nesting_map);

src/libasr/pass/global_symbols.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,35 @@ namespace LCompilers {
1616

1717
void pass_wrap_global_syms_into_module(Allocator &al,
1818
ASR::TranslationUnit_t &unit,
19-
const LCompilers::PassOptions& /*pass_options*/) {
19+
const LCompilers::PassOptions& pass_options) {
2020
Location loc = unit.base.base.loc;
2121
char *module_name = s2c(al, "_global_symbols");
2222
SymbolTable *module_scope = al.make_new<SymbolTable>(unit.m_global_scope);
2323
Vec<char *> moved_symbols;
2424
Vec<char *> mod_dependencies;
25+
Vec<ASR::stmt_t*> var_init;
2526

2627
// Move all the symbols from global into the module scope
2728
unit.m_global_scope->move_symbols_from_global_scope(al, module_scope,
28-
moved_symbols, mod_dependencies);
29+
moved_symbols, mod_dependencies, var_init);
2930

3031
// Erase the symbols that are moved into the module
3132
for (auto &sym: moved_symbols) {
3233
unit.m_global_scope->erase_symbol(sym);
3334
}
3435

36+
if (module_scope->get_symbol(pass_options.run_fun) && var_init.n > 0) {
37+
ASR::Function_t *f = ASR::down_cast<ASR::Function_t>(
38+
module_scope->get_symbol(pass_options.run_fun));
39+
for (size_t i = 0; i < f->n_body; i++) {
40+
var_init.push_back(al, f->m_body[i]);
41+
}
42+
f->m_body = var_init.p;
43+
f->n_body = var_init.n;
44+
// Overwrites the function: `_lpython_main_program`
45+
module_scope->add_symbol(f->m_name, (ASR::symbol_t *) f);
46+
}
47+
3548
Vec<char *> m_dependencies;
3649
m_dependencies.reserve(al, mod_dependencies.size());
3750
for( auto &dep: mod_dependencies) {

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3800,6 +3800,10 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
38003800
void visit_For(const AST::For_t &/*x*/) {
38013801
// We skip this in the SymbolTable visitor, but visit it in the BodyVisitor
38023802
}
3803+
3804+
void visit_Assert(const AST::Assert_t &/*x*/) {
3805+
// We skip this in the SymbolTable visitor, but visit it in the BodyVisitor
3806+
}
38033807
};
38043808

38053809
Result<ASR::asr_t*> symbol_table_visitor(Allocator &al, LocationManager &lm, const AST::Module_t &ast,

tests/reference/asr-expr_07-7742668.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": "asr-expr_07-7742668.stdout",
9-
"stdout_hash": "36af7cdd0a8bed977355197e5fb0512e1b23f1b36966eef5e83ef244",
9+
"stdout_hash": "e419602ad57368da314d299a740459bc2fd912e9302ef68207e70105",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
(TranslationUnit (SymbolTable 1 {_global_symbols: (Module (SymbolTable 7 {_lpython_main_program: (Function (SymbolTable 6 {}) _lpython_main_program (FunctionType [] () Source Implementation () .false. .false. .false. .false. .false. [] [] .false.) [f bool_to_str] [] [(SubroutineCall 7 f () [] ()) (SubroutineCall 7 bool_to_str () [] ())] () Public .false. .false.), bool_to_str: (Function (SymbolTable 4 {var: (Variable 4 var [] Local () () Default (Logical 4 []) Source Public Required .false.)}) bool_to_str (FunctionType [] () Source Implementation () .false. .false. .false. .false. .false. [] [] .false.) [] [] [(= (Var 4 var) (LogicalConstant .true. (Logical 4 [])) ()) (Print () [(Cast (LogicalConstant .true. (Logical 4 [])) LogicalToCharacter (Character 1 -2 () []) (StringConstant "True" (Character 1 4 () [])))] () ()) (Assert (StringCompare (Cast (Var 4 var) LogicalToCharacter (Character 1 -2 () []) ()) Eq (StringConstant "True" (Character 1 4 () [])) (Logical 4 []) ()) ()) (= (Var 4 var) (LogicalConstant .false. (Logical 4 [])) ()) (Assert (StringCompare (Cast (Var 4 var) LogicalToCharacter (Character 1 -2 () []) ()) Eq (StringConstant "False" (Character 1 5 () [])) (Logical 4 []) ()) ()) (Assert (StringCompare (Cast (LogicalConstant .true. (Logical 4 [])) LogicalToCharacter (Character 1 -2 () []) (StringConstant "True" (Character 1 4 () []))) Eq (StringConstant "True" (Character 1 4 () [])) (Logical 4 []) (LogicalConstant .true. (Logical 4 []))) ())] () Public .false. .false.), f: (Function (SymbolTable 3 {a: (Variable 3 a [] Local (IntegerConstant 5 (Integer 4 [])) () Default (Integer 4 []) Source Public Required .false.), b: (Variable 3 b [x] Local (IntegerBinOp (Var 3 x) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) ()) () Default (Integer 4 []) Source Public Required .false.), x: (Variable 3 x [] Local (IntegerConstant 3 (Integer 4 [])) () Default (Integer 4 []) Source Public Required .false.)}) f (FunctionType [] () Source Implementation () .false. .false. .false. .false. .false. [] [] .false.) [g] [] [(= (Var 3 a) (IntegerConstant 5 (Integer 4 [])) ()) (= (Var 3 x) (IntegerConstant 3 (Integer 4 [])) ()) (= (Var 3 x) (IntegerConstant 5 (Integer 4 [])) ()) (= (Var 3 b) (IntegerBinOp (Var 3 x) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) ()) ()) (Print () [(Var 3 a) (Var 3 b)] () ()) (Assert (IntegerCompare (Var 3 b) Eq (IntegerConstant 6 (Integer 4 [])) (Logical 4 []) ()) ()) (SubroutineCall 7 g () [((IntegerBinOp (IntegerBinOp (Var 3 a) Mul (Var 3 b) (Integer 4 []) ()) Add (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) ()))] ())] () Public .false. .false.), g: (Function (SymbolTable 2 {x: (Variable 2 x [] In () () Default (Integer 4 []) Source Public Required .false.)}) g (FunctionType [(Integer 4 [])] () Source Implementation () .false. .false. .false. .false. .false. [] [] .false.) [] [(Var 2 x)] [(Print () [(Var 2 x)] () ())] () Public .false. .false.), x: (Variable 7 x [] Local (IntegerConstant 7 (Integer 4 [])) () Default (Integer 4 []) Source Public Required .false.)}) _global_symbols [] .false. .false.), main_program: (Program (SymbolTable 5 {_lpython_main_program: (ExternalSymbol 5 _lpython_main_program 7 _lpython_main_program _global_symbols [] _lpython_main_program Public)}) main_program [_global_symbols] [(SubroutineCall 5 _lpython_main_program () [] ())])}) [])
1+
(TranslationUnit (SymbolTable 1 {_global_symbols: (Module (SymbolTable 7 {_lpython_main_program: (Function (SymbolTable 6 {}) _lpython_main_program (FunctionType [] () Source Implementation () .false. .false. .false. .false. .false. [] [] .false.) [f bool_to_str] [] [(= (Var 7 x) (IntegerConstant 7 (Integer 4 [])) ()) (SubroutineCall 7 f () [] ()) (SubroutineCall 7 bool_to_str () [] ())] () Public .false. .false.), bool_to_str: (Function (SymbolTable 4 {var: (Variable 4 var [] Local () () Default (Logical 4 []) Source Public Required .false.)}) bool_to_str (FunctionType [] () Source Implementation () .false. .false. .false. .false. .false. [] [] .false.) [] [] [(= (Var 4 var) (LogicalConstant .true. (Logical 4 [])) ()) (Print () [(Cast (LogicalConstant .true. (Logical 4 [])) LogicalToCharacter (Character 1 -2 () []) (StringConstant "True" (Character 1 4 () [])))] () ()) (Assert (StringCompare (Cast (Var 4 var) LogicalToCharacter (Character 1 -2 () []) ()) Eq (StringConstant "True" (Character 1 4 () [])) (Logical 4 []) ()) ()) (= (Var 4 var) (LogicalConstant .false. (Logical 4 [])) ()) (Assert (StringCompare (Cast (Var 4 var) LogicalToCharacter (Character 1 -2 () []) ()) Eq (StringConstant "False" (Character 1 5 () [])) (Logical 4 []) ()) ()) (Assert (StringCompare (Cast (LogicalConstant .true. (Logical 4 [])) LogicalToCharacter (Character 1 -2 () []) (StringConstant "True" (Character 1 4 () []))) Eq (StringConstant "True" (Character 1 4 () [])) (Logical 4 []) (LogicalConstant .true. (Logical 4 []))) ())] () Public .false. .false.), f: (Function (SymbolTable 3 {a: (Variable 3 a [] Local (IntegerConstant 5 (Integer 4 [])) () Default (Integer 4 []) Source Public Required .false.), b: (Variable 3 b [x] Local (IntegerBinOp (Var 3 x) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) ()) () Default (Integer 4 []) Source Public Required .false.), x: (Variable 3 x [] Local (IntegerConstant 3 (Integer 4 [])) () Default (Integer 4 []) Source Public Required .false.)}) f (FunctionType [] () Source Implementation () .false. .false. .false. .false. .false. [] [] .false.) [g] [] [(= (Var 3 a) (IntegerConstant 5 (Integer 4 [])) ()) (= (Var 3 x) (IntegerConstant 3 (Integer 4 [])) ()) (= (Var 3 x) (IntegerConstant 5 (Integer 4 [])) ()) (= (Var 3 b) (IntegerBinOp (Var 3 x) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) ()) ()) (Print () [(Var 3 a) (Var 3 b)] () ()) (Assert (IntegerCompare (Var 3 b) Eq (IntegerConstant 6 (Integer 4 [])) (Logical 4 []) ()) ()) (SubroutineCall 7 g () [((IntegerBinOp (IntegerBinOp (Var 3 a) Mul (Var 3 b) (Integer 4 []) ()) Add (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) ()))] ())] () Public .false. .false.), g: (Function (SymbolTable 2 {x: (Variable 2 x [] In () () Default (Integer 4 []) Source Public Required .false.)}) g (FunctionType [(Integer 4 [])] () Source Implementation () .false. .false. .false. .false. .false. [] [] .false.) [] [(Var 2 x)] [(Print () [(Var 2 x)] () ())] () Public .false. .false.), x: (Variable 7 x [] Local () () Default (Integer 4 []) Source Public Required .false.)}) _global_symbols [] .false. .false.), main_program: (Program (SymbolTable 5 {_lpython_main_program: (ExternalSymbol 5 _lpython_main_program 7 _lpython_main_program _global_symbols [] _lpython_main_program Public)}) main_program [_global_symbols] [(SubroutineCall 5 _lpython_main_program () [] ())])}) [])

tests/reference/llvm-print_04-443a8d8.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": "llvm-print_04-443a8d8.stdout",
9-
"stdout_hash": "82ed5155deef7a5b597b62a427ca9c33a1dd6650f757223c5c604889",
9+
"stdout_hash": "740498e6d0b9c0a6ffc7f6711e1f8c5bae27b834b726d108fb0e0c18",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

tests/reference/llvm-print_04-443a8d8.stdout

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
; ModuleID = 'LFortran'
22
source_filename = "LFortran"
33

4-
@u = global i64 -922337203685477580
5-
@x = global i32 -2147483648
6-
@y = global i16 -32768
7-
@z = global i8 -128
4+
@u = global i64 0
5+
@x = global i32 0
6+
@y = global i16 0
7+
@z = global i8 0
88
@0 = private unnamed_addr constant [2 x i8] c" \00", align 1
99
@1 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
1010
@2 = private unnamed_addr constant [7 x i8] c"%lld%s\00", align 1
@@ -20,6 +20,10 @@ source_filename = "LFortran"
2020

2121
define void @__module__global_symbols__lpython_main_program() {
2222
.entry:
23+
store i64 -922337203685477580, i64* @u, align 4
24+
store i32 -2147483648, i32* @x, align 4
25+
store i16 -32768, i16* @y, align 2
26+
store i8 -128, i8* @z, align 1
2327
%0 = load i64, i64* @u, align 4
2428
call void (i8*, ...) @_lfortran_printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @2, i32 0, i32 0), i64 %0, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @1, i32 0, i32 0))
2529
%1 = load i32, i32* @x, align 4

0 commit comments

Comments
 (0)