@@ -1708,6 +1708,12 @@ namespace LCompilers {
17081708 list_api->list_deepcopy (src, dest, list_type, module , name2memidx);
17091709 break ;
17101710 }
1711+ case ASR::ttypeType::Dict: {
1712+ ASR::Dict_t* dict_type = ASR::down_cast<ASR::Dict_t>(asr_type);
1713+ // set dict api here?
1714+ dict_api->dict_deepcopy (src, dest, dict_type, module , name2memidx);
1715+ break ;
1716+ }
17111717 case ASR::ttypeType::Struct: {
17121718 ASR::Struct_t* struct_t = ASR::down_cast<ASR::Struct_t>(asr_type);
17131719 ASR::StructType_t* struct_type_t = ASR::down_cast<ASR::StructType_t>(
@@ -3865,6 +3871,178 @@ namespace LCompilers {
38653871 return LLVM::CreateLoad (*builder, value_ptr);
38663872 }
38673873
3874+ void LLVMDict::get_elements_list (llvm::Value* dict,
3875+ llvm::Value* elements_list, ASR::ttype_t * key_asr_type,
3876+ ASR::ttype_t * value_asr_type, llvm::Module& module ,
3877+ std::map<std::string, std::map<std::string, int >>& name2memidx,
3878+ bool key_or_value) {
3879+
3880+ /* *
3881+ * C++ equivalent:
3882+ *
3883+ * // key_or_value = 0 for keys, 1 for values
3884+ *
3885+ * idx = 0;
3886+ *
3887+ * while( capacity > idx ) {
3888+ * el = key_or_value_list[idx];
3889+ * key_mask_value = key_mask[idx];
3890+ *
3891+ * is_key_skip = key_mask_value == 3; // tombstone
3892+ * is_key_set = key_mask_value != 0;
3893+ * add_el = is_key_set && !is_key_skip;
3894+ * if( add_el ) {
3895+ * elements_list.append(el);
3896+ * }
3897+ *
3898+ * idx++;
3899+ * }
3900+ *
3901+ */
3902+
3903+ llvm::Value* capacity = LLVM::CreateLoad (*builder, get_pointer_to_capacity (dict));
3904+ llvm::Value* key_mask = LLVM::CreateLoad (*builder, get_pointer_to_keymask (dict));
3905+ llvm::Value* el_list = key_or_value == 0 ? get_key_list (dict) : get_value_list (dict);
3906+ ASR::ttype_t * el_asr_type = key_or_value == 0 ? key_asr_type : value_asr_type;
3907+ if ( !are_iterators_set ) {
3908+ idx_ptr = builder->CreateAlloca (llvm::Type::getInt32Ty (context), nullptr );
3909+ }
3910+ LLVM::CreateStore (*builder, llvm::ConstantInt::get (llvm::Type::getInt32Ty (context),
3911+ llvm::APInt (32 , 0 )), idx_ptr);
3912+
3913+ llvm::BasicBlock *loophead = llvm::BasicBlock::Create (context, " loop.head" );
3914+ llvm::BasicBlock *loopbody = llvm::BasicBlock::Create (context, " loop.body" );
3915+ llvm::BasicBlock *loopend = llvm::BasicBlock::Create (context, " loop.end" );
3916+
3917+ // head
3918+ llvm_utils->start_new_block (loophead);
3919+ {
3920+ llvm::Value *cond = builder->CreateICmpSGT (capacity, LLVM::CreateLoad (*builder, idx_ptr));
3921+ builder->CreateCondBr (cond, loopbody, loopend);
3922+ }
3923+
3924+ // body
3925+ llvm_utils->start_new_block (loopbody);
3926+ {
3927+ llvm::Value* idx = LLVM::CreateLoad (*builder, idx_ptr);
3928+ llvm::Value* key_mask_value = LLVM::CreateLoad (*builder,
3929+ llvm_utils->create_ptr_gep (key_mask, idx));
3930+ llvm::Value* is_key_skip = builder->CreateICmpEQ (key_mask_value,
3931+ llvm::ConstantInt::get (llvm::Type::getInt8Ty (context), llvm::APInt (8 , 3 )));
3932+ llvm::Value* is_key_set = builder->CreateICmpNE (key_mask_value,
3933+ llvm::ConstantInt::get (llvm::Type::getInt8Ty (context), llvm::APInt (8 , 0 )));
3934+
3935+ llvm::Value* add_el = builder->CreateAnd (is_key_set,
3936+ builder->CreateNot (is_key_skip));
3937+ llvm_utils->create_if_else (add_el, [&]() {
3938+ llvm::Value* el = llvm_utils->list_api ->read_item (el_list, idx,
3939+ false , module , LLVM::is_llvm_struct (el_asr_type));
3940+ llvm_utils->list_api ->append (elements_list, el,
3941+ el_asr_type, &module , name2memidx);
3942+ }, [=]() {
3943+ });
3944+
3945+ idx = builder->CreateAdd (idx, llvm::ConstantInt::get (
3946+ llvm::Type::getInt32Ty (context), llvm::APInt (32 , 1 )));
3947+ LLVM::CreateStore (*builder, idx, idx_ptr);
3948+ }
3949+
3950+ builder->CreateBr (loophead);
3951+
3952+ // end
3953+ llvm_utils->start_new_block (loopend);
3954+ }
3955+
3956+ void LLVMDictSeparateChaining::get_elements_list (llvm::Value* dict,
3957+ llvm::Value* elements_list, ASR::ttype_t * key_asr_type,
3958+ ASR::ttype_t * value_asr_type, llvm::Module& module ,
3959+ std::map<std::string, std::map<std::string, int >>& name2memidx,
3960+ bool key_or_value) {
3961+ if ( !are_iterators_set ) {
3962+ idx_ptr = builder->CreateAlloca (llvm::Type::getInt32Ty (context), nullptr );
3963+ chain_itr = builder->CreateAlloca (llvm::Type::getInt8PtrTy (context), nullptr );
3964+ }
3965+ LLVM::CreateStore (*builder, llvm::ConstantInt::get (llvm::Type::getInt32Ty (context),
3966+ llvm::APInt (32 , 0 )), idx_ptr);
3967+
3968+ llvm::Value* capacity = LLVM::CreateLoad (*builder, get_pointer_to_capacity (dict));
3969+ llvm::Value* key_mask = LLVM::CreateLoad (*builder, get_pointer_to_keymask (dict));
3970+ llvm::Value* key_value_pairs = LLVM::CreateLoad (*builder, get_pointer_to_key_value_pairs (dict));
3971+ llvm::Type* kv_pair_type = get_key_value_pair_type (key_asr_type, value_asr_type);
3972+ ASR::ttype_t * el_asr_type = key_or_value == 0 ? key_asr_type : value_asr_type;
3973+ llvm::BasicBlock *loophead = llvm::BasicBlock::Create (context, " loop.head" );
3974+ llvm::BasicBlock *loopbody = llvm::BasicBlock::Create (context, " loop.body" );
3975+ llvm::BasicBlock *loopend = llvm::BasicBlock::Create (context, " loop.end" );
3976+
3977+ // head
3978+ llvm_utils->start_new_block (loophead);
3979+ {
3980+ llvm::Value *cond = builder->CreateICmpSGT (
3981+ capacity,
3982+ LLVM::CreateLoad (*builder, idx_ptr));
3983+ builder->CreateCondBr (cond, loopbody, loopend);
3984+ }
3985+
3986+ // body
3987+ llvm_utils->start_new_block (loopbody);
3988+ {
3989+ llvm::Value* idx = LLVM::CreateLoad (*builder, idx_ptr);
3990+ llvm::Value* key_mask_value = LLVM::CreateLoad (*builder,
3991+ llvm_utils->create_ptr_gep (key_mask, idx));
3992+ llvm::Value* is_key_set = builder->CreateICmpEQ (key_mask_value,
3993+ llvm::ConstantInt::get (llvm::Type::getInt8Ty (context), llvm::APInt (8 , 1 )));
3994+
3995+ llvm_utils->create_if_else (is_key_set, [&]() {
3996+ llvm::Value* dict_i = llvm_utils->create_ptr_gep (key_value_pairs, idx);
3997+ llvm::Value* kv_ll_i8 = builder->CreateBitCast (dict_i, llvm::Type::getInt8PtrTy (context));
3998+ LLVM::CreateStore (*builder, kv_ll_i8, chain_itr);
3999+
4000+ llvm::BasicBlock *loop2head = llvm::BasicBlock::Create (context, " loop2.head" );
4001+ llvm::BasicBlock *loop2body = llvm::BasicBlock::Create (context, " loop2.body" );
4002+ llvm::BasicBlock *loop2end = llvm::BasicBlock::Create (context, " loop2.end" );
4003+
4004+ // head
4005+ llvm_utils->start_new_block (loop2head);
4006+ {
4007+ llvm::Value *cond = builder->CreateICmpNE (
4008+ LLVM::CreateLoad (*builder, chain_itr),
4009+ llvm::ConstantPointerNull::get (llvm::Type::getInt8PtrTy (context))
4010+ );
4011+ builder->CreateCondBr (cond, loop2body, loop2end);
4012+ }
4013+
4014+ // body
4015+ llvm_utils->start_new_block (loop2body);
4016+ {
4017+ llvm::Value* kv_struct_i8 = LLVM::CreateLoad (*builder, chain_itr);
4018+ llvm::Value* kv_struct = builder->CreateBitCast (kv_struct_i8, kv_pair_type->getPointerTo ());
4019+ llvm::Value* kv_el = llvm_utils->create_gep (kv_struct, key_or_value);
4020+ if ( !LLVM::is_llvm_struct (el_asr_type) ) {
4021+ kv_el = LLVM::CreateLoad (*builder, kv_el);
4022+ }
4023+ llvm_utils->list_api ->append (elements_list, kv_el,
4024+ el_asr_type, &module , name2memidx);
4025+ llvm::Value* next_kv_struct = LLVM::CreateLoad (*builder, llvm_utils->create_gep (kv_struct, 2 ));
4026+ LLVM::CreateStore (*builder, next_kv_struct, chain_itr);
4027+ }
4028+
4029+ builder->CreateBr (loop2head);
4030+
4031+ // end
4032+ llvm_utils->start_new_block (loop2end);
4033+ }, [=]() {
4034+ });
4035+ llvm::Value* tmp = builder->CreateAdd (idx,
4036+ llvm::ConstantInt::get (context, llvm::APInt (32 , 1 )));
4037+ LLVM::CreateStore (*builder, tmp, idx_ptr);
4038+ }
4039+
4040+ builder->CreateBr (loophead);
4041+
4042+ // end
4043+ llvm_utils->start_new_block (loopend);
4044+ }
4045+
38684046 llvm::Value* LLVMList::read_item (llvm::Value* list, llvm::Value* pos,
38694047 bool enable_bounds_checking,
38704048 llvm::Module& module , bool get_pointer) {
0 commit comments