Skip to content

Commit c5880e7

Browse files
committed
Create iterators if not already created
1 parent 06e4289 commit c5880e7

File tree

1 file changed

+28
-12
lines changed

1 file changed

+28
-12
lines changed

src/libasr/codegen/llvm_utils.cpp

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,8 @@ namespace LFortran {
282282
llvm_utils(std::move(llvm_utils_)),
283283
builder(std::move(builder_)),
284284
pos_ptr(nullptr), is_key_matching_var(nullptr),
285-
are_iterators_set(false) {
285+
idx_ptr(nullptr), are_iterators_set(false),
286+
is_dict_present(false) {
286287
}
287288

288289
llvm::Type* LLVMList::get_list_type(llvm::Type* el_type, std::string& type_code,
@@ -301,6 +302,7 @@ namespace LFortran {
301302
llvm::Type* LLVMDict::get_dict_type(std::string key_type_code, std::string value_type_code,
302303
int32_t key_type_size, int32_t value_type_size,
303304
llvm::Type* key_type, llvm::Type* value_type) {
305+
is_dict_present = true;
304306
std::pair<std::string, std::string> llvm_key = std::make_pair(key_type_code, value_type_code);
305307
if( typecode2dicttype.find(llvm_key) != typecode2dicttype.end() ) {
306308
return std::get<0>(typecode2dicttype[llvm_key]);
@@ -554,25 +556,37 @@ namespace LFortran {
554556
}
555557

556558
void LLVMDict::set_iterators() {
557-
if( are_iterators_set ) {
559+
if( are_iterators_set || !is_dict_present ) {
558560
return ;
559561
}
560-
pos_ptr = builder->CreateAlloca(llvm::Type::getInt32Ty(context), nullptr);
561-
is_key_matching_var = builder->CreateAlloca(llvm::Type::getInt1Ty(context), nullptr);
562+
pos_ptr = builder->CreateAlloca(llvm::Type::getInt32Ty(context), nullptr, "pos_ptr");
563+
LLVM::CreateStore(*builder, llvm::ConstantInt::get(llvm::Type::getInt32Ty(context),
564+
llvm::APInt(32, 0)), pos_ptr);
565+
is_key_matching_var = builder->CreateAlloca(llvm::Type::getInt1Ty(context), nullptr,
566+
"is_key_matching_var");
567+
LLVM::CreateStore(*builder, llvm::ConstantInt::get(llvm::Type::getInt1Ty(context),
568+
llvm::APInt(1, 0)), is_key_matching_var);
569+
idx_ptr = builder->CreateAlloca(llvm::Type::getInt32Ty(context), nullptr, "idx_ptr");
570+
LLVM::CreateStore(*builder, llvm::ConstantInt::get(llvm::Type::getInt32Ty(context),
571+
llvm::APInt(32, 0)), idx_ptr);
562572
are_iterators_set = true;
563573
}
564574

565575
void LLVMDict::reset_iterators() {
566576
pos_ptr = nullptr;
567577
is_key_matching_var = nullptr;
578+
idx_ptr = nullptr;
568579
are_iterators_set = false;
569580
}
570581

571582
void LLVMDict::linear_probing(llvm::Value* capacity, llvm::Value* key_hash,
572583
llvm::Value* key, llvm::Value* key_list,
573584
llvm::Value* key_mask, llvm::Module& module,
574585
ASR::ttype_t* key_asr_type) {
575-
set_iterators();
586+
if( !are_iterators_set ) {
587+
pos_ptr = builder->CreateAlloca(llvm::Type::getInt32Ty(context), nullptr);
588+
is_key_matching_var = builder->CreateAlloca(llvm::Type::getInt1Ty(context), nullptr);
589+
}
576590
LLVM::CreateStore(*builder, key_hash, pos_ptr);
577591

578592
llvm::BasicBlock *loophead = llvm::BasicBlock::Create(context, "loop.head");
@@ -654,7 +668,9 @@ namespace LFortran {
654668
LLVM::CreateStore(*builder,
655669
llvm::ConstantInt::get(llvm::Type::getInt1Ty(context), llvm::APInt(1, 1)),
656670
llvm_utils->create_ptr_gep(key_mask, pos));
657-
reset_iterators();
671+
if( !are_iterators_set ) {
672+
pos_ptr = nullptr;
673+
}
658674
}
659675

660676
llvm::Value* LLVMDict::linear_probing_for_read(llvm::Value* dict, llvm::Value* key_hash,
@@ -667,7 +683,9 @@ namespace LFortran {
667683
linear_probing(capacity, key_hash, key, key_list, key_mask, module, key_asr_type);
668684
llvm::Value* pos = LLVM::CreateLoad(*builder, pos_ptr);
669685
llvm::Value* item = llvm_utils->list_api->read_item(value_list, pos, true, false);
670-
reset_iterators();
686+
if( !are_iterators_set ) {
687+
pos_ptr = nullptr;
688+
}
671689
return item;
672690
}
673691

@@ -729,10 +747,9 @@ namespace LFortran {
729747
new_key_mask = builder->CreateBitCast(new_key_mask, llvm::Type::getInt1PtrTy(context));
730748

731749
llvm::Value* current_capacity = LLVM::CreateLoad(*builder, get_pointer_to_capacity(dict));
732-
// TODO: Should be created outside the user loop and not here.
733-
// LLVMDict should treat them as data members and create them
734-
// only if they are NULL
735-
llvm::Value* idx_ptr = builder->CreateAlloca(llvm::Type::getInt32Ty(context), nullptr);
750+
if( !are_iterators_set ) {
751+
idx_ptr = builder->CreateAlloca(llvm::Type::getInt32Ty(context), nullptr);
752+
}
736753
LLVM::CreateStore(*builder, llvm::ConstantInt::get(llvm::Type::getInt32Ty(context),
737754
llvm::APInt(32, 0)), idx_ptr);
738755

@@ -790,7 +807,6 @@ namespace LFortran {
790807

791808
// end
792809
llvm_utils->start_new_block(loopend);
793-
reset_iterators();
794810

795811
// TODO: Free key_list, value_list and key_mask
796812
llvm_utils->list_api->free_data(key_list, *module);

0 commit comments

Comments
 (0)