Skip to content

Commit 6bee770

Browse files
committed
wip
1 parent 1bc3a3b commit 6bee770

File tree

6 files changed

+118
-11
lines changed

6 files changed

+118
-11
lines changed

integration_tests/test_list_06.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,48 @@
11
from ltypes import i32, f64
22

3+
def check_mat_and_vec(mat: list[list[f64]], vec: list[f64]):
4+
rows: i32 = len(mat)
5+
cols: i32 = len(vec)
6+
i: i32
7+
j: i32
8+
9+
for i in range(rows):
10+
for j in range(cols):
11+
assert mat[i][j] == float(i + j)
12+
13+
for i in range(cols):
14+
assert vec[i] == 2 * float(i)
15+
316
def test_list_of_lists():
17+
tensor: list[list[list[f64]]] = []
418
mat: list[list[f64]] = []
5-
vec: list[f64] = [1.0, 2.0, 3.0]
19+
vec: list[f64] = []
620
rows: i32 = 10
721
cols: i32 = 5
822
i: i32
923
j: i32
24+
k: i32
25+
26+
for i in range(rows):
27+
for j in range(cols):
28+
vec.append(float(i + j))
29+
mat.append(vec)
30+
vec.clear()
31+
32+
for i in range(cols):
33+
vec.append(2 * float(i))
34+
35+
check_mat_and_vec(mat, vec)
36+
37+
for k in range(rows):
38+
tensor.append(mat)
39+
for i in range(rows):
40+
for j in range(cols):
41+
mat[i][j] += float(1)
1042

11-
mat.append(vec)
12-
vec[0] = -1.0
13-
print(mat[0][0], vec[0])
43+
for k in range(rows):
44+
for i in range(rows):
45+
for j in range(cols):
46+
assert mat[i][j] - tensor[k][i][j] == rows - k
1447

1548
test_list_of_lists()

src/libasr/ASR.asdl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ stmt
206206
| SetRemove(expr a, expr ele)
207207
| ListInsert(expr a, expr pos, expr ele)
208208
| ListRemove(expr a, expr ele)
209+
| ListClear(expr a)
209210
| DictInsert(expr a, expr key, expr value)
210211

211212

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,6 +1282,16 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
12821282
list_api->remove(plist, item, asr_el_type, *module);
12831283
}
12841284

1285+
void visit_ListClear(const ASR::ListClear_t& x) {
1286+
uint64_t ptr_loads_copy = ptr_loads;
1287+
ptr_loads = 0;
1288+
this->visit_expr(*x.m_a);
1289+
llvm::Value* plist = tmp;
1290+
ptr_loads = ptr_loads_copy;
1291+
1292+
list_api->list_clear(plist);
1293+
}
1294+
12851295
void visit_TupleLen(const ASR::TupleLen_t& x) {
12861296
LFORTRAN_ASSERT(x.m_value);
12871297
this->visit_expr(*x.m_value);
@@ -1844,8 +1854,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
18441854
a_kind);
18451855
std::string el_type_code = ASRUtils::get_type_code(asr_list->m_type);
18461856
int32_t type_size = -1;
1847-
if( ASR::is_a<ASR::Character_t>(*asr_list->m_type) ||
1848-
ASR::is_a<ASR::Tuple_t>(*asr_list->m_type) ) {
1857+
if( LLVM::is_llvm_struct(asr_list->m_type) ||
1858+
ASR::is_a<ASR::Character_t>(*asr_list->m_type) ) {
18491859
llvm::DataLayout data_layout(module.get());
18501860
type_size = data_layout.getTypeAllocSize(el_llvm_type);
18511861
} else {
@@ -2226,8 +2236,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
22262236
is_list, m_dims, n_dims,
22272237
a_kind);
22282238
int32_t type_size = -1;
2229-
if( ASR::is_a<ASR::Character_t>(*asr_list->m_type) ||
2230-
ASR::is_a<ASR::Tuple_t>(*asr_list->m_type) ) {
2239+
if( LLVM::is_llvm_struct(asr_list->m_type) ||
2240+
ASR::is_a<ASR::Character_t>(*asr_list->m_type) ) {
22312241
llvm::DataLayout data_layout(module.get());
22322242
type_size = data_layout.getTypeAllocSize(el_llvm_type);
22332243
} else {

src/libasr/codegen/llvm_utils.cpp

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,48 @@ namespace LFortran {
304304
arg_size);
305305
llvm::Type* el_type = std::get<2>(typecode2listtype[src_type_code]);
306306
copy_data = builder->CreateBitCast(copy_data, el_type->getPointerTo());
307-
builder->CreateMemCpy(copy_data, llvm::MaybeAlign(), src_data,
308-
llvm::MaybeAlign(), arg_size);
309-
builder->CreateStore(copy_data, get_pointer_to_list_data(dest));
307+
if( LLVM::is_mutable_llvm_struct(list_type->m_type) ) {
308+
builder->CreateStore(copy_data, get_pointer_to_list_data(dest));
309+
llvm::AllocaInst *pos_ptr = builder->CreateAlloca(llvm::Type::getInt32Ty(context),
310+
nullptr);
311+
LLVM::CreateStore(*builder, llvm::ConstantInt::get(llvm::Type::getInt32Ty(context),
312+
llvm::APInt(32, 0)), pos_ptr);
313+
314+
llvm::BasicBlock *loophead = llvm::BasicBlock::Create(context, "loop.head");
315+
llvm::BasicBlock *loopbody = llvm::BasicBlock::Create(context, "loop.body");
316+
llvm::BasicBlock *loopend = llvm::BasicBlock::Create(context, "loop.end");
317+
318+
// head
319+
llvm_utils->start_new_block(loophead);
320+
{
321+
llvm::Value *cond = builder->CreateICmpSGT(
322+
src_end_point,
323+
LLVM::CreateLoad(*builder, pos_ptr));
324+
builder->CreateCondBr(cond, loopbody, loopend);
325+
}
326+
327+
// body
328+
llvm_utils->start_new_block(loopbody);
329+
{
330+
llvm::Value* pos = LLVM::CreateLoad(*builder, pos_ptr);
331+
llvm::Value* srci = read_item(src, pos, true);
332+
llvm::Value* desti = read_item(dest, pos, true);
333+
llvm_utils->deepcopy(srci, desti, list_type->m_type, module);
334+
llvm::Value* tmp = builder->CreateAdd(
335+
pos,
336+
llvm::ConstantInt::get(context, llvm::APInt(32, 1)));
337+
LLVM::CreateStore(*builder, tmp, pos_ptr);
338+
}
339+
340+
builder->CreateBr(loophead);
341+
342+
// end
343+
llvm_utils->start_new_block(loopend);
344+
} else {
345+
builder->CreateMemCpy(copy_data, llvm::MaybeAlign(), src_data,
346+
llvm::MaybeAlign(), arg_size);
347+
builder->CreateStore(copy_data, get_pointer_to_list_data(dest));
348+
}
310349
}
311350

312351
void LLVMList::write_item(llvm::Value* list, llvm::Value* pos,
@@ -598,6 +637,13 @@ namespace LFortran {
598637
builder->CreateStore(end_point, end_point_ptr);
599638
}
600639

640+
void LLVMList::list_clear(llvm::Value* list) {
641+
llvm::Value* end_point_ptr = get_pointer_to_current_end_point(list);
642+
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::getInt32Ty(context),
643+
llvm::APInt(32, 0));
644+
LLVM::CreateStore(*builder, zero, end_point_ptr);
645+
}
646+
601647

602648
LLVMTuple::LLVMTuple(llvm::LLVMContext& context_,
603649
LLVMUtils* llvm_utils_,

src/libasr/codegen/llvm_utils.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ namespace LFortran {
5555
ASR::is_a<ASR::Derived_t>(*asr_type) ||
5656
ASR::is_a<ASR::Class_t>(*asr_type);
5757
}
58+
static inline bool is_mutable_llvm_struct(ASR::ttype_t* asr_type) {
59+
return ASR::is_a<ASR::List_t>(*asr_type) ||
60+
ASR::is_a<ASR::Derived_t>(*asr_type) ||
61+
ASR::is_a<ASR::Class_t>(*asr_type);
62+
}
5863
}
5964

6065
class LLVMList;
@@ -157,6 +162,8 @@ namespace LFortran {
157162
void remove(llvm::Value* list, llvm::Value* item,
158163
ASR::ttype_t* item_type, llvm::Module& module);
159164

165+
void list_clear(llvm::Value* list);
166+
160167
llvm::Value* find_item_position(llvm::Value* list,
161168
llvm::Value* item, ASR::ttype_t* item_type,
162169
llvm::Module& module);

src/lpython/semantics/python_attribute_eval.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct AttributeHandler {
2121
{"int@bit_length", &eval_int_bit_length},
2222
{"list@append", &eval_list_append},
2323
{"list@remove", &eval_list_remove},
24+
{"list@clear", &eval_list_clear},
2425
{"list@insert", &eval_list_insert},
2526
{"list@pop", &eval_list_pop},
2627
{"set@pop", &eval_set_pop},
@@ -187,6 +188,15 @@ struct AttributeHandler {
187188
return make_ListPop_t(al, loc, s, idx, list_type, nullptr);
188189
}
189190

191+
static ASR::asr_t* eval_list_clear(ASR::expr_t *s, Allocator &al,
192+
const Location &loc, Vec<ASR::expr_t*> &args, diag::Diagnostics &diag) {
193+
if (args.size() != 0) {
194+
throw SemanticError("clear() takes no argument", loc);
195+
}
196+
197+
return make_ListClear_t(al, loc, s);
198+
}
199+
190200
static ASR::asr_t* eval_set_pop(ASR::expr_t *s, Allocator &al, const Location &loc,
191201
Vec<ASR::expr_t*> &args, diag::Diagnostics &/*diag*/) {
192202
if (args.size() != 0) {

0 commit comments

Comments
 (0)