Skip to content

Commit 1bc3a3b

Browse files
committed
wip
1 parent 4fd0811 commit 1bc3a3b

File tree

4 files changed

+114
-50
lines changed

4 files changed

+114
-50
lines changed

integration_tests/test_list_06.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from ltypes import i32, f64
2+
3+
def test_list_of_lists():
4+
mat: list[list[f64]] = []
5+
vec: list[f64] = [1.0, 2.0, 3.0]
6+
rows: i32 = 10
7+
cols: i32 = 5
8+
i: i32
9+
j: i32
10+
11+
mat.append(vec)
12+
vec[0] = -1.0
13+
print(mat[0][0], vec[0])
14+
15+
test_list_of_lists()

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
244244
ptr_loads(2),
245245
is_assignment_target(false)
246246
{
247+
llvm_utils->tuple_api = tuple_api.get();
248+
llvm_utils->list_api = list_api.get();
247249
}
248250

249251
llvm::Value* CreateLoad(llvm::Value *x) {
@@ -1147,7 +1149,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
11471149
this->visit_expr(*x.m_args[i]);
11481150
llvm::Value* item = tmp;
11491151
llvm::Value* pos = llvm::ConstantInt::get(context, llvm::APInt(32, i));
1150-
list_api->write_item(const_list, pos, item);
1152+
list_api->write_item(const_list, pos, item, list_type->m_type, *module);
11511153
}
11521154
ptr_loads = ptr_loads_copy;
11531155
tmp = const_list;
@@ -1203,18 +1205,18 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
12031205
}
12041206

12051207
void visit_ListAppend(const ASR::ListAppend_t& x) {
1208+
ASR::List_t* asr_list = ASR::down_cast<ASR::List_t>(ASRUtils::expr_type(x.m_a));
12061209
uint64_t ptr_loads_copy = ptr_loads;
12071210
ptr_loads = 0;
12081211
this->visit_expr(*x.m_a);
1209-
ptr_loads = ptr_loads_copy;
12101212
llvm::Value* plist = tmp;
12111213

1214+
ptr_loads = !LLVM::is_llvm_struct(asr_list->m_type);
12121215
this->visit_expr_wrapper(x.m_ele, true);
12131216
llvm::Value *item = tmp;
1217+
ptr_loads = ptr_loads_copy;
12141218

1215-
ASR::List_t* asr_list = ASR::down_cast<ASR::List_t>(ASRUtils::expr_type(x.m_a));
1216-
std::string type_code = ASRUtils::get_type_code(asr_list->m_type);
1217-
list_api->append(plist, item, *module, type_code);
1219+
list_api->append(plist, item, asr_list->m_type, *module);
12181220
}
12191221

12201222
void visit_ListItem(const ASR::ListItem_t& x) {
@@ -1230,11 +1232,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
12301232
ptr_loads = ptr_loads_copy;
12311233
llvm::Value *pos = tmp;
12321234

1233-
bool get_pointer = false;
1234-
if( ASR::is_a<ASR::Tuple_t>(*el_type) ) {
1235-
get_pointer = true;
1236-
}
1237-
tmp = list_api->read_item(plist, pos, get_pointer);
1235+
tmp = list_api->read_item(plist, pos, LLVM::is_llvm_struct(el_type));
12381236
}
12391237

12401238
void visit_ListLen(const ASR::ListLen_t& x) {
@@ -1251,23 +1249,23 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
12511249
}
12521250

12531251
void visit_ListInsert(const ASR::ListInsert_t& x) {
1252+
ASR::List_t* asr_list = ASR::down_cast<ASR::List_t>(
1253+
ASRUtils::expr_type(x.m_a));
12541254
uint64_t ptr_loads_copy = ptr_loads;
12551255
ptr_loads = 0;
12561256
this->visit_expr(*x.m_a);
1257-
ptr_loads = ptr_loads_copy;
12581257
llvm::Value* plist = tmp;
12591258

1259+
ptr_loads = 1;
12601260
this->visit_expr_wrapper(x.m_pos, true);
12611261
llvm::Value *pos = tmp;
12621262

1263+
ptr_loads = !LLVM::is_llvm_struct(asr_list->m_type);
12631264
this->visit_expr_wrapper(x.m_ele, true);
12641265
llvm::Value *item = tmp;
1266+
ptr_loads = ptr_loads_copy;
12651267

1266-
ASR::List_t* asr_list = ASR::down_cast<ASR::List_t>(
1267-
ASRUtils::expr_type(x.m_a));
1268-
std::string type_code = ASRUtils::get_type_code(asr_list->m_type);
1269-
1270-
list_api->insert_item(plist, pos, item, *module, type_code);
1268+
list_api->insert_item(plist, pos, item, asr_list->m_type, *module);
12711269
}
12721270

12731271
void visit_ListRemove(const ASR::ListRemove_t& x) {
@@ -1277,7 +1275,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
12771275
this->visit_expr(*x.m_a);
12781276
llvm::Value* plist = tmp;
12791277

1280-
ptr_loads = ASR::is_a<ASR::Tuple_t>(*asr_el_type) ? 0 : ptr_loads_copy;
1278+
ptr_loads = !LLVM::is_llvm_struct(asr_el_type);
12811279
this->visit_expr_wrapper(x.m_ele, true);
12821280
ptr_loads = ptr_loads_copy;
12831281
llvm::Value *item = tmp;
@@ -2960,7 +2958,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
29602958
ASR::List_t* value_asr_list = ASR::down_cast<ASR::List_t>(
29612959
ASRUtils::expr_type(x.m_value));
29622960
std::string value_type_code = ASRUtils::get_type_code(value_asr_list->m_type);
2963-
list_api->list_deepcopy(value_list, target_list, value_type_code, *module);
2961+
list_api->list_deepcopy(value_list, target_list,
2962+
value_asr_list, *module);
29642963
return ;
29652964
} else if( is_target_tuple && is_value_tuple ) {
29662965
uint64_t ptr_loads_copy = ptr_loads;
@@ -2998,7 +2997,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
29982997
ASR::Tuple_t* value_tuple_type = ASR::down_cast<ASR::Tuple_t>(asr_value_type);
29992998
std::string type_code = ASRUtils::get_type_code(value_tuple_type->m_type,
30002999
value_tuple_type->n_type);
3001-
tuple_api->tuple_deepcopy(value_tuple, target_tuple, type_code);
3000+
tuple_api->tuple_deepcopy(value_tuple, target_tuple,
3001+
value_tuple_type, *module);
30023002
}
30033003
}
30043004
return ;

src/libasr/codegen/llvm_utils.cpp

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ namespace LFortran {
195195
}
196196
case ASR::ttypeType::Tuple: {
197197
ASR::Tuple_t* tuple_type = ASR::down_cast<ASR::Tuple_t>(asr_type);
198-
return LLVMTuple::check_tuple_equality(left, right, tuple_type, context,
199-
this, builder, module);
198+
return tuple_api->check_tuple_equality(left, right, tuple_type, context,
199+
builder, module);
200200
}
201201
default: {
202202
throw LCompilersException("LLVMUtils::is_equal_by_value isn't implemented for " +
@@ -205,6 +205,34 @@ namespace LFortran {
205205
}
206206
}
207207

208+
void LLVMUtils::deepcopy(llvm::Value* src, llvm::Value* dest,
209+
ASR::ttype_t* asr_type, llvm::Module& module) {
210+
switch( asr_type->type ) {
211+
case ASR::ttypeType::Integer:
212+
case ASR::ttypeType::Real:
213+
case ASR::ttypeType::Character:
214+
case ASR::ttypeType::Logical:
215+
case ASR::ttypeType::Complex: {
216+
LLVM::CreateStore(*builder, src, dest);
217+
break ;
218+
};
219+
case ASR::ttypeType::Tuple: {
220+
ASR::Tuple_t* tuple_type = ASR::down_cast<ASR::Tuple_t>(asr_type);
221+
tuple_api->tuple_deepcopy(src, dest, tuple_type, module);
222+
break ;
223+
}
224+
case ASR::ttypeType::List: {
225+
ASR::List_t* list_type = ASR::down_cast<ASR::List_t>(asr_type);
226+
list_api->list_deepcopy(src, dest, list_type, module);
227+
break ;
228+
}
229+
default: {
230+
throw LCompilersException("LLVMUtils::deepcopy isn't implemented for " +
231+
ASRUtils::type_to_str_python(asr_type));
232+
}
233+
}
234+
}
235+
208236
LLVMList::LLVMList(llvm::LLVMContext& context_,
209237
LLVMUtils* llvm_utils_,
210238
llvm::IRBuilder<>* builder_):
@@ -259,9 +287,9 @@ namespace LFortran {
259287
}
260288

261289
void LLVMList::list_deepcopy(llvm::Value* src, llvm::Value* dest,
262-
std::string& src_type_code,
263-
llvm::Module& module) {
290+
ASR::List_t* list_type, llvm::Module& module) {
264291
LFORTRAN_ASSERT(src->getType() == dest->getType());
292+
std::string src_type_code = ASRUtils::get_type_code(list_type->m_type);
265293
llvm::Value* src_end_point = LLVM::CreateLoad(*builder, get_pointer_to_current_end_point(src));
266294
llvm::Value* src_capacity = LLVM::CreateLoad(*builder, get_pointer_to_current_capacity(src));
267295
llvm::Value* dest_end_point_ptr = get_pointer_to_current_end_point(dest);
@@ -281,10 +309,19 @@ namespace LFortran {
281309
builder->CreateStore(copy_data, get_pointer_to_list_data(dest));
282310
}
283311

284-
void LLVMList::write_item(llvm::Value* list, llvm::Value* pos, llvm::Value* item) {
312+
void LLVMList::write_item(llvm::Value* list, llvm::Value* pos,
313+
llvm::Value* item, ASR::ttype_t* asr_type,
314+
llvm::Module& module) {
315+
llvm::Value* list_data = LLVM::CreateLoad(*builder, get_pointer_to_list_data(list));
316+
llvm::Value* element_ptr = llvm_utils->create_ptr_gep(list_data, pos);
317+
llvm_utils->deepcopy(item, element_ptr, asr_type, module);
318+
}
319+
320+
void LLVMList::write_item(llvm::Value* list, llvm::Value* pos,
321+
llvm::Value* item) {
285322
llvm::Value* list_data = LLVM::CreateLoad(*builder, get_pointer_to_list_data(list));
286323
llvm::Value* element_ptr = llvm_utils->create_ptr_gep(list_data, pos);
287-
builder->CreateStore(item, element_ptr);
324+
LLVM::CreateStore(*builder, item, element_ptr);
288325
}
289326

290327
llvm::Value* LLVMList::read_item(llvm::Value* list, llvm::Value* pos, bool get_pointer) {
@@ -337,21 +374,22 @@ namespace LFortran {
337374
}
338375

339376
void LLVMList::append(llvm::Value* list, llvm::Value* item,
340-
llvm::Module& module,
341-
std::string& type_code) {
377+
ASR::ttype_t* asr_type, llvm::Module& module) {
342378
llvm::Value* current_end_point = LLVM::CreateLoad(*builder, get_pointer_to_current_end_point(list));
343379
llvm::Value* current_capacity = LLVM::CreateLoad(*builder, get_pointer_to_current_capacity(list));
380+
std::string type_code = ASRUtils::get_type_code(asr_type);
344381
int type_size = std::get<1>(typecode2listtype[type_code]);
345382
llvm::Type* el_type = std::get<2>(typecode2listtype[type_code]);
346383
resize_if_needed(list, current_end_point, current_capacity,
347384
type_size, el_type, module);
348-
write_item(list, current_end_point, item);
385+
write_item(list, current_end_point, item, asr_type, module);
349386
shift_end_point_by_one(list);
350387
}
351388

352389
void LLVMList::insert_item(llvm::Value* list, llvm::Value* pos,
353-
llvm::Value* item, llvm::Module& module,
354-
std::string& type_code) {
390+
llvm::Value* item, ASR::ttype_t* asr_type,
391+
llvm::Module& module) {
392+
std::string type_code = ASRUtils::get_type_code(asr_type);
355393
llvm::Value* current_end_point = LLVM::CreateLoad(*builder,
356394
get_pointer_to_current_end_point(list));
357395
llvm::Value* current_capacity = LLVM::CreateLoad(*builder,
@@ -406,7 +444,7 @@ namespace LFortran {
406444
LLVM::CreateLoad(*builder, pos_ptr),
407445
llvm::ConstantInt::get(context, llvm::APInt(32, 1)));
408446
tmp = read_item(list, next_index, false);
409-
write_item(list, next_index, LLVM::CreateLoad(*builder, tmp_ptr));
447+
write_item(list, next_index, LLVM::CreateLoad(*builder, tmp_ptr));
410448
LLVM::CreateStore(*builder, tmp, tmp_ptr);
411449

412450
tmp = builder->CreateAdd(
@@ -419,7 +457,7 @@ namespace LFortran {
419457
// end
420458
llvm_utils->start_new_block(loopend);
421459

422-
write_item(list, pos, item);
460+
write_item(list, pos, item, asr_type, module);
423461
shift_end_point_by_one(list);
424462
}
425463

@@ -601,27 +639,26 @@ namespace LFortran {
601639
}
602640

603641
void LLVMTuple::tuple_deepcopy(llvm::Value* src, llvm::Value* dest,
604-
std::string& type_code) {
642+
ASR::Tuple_t* tuple_type, llvm::Module& module) {
605643
LFORTRAN_ASSERT(src->getType() == dest->getType());
606-
size_t n_elements = typecode2tupletype[type_code].second;
607-
for( size_t i = 0; i < n_elements; i++ ) {
608-
llvm::Value* src_item = read_item(src, i, false);
644+
for( size_t i = 0; i < tuple_type->n_type; i++ ) {
645+
llvm::Value* src_item = read_item(src, i, LLVM::is_llvm_struct(
646+
tuple_type->m_type[i]));
609647
llvm::Value* dest_item_ptr = read_item(dest, i, true);
610-
builder->CreateStore(src_item, dest_item_ptr);
648+
llvm_utils->deepcopy(src_item, dest_item_ptr,
649+
tuple_type->m_type[i], module);
611650
}
612651
}
613652

614653
llvm::Value* LLVMTuple::check_tuple_equality(llvm::Value* t1, llvm::Value* t2,
615654
ASR::Tuple_t* tuple_type,
616655
llvm::LLVMContext& context,
617-
LLVMUtils* llvm_utils,
618656
llvm::IRBuilder<>* builder,
619657
llvm::Module& module) {
620-
LLVMTuple tuple_api(context, llvm_utils, builder);
621658
llvm::Value* is_equal = llvm::ConstantInt::get(context, llvm::APInt(1, 1));
622659
for( size_t i = 0; i < tuple_type->n_type; i++ ) {
623-
llvm::Value* t1i = tuple_api.read_item(t1, i);
624-
llvm::Value* t2i = tuple_api.read_item(t2, i);
660+
llvm::Value* t1i = llvm_utils->tuple_api->read_item(t1, i);
661+
llvm::Value* t2i = llvm_utils->tuple_api->read_item(t2, i);
625662
llvm::Value* is_t1_eq_t2 = llvm_utils->is_equal_by_value(t1i, t2i, module,
626663
tuple_type->m_type[i]);
627664
is_equal = builder->CreateAnd(is_equal, is_t1_eq_t2);

src/libasr/codegen/llvm_utils.h

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,14 @@ namespace LFortran {
5252
static inline bool is_llvm_struct(ASR::ttype_t* asr_type) {
5353
return ASR::is_a<ASR::Tuple_t>(*asr_type) ||
5454
ASR::is_a<ASR::List_t>(*asr_type) ||
55-
ASR::is_a<ASR::Complex_t>(*asr_type) ||
5655
ASR::is_a<ASR::Derived_t>(*asr_type) ||
5756
ASR::is_a<ASR::Class_t>(*asr_type);
5857
}
5958
}
6059

60+
class LLVMList;
61+
class LLVMTuple;
62+
6163
class LLVMUtils {
6264

6365
private:
@@ -67,6 +69,9 @@ namespace LFortran {
6769

6870
public:
6971

72+
LLVMTuple* tuple_api;
73+
LLVMList* list_api;
74+
7075
LLVMUtils(llvm::LLVMContext& context,
7176
llvm::IRBuilder<>* _builder);
7277

@@ -88,6 +93,9 @@ namespace LFortran {
8893
llvm::Value* is_equal_by_value(llvm::Value* left, llvm::Value* right,
8994
llvm::Module& module, ASR::ttype_t* asr_type);
9095

96+
void deepcopy(llvm::Value* src, llvm::Value* dest,
97+
ASR::ttype_t* asr_type, llvm::Module& module);
98+
9199
}; // LLVMUtils
92100

93101
class LLVMList {
@@ -108,7 +116,7 @@ namespace LFortran {
108116
public:
109117

110118
LLVMList(llvm::LLVMContext& context_, LLVMUtils* llvm_utils,
111-
llvm::IRBuilder<>* builder);
119+
llvm::IRBuilder<>* builder);
112120

113121
llvm::Type* get_list_type(llvm::Type* el_type, std::string& type_code,
114122
int32_t type_size);
@@ -124,23 +132,27 @@ namespace LFortran {
124132
llvm::Value* get_pointer_to_current_capacity(llvm::Value* list);
125133

126134
void list_deepcopy(llvm::Value* src, llvm::Value* dest,
127-
std::string& src_type_code,
135+
ASR::List_t* list_type,
128136
llvm::Module& module);
129137

130138
llvm::Value* read_item(llvm::Value* list, llvm::Value* pos,
131139
bool get_pointer=false);
132140

133141
llvm::Value* len(llvm::Value* list);
134142

143+
void write_item(llvm::Value* list, llvm::Value* pos,
144+
llvm::Value* item, ASR::ttype_t* asr_type,
145+
llvm::Module& module);
146+
135147
void write_item(llvm::Value* list, llvm::Value* pos,
136148
llvm::Value* item);
137149

138150
void append(llvm::Value* list, llvm::Value* item,
139-
llvm::Module& module, std::string& type_code);
151+
ASR::ttype_t* asr_type, llvm::Module& module);
140152

141153
void insert_item(llvm::Value* list, llvm::Value* pos,
142-
llvm::Value* item, llvm::Module& module,
143-
std::string& type_code);
154+
llvm::Value* item, ASR::ttype_t* asr_type,
155+
llvm::Module& module);
144156

145157
void remove(llvm::Value* list, llvm::Value* item,
146158
ASR::ttype_t* item_type, llvm::Module& module);
@@ -177,10 +189,10 @@ namespace LFortran {
177189
bool get_pointer=false);
178190

179191
void tuple_deepcopy(llvm::Value* src, llvm::Value* dest,
180-
std::string& type_code);
192+
ASR::Tuple_t* type_code, llvm::Module& module);
181193

182-
static llvm::Value* check_tuple_equality(llvm::Value* t1, llvm::Value* t2,
183-
ASR::Tuple_t* tuple_type, llvm::LLVMContext& context, LLVMUtils* llvm_utils,
194+
llvm::Value* check_tuple_equality(llvm::Value* t1, llvm::Value* t2,
195+
ASR::Tuple_t* tuple_type, llvm::LLVMContext& context,
184196
llvm::IRBuilder<>* builder, llvm::Module& module);
185197
};
186198

0 commit comments

Comments
 (0)