@@ -6709,6 +6709,180 @@ namespace LCompilers {
6709
6709
LLVM::CreateStore (*builder, occupancy, occupancy_ptr);
6710
6710
}
6711
6711
6712
+ llvm::Value* LLVMSetLinearProbing::pop_item (llvm::Value *set, llvm::Module &module ,
6713
+ ASR::ttype_t *el_asr_type) {
6714
+ llvm::Value* current_capacity = LLVM::CreateLoad (*builder, get_pointer_to_capacity (set));
6715
+
6716
+ llvm::Value* occupancy_ptr = get_pointer_to_occupancy (set);
6717
+ llvm::Value* occupancy = LLVM::CreateLoad (*builder, occupancy_ptr);
6718
+ llvm_utils->create_if_else (builder->CreateICmpNE (occupancy, llvm::ConstantInt::get (llvm::Type::getInt32Ty (context), 0 )), [=]() {}, [&]() {
6719
+ std::string message = " The set is empty" ;
6720
+ llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr (" KeyError: %s\n " );
6721
+ llvm::Value *fmt_ptr2 = builder->CreateGlobalStringPtr (message);
6722
+ print_error (context, module , *builder, {fmt_ptr, fmt_ptr2});
6723
+ int exit_code_int = 1 ;
6724
+ llvm::Value *exit_code = llvm::ConstantInt::get (context,
6725
+ llvm::APInt (32 , exit_code_int));
6726
+ exit (context, module , *builder, exit_code);
6727
+ });
6728
+ get_builder0 ();
6729
+ llvm::AllocaInst *pos_ptr = builder0.CreateAlloca (llvm::Type::getInt32Ty (context), nullptr );
6730
+ LLVM::CreateStore (*builder, llvm::ConstantInt::get (llvm::Type::getInt32Ty (context), 0 ), pos_ptr);
6731
+
6732
+ llvm::BasicBlock *loophead = llvm::BasicBlock::Create (context, " loop.head" );
6733
+ llvm::BasicBlock *loopbody = llvm::BasicBlock::Create (context, " loop.body" );
6734
+ llvm::BasicBlock *loopend = llvm::BasicBlock::Create (context, " loop.end" );
6735
+
6736
+ llvm::Value *el_mask = LLVM::CreateLoad (*builder, get_pointer_to_mask (set));
6737
+ llvm::Value *el_list = get_el_list (set);
6738
+
6739
+ // head
6740
+ llvm_utils->start_new_block (loophead);
6741
+ {
6742
+ llvm::Value *cond = builder->CreateICmpSGT (
6743
+ current_capacity,
6744
+ LLVM::CreateLoad (*builder, pos_ptr)
6745
+ );
6746
+ builder->CreateCondBr (cond, loopbody, loopend);
6747
+ }
6748
+
6749
+ // body
6750
+ llvm_utils->start_new_block (loopbody);
6751
+ {
6752
+ llvm::Value* pos = LLVM::CreateLoad (*builder, pos_ptr);
6753
+ llvm::Value* el_mask_value = LLVM::CreateLoad (*builder,
6754
+ llvm_utils->create_ptr_gep (el_mask, pos));
6755
+ llvm::Value* is_el_skip = builder->CreateICmpEQ (el_mask_value,
6756
+ llvm::ConstantInt::get (llvm::Type::getInt8Ty (context), llvm::APInt (8 , 3 )));
6757
+ llvm::Value* is_el_set = builder->CreateICmpNE (el_mask_value,
6758
+ llvm::ConstantInt::get (llvm::Type::getInt8Ty (context), llvm::APInt (8 , 0 )));
6759
+ llvm::Value* is_el = builder->CreateAnd (is_el_set,
6760
+ builder->CreateNot (is_el_skip));
6761
+
6762
+ llvm_utils->create_if_else (is_el, [&]() {
6763
+ llvm::Value* el_mask_i = llvm_utils->create_ptr_gep (el_mask, pos);
6764
+ llvm::Value* tombstone_marker = llvm::ConstantInt::get (llvm::Type::getInt8Ty (context), llvm::APInt (8 , 3 ));
6765
+ LLVM::CreateStore (*builder, tombstone_marker, el_mask_i);
6766
+ occupancy = builder->CreateSub (occupancy, llvm::ConstantInt::get (
6767
+ llvm::Type::getInt32Ty (context), llvm::APInt (32 , 1 )));
6768
+ LLVM::CreateStore (*builder, occupancy, occupancy_ptr);
6769
+ }, [=]() {
6770
+ LLVM::CreateStore (*builder, builder->CreateAdd (pos, llvm::ConstantInt::get (
6771
+ llvm::Type::getInt32Ty (context), llvm::APInt (32 , 1 ))), pos_ptr);
6772
+ });
6773
+ builder->CreateCondBr (is_el, loopend, loophead);
6774
+ }
6775
+
6776
+ // end
6777
+ llvm_utils->start_new_block (loopend);
6778
+
6779
+ llvm::Value* pos = LLVM::CreateLoad (*builder, pos_ptr);
6780
+ llvm::Value *el = llvm_utils->list_api ->read_item (el_list, pos, false , module ,
6781
+ LLVM::is_llvm_struct (el_asr_type));
6782
+ return el;
6783
+ }
6784
+
6785
+ llvm::Value* LLVMSetSeparateChaining::pop_item (llvm::Value *set, llvm::Module &module ,
6786
+ ASR::ttype_t *el_asr_type) {
6787
+ llvm::Value* current_capacity = LLVM::CreateLoad (*builder, get_pointer_to_capacity (set));
6788
+ llvm::Value* occupancy_ptr = get_pointer_to_occupancy (set);
6789
+ llvm::Value* occupancy = LLVM::CreateLoad (*builder, occupancy_ptr);
6790
+ llvm_utils->create_if_else (builder->CreateICmpNE (occupancy, llvm::ConstantInt::get (llvm::Type::getInt32Ty (context), 0 )), []() {}, [&]() {
6791
+ std::string message = " The set is empty" ;
6792
+ llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr (" KeyError: %s\n " );
6793
+ llvm::Value *fmt_ptr2 = builder->CreateGlobalStringPtr (message);
6794
+ print_error (context, module , *builder, {fmt_ptr, fmt_ptr2});
6795
+ int exit_code_int = 1 ;
6796
+ llvm::Value *exit_code = llvm::ConstantInt::get (context,
6797
+ llvm::APInt (32 , exit_code_int));
6798
+ exit (context, module , *builder, exit_code);
6799
+ });
6800
+
6801
+ get_builder0 ();
6802
+ llvm::AllocaInst* chain_itr = builder0.CreateAlloca (llvm::Type::getInt8PtrTy (context), nullptr );
6803
+ llvm::AllocaInst* found_ptr = builder0.CreateAlloca (llvm::Type::getInt8PtrTy (context), nullptr );
6804
+ llvm::AllocaInst* pos = builder0.CreateAlloca (llvm::Type::getInt32Ty (context), nullptr );
6805
+ LLVM::CreateStore (*builder,
6806
+ llvm::ConstantInt::get (llvm::Type::getInt32Ty (context), 0 ), pos);
6807
+
6808
+ llvm::BasicBlock *loophead = llvm::BasicBlock::Create (context, " loop.head" );
6809
+ llvm::BasicBlock *loopbody = llvm::BasicBlock::Create (context, " loop.body" );
6810
+ llvm::BasicBlock *loopend = llvm::BasicBlock::Create (context, " loop.end" );
6811
+
6812
+ llvm::Value* elems = LLVM::CreateLoad (*builder, get_pointer_to_elems (set));
6813
+ llvm::Value* el_mask = LLVM::CreateLoad (*builder, get_pointer_to_mask (set));
6814
+
6815
+ // head
6816
+ llvm_utils->start_new_block (loophead);
6817
+ {
6818
+ llvm::Value *cond = builder->CreateICmpSGT (
6819
+ current_capacity,
6820
+ LLVM::CreateLoad (*builder, pos_ptr)
6821
+ );
6822
+ builder->CreateCondBr (cond, loopbody, loopend);
6823
+ }
6824
+
6825
+ // body
6826
+ llvm_utils->start_new_block (loopbody);
6827
+ {
6828
+ llvm::Value *el_mask_value = LLVM::CreateLoad (*builder,
6829
+ llvm_utils->create_ptr_gep (el_mask, LLVM::CreateLoad (*builder, pos)));
6830
+ llvm::Value* el_linked_list = llvm_utils->create_ptr_gep (elems, LLVM::CreateLoad (*builder, pos));
6831
+
6832
+ llvm::Value *is_el = builder->CreateICmpEQ (el_mask_value,
6833
+ llvm::ConstantInt::get (llvm::Type::getInt8Ty (context), llvm::APInt (8 , 1 )));
6834
+ llvm_utils->create_if_else (is_el, [&]() {
6835
+ llvm::Value* el_ll_i8 = builder->CreateBitCast (el_linked_list, llvm::Type::getInt8PtrTy (context));
6836
+ LLVM::CreateStore (*builder, el_ll_i8, chain_itr);
6837
+ llvm::Value* el_struct_i8 = LLVM::CreateLoad (*builder, chain_itr);
6838
+ llvm::Type* el_struct_type = typecode2elstruct[ASRUtils::get_type_code (el_asr_type)];
6839
+ llvm::Value* el_struct = builder->CreateBitCast (el_struct_i8, el_struct_type->getPointerTo ());
6840
+ llvm::Value* next_el_struct = LLVM::CreateLoad (*builder, llvm_utils->create_gep (el_struct, 1 ));
6841
+ llvm::Value *cond = builder->CreateICmpNE (
6842
+ next_el_struct,
6843
+ llvm::ConstantPointerNull::get (llvm::Type::getInt8PtrTy (context))
6844
+ );
6845
+
6846
+ llvm_utils->create_if_else (cond, [&](){
6847
+ llvm::Value *found = LLVM::CreateLoad (*builder, next_el_struct);
6848
+ llvm::Value *prev = LLVM::CreateLoad (*builder, chain_itr);
6849
+ found = builder->CreateBitCast (found, el_struct_type->getPointerTo ());
6850
+ llvm::Value* found_next = LLVM::CreateLoad (*builder, llvm_utils->create_gep (found, 1 ));
6851
+ prev = builder->CreateBitCast (prev, el_struct_type->getPointerTo ());
6852
+ LLVM::CreateStore (*builder, found_next, llvm_utils->create_gep (prev, 1 ));
6853
+ LLVM::CreateStore (*builder, found, found_ptr);
6854
+ }, [&](){
6855
+ llvm::Value *found = LLVM::CreateLoad (*builder, chain_itr);
6856
+ llvm::Type* el_struct_type = typecode2elstruct[ASRUtils::get_type_code (el_asr_type)];
6857
+ found = builder->CreateBitCast (found, el_struct_type->getPointerTo ());
6858
+ LLVM::CreateStore (*builder, found, found_ptr);
6859
+ LLVM::CreateStore (
6860
+ *builder,
6861
+ llvm::ConstantInt::get (llvm::Type::getInt8Ty (context), llvm::APInt (8 , 0 )),
6862
+ llvm_utils->create_ptr_gep (el_mask, LLVM::CreateLoad (*builder, pos))
6863
+ );
6864
+ llvm::Value* num_buckets_filled_ptr = get_pointer_to_number_of_filled_buckets (set);
6865
+ llvm::Value* num_buckets_filled = LLVM::CreateLoad (*builder, num_buckets_filled_ptr);
6866
+ num_buckets_filled = builder->CreateSub (num_buckets_filled, llvm::ConstantInt::get (
6867
+ llvm::Type::getInt32Ty (context), llvm::APInt (32 , 1 )));
6868
+ LLVM::CreateStore (*builder, num_buckets_filled, num_buckets_filled_ptr);
6869
+ });
6870
+ }, [&]() {
6871
+ });
6872
+ LLVM::CreateStore (*builder, builder->CreateAdd (pos, llvm::ConstantInt::get (
6873
+ llvm::Type::getInt32Ty (context), llvm::APInt (32 , 1 ))), pos_ptr);
6874
+ builder->CreateCondBr (is_el, loopend, loophead);
6875
+ }
6876
+
6877
+ llvm::Value *el = llvm_utils->create_ptr_gep (LLVM::CreateLoad (*builder, pos_ptr), 0 );
6878
+
6879
+ if (LLVM::is_llvm_struct (el_asr_type)) {
6880
+ return el;
6881
+ } else {
6882
+ return LLVM::CreateLoad (*builder, el);
6883
+ }
6884
+ }
6885
+
6712
6886
void LLVMSetLinearProbing::set_deepcopy (
6713
6887
llvm::Value* src, llvm::Value* dest,
6714
6888
ASR::Set_t* set_type, llvm::Module* module ,
0 commit comments