@@ -3872,34 +3872,38 @@ namespace LCompilers {
3872
3872
}
3873
3873
3874
3874
void LLVMDict::get_elements_list (llvm::Value* dict,
3875
- llvm::Value* elements_list, ASR::ttype_t * el_asr_type, llvm::Module& module ,
3875
+ llvm::Value* elements_list, ASR::ttype_t * key_asr_type,
3876
+ ASR::ttype_t * value_asr_type, llvm::Module& module ,
3876
3877
std::map<std::string, std::map<std::string, int >>& name2memidx,
3877
3878
bool key_or_value) {
3878
3879
3879
3880
/* *
3880
3881
* C++ equivalent:
3881
- *
3882
+ *
3883
+ * // key_or_value = 0 for keys, 1 for values
3884
+ *
3882
3885
* idx = 0;
3883
- *
3886
+ *
3884
3887
* while( capacity > idx ) {
3885
3888
* el = key_or_value_list[idx];
3886
3889
* key_mask_value = key_mask[idx];
3887
- *
3890
+ *
3888
3891
* is_key_skip = key_mask_value == 3; // tombstone
3889
3892
* is_key_set = key_mask_value != 0;
3890
3893
* add_el = is_key_set && !is_key_skip;
3891
3894
* if( add_el ) {
3892
3895
* elements_list.append(el);
3893
3896
* }
3894
- *
3897
+ *
3895
3898
* idx++;
3896
3899
* }
3897
- *
3900
+ *
3898
3901
*/
3899
3902
3900
3903
llvm::Value* capacity = LLVM::CreateLoad (*builder, get_pointer_to_capacity (dict));
3901
3904
llvm::Value* key_mask = LLVM::CreateLoad (*builder, get_pointer_to_keymask (dict));
3902
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;
3903
3907
if ( !are_iterators_set ) {
3904
3908
idx_ptr = builder->CreateAlloca (llvm::Type::getInt32Ty (context), nullptr );
3905
3909
}
@@ -3949,10 +3953,95 @@ namespace LCompilers {
3949
3953
llvm_utils->start_new_block (loopend);
3950
3954
}
3951
3955
3952
- void LLVMDictSeparateChaining::get_elements_list (llvm::Value* /* dict*/ ,
3953
- llvm::Value* /* elements_list*/ , ASR::ttype_t * /* el_asr_type*/ , llvm::Module& /* module*/ ,
3954
- std::map<std::string, std::map<std::string, int >>& /* name2memidx*/ ,
3955
- bool /* key_or_value*/ ) {}
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
+ }
3956
4045
3957
4046
llvm::Value* LLVMList::read_item (llvm::Value* list, llvm::Value* pos,
3958
4047
bool enable_bounds_checking,
0 commit comments