Skip to content

Commit cd89bef

Browse files
authored
Merge pull request #986 from czgdp1807/dict02
Creating dict iterators outside the user loops
2 parents 37ef025 + 8d19070 commit cd89bef

File tree

3 files changed

+33
-12
lines changed

3 files changed

+33
-12
lines changed

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,6 +1756,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
17561756
}
17571757

17581758
void visit_Program(const ASR::Program_t &x) {
1759+
bool is_dict_present_copy = dict_api->is_dict_present;
1760+
dict_api->is_dict_present = false;
17591761
llvm_goto_targets.clear();
17601762
// Generate code for nested subroutines and functions first:
17611763
for (auto &item : x.m_symtab->get_scope()) {
@@ -1784,6 +1786,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
17841786
llvm::Value *ret_val2 = llvm::ConstantInt::get(context,
17851787
llvm::APInt(32, 0));
17861788
builder->CreateRet(ret_val2);
1789+
dict_api->is_dict_present = is_dict_present_copy;
17871790
}
17881791

17891792
/*
@@ -2586,6 +2589,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
25862589
}
25872590

25882591
void visit_Function(const ASR::Function_t &x) {
2592+
bool is_dict_present_copy = dict_api->is_dict_present;
2593+
dict_api->is_dict_present = false;
25892594
llvm_goto_targets.clear();
25902595
instantiate_function(x);
25912596
if (x.m_deftype == ASR::deftypeType::Interface) {
@@ -2596,6 +2601,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
25962601
visit_procedures(x);
25972602
generate_function(x);
25982603
parent_function = nullptr;
2604+
dict_api->is_dict_present = is_dict_present_copy;
25992605
}
26002606

26012607
void instantiate_function(const ASR::Function_t &x){
@@ -3577,6 +3583,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
35773583
}
35783584

35793585
void visit_WhileLoop(const ASR::WhileLoop_t &x) {
3586+
dict_api->set_iterators();
35803587
llvm::BasicBlock *loophead = llvm::BasicBlock::Create(context, "loop.head");
35813588
llvm::BasicBlock *loopbody = llvm::BasicBlock::Create(context, "loop.body");
35823589
llvm::BasicBlock *loopend = llvm::BasicBlock::Create(context, "loop.end");
@@ -3598,6 +3605,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
35983605

35993606
// end
36003607
start_new_block(loopend);
3608+
dict_api->reset_iterators();
36013609
}
36023610

36033611
void visit_Exit(const ASR::Exit_t & /* x */) {

src/libasr/codegen/llvm_utils.cpp

Lines changed: 22 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,6 @@ 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();
658671
}
659672

660673
llvm::Value* LLVMDict::linear_probing_for_read(llvm::Value* dict, llvm::Value* key_hash,
@@ -667,7 +680,6 @@ namespace LFortran {
667680
linear_probing(capacity, key_hash, key, key_list, key_mask, module, key_asr_type);
668681
llvm::Value* pos = LLVM::CreateLoad(*builder, pos_ptr);
669682
llvm::Value* item = llvm_utils->list_api->read_item(value_list, pos, true, false);
670-
reset_iterators();
671683
return item;
672684
}
673685

@@ -729,10 +741,9 @@ namespace LFortran {
729741
new_key_mask = builder->CreateBitCast(new_key_mask, llvm::Type::getInt1PtrTy(context));
730742

731743
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);
744+
if( !are_iterators_set ) {
745+
idx_ptr = builder->CreateAlloca(llvm::Type::getInt32Ty(context), nullptr);
746+
}
736747
LLVM::CreateStore(*builder, llvm::ConstantInt::get(llvm::Type::getInt32Ty(context),
737748
llvm::APInt(32, 0)), idx_ptr);
738749

@@ -790,7 +801,6 @@ namespace LFortran {
790801

791802
// end
792803
llvm_utils->start_new_block(loopend);
793-
reset_iterators();
794804

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

src/libasr/codegen/llvm_utils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ namespace LFortran {
223223
LLVMUtils* llvm_utils;
224224
llvm::IRBuilder<>* builder;
225225
llvm::AllocaInst *pos_ptr, *is_key_matching_var;
226+
llvm::AllocaInst *idx_ptr;
226227
bool are_iterators_set;
227228

228229
std::map<std::pair<std::string, std::string>,
@@ -231,6 +232,8 @@ namespace LFortran {
231232

232233
public:
233234

235+
bool is_dict_present;
236+
234237
LLVMDict(llvm::LLVMContext& context_,
235238
LLVMUtils* llvm_utils,
236239
llvm::IRBuilder<>* builder);

0 commit comments

Comments
 (0)