@@ -3177,7 +3177,7 @@ namespace LCompilers {
31773177 llvm::Value* LLVMDict::resolve_collision_for_read_with_bound_check (
31783178 llvm::Value* dict, llvm::Value* key_hash,
31793179 llvm::Value* key, llvm::Module& module ,
3180- ASR::ttype_t * key_asr_type, ASR::ttype_t * /* value_asr_type*/ ) {
3180+ ASR::ttype_t * key_asr_type, ASR::ttype_t * /* value_asr_type*/ , bool check_if_exists ) {
31813181 llvm::Value* key_list = get_key_list (dict);
31823182 llvm::Value* value_list = get_value_list (dict);
31833183 llvm::Value* key_mask = LLVM::CreateLoad (*builder, get_pointer_to_keymask (dict));
@@ -3187,6 +3187,8 @@ namespace LCompilers {
31873187 llvm::Value* is_key_matching = llvm_utils->is_equal_by_value (key,
31883188 llvm_utils->list_api ->read_item (key_list, pos, false , module ,
31893189 LLVM::is_llvm_struct (key_asr_type)), module , key_asr_type);
3190+ if (check_if_exists)
3191+ return is_key_matching;
31903192
31913193 llvm_utils->create_if_else (is_key_matching, [&]() {
31923194 }, [&]() {
@@ -3245,7 +3247,7 @@ namespace LCompilers {
32453247 llvm::Value* LLVMDictOptimizedLinearProbing::resolve_collision_for_read_with_bound_check (
32463248 llvm::Value* dict, llvm::Value* key_hash,
32473249 llvm::Value* key, llvm::Module& module ,
3248- ASR::ttype_t * key_asr_type, ASR::ttype_t * /* value_asr_type*/ ) {
3250+ ASR::ttype_t * key_asr_type, ASR::ttype_t * /* value_asr_type*/ , bool check_if_exists ) {
32493251
32503252 /* *
32513253 * C++ equivalent:
@@ -3287,6 +3289,9 @@ namespace LCompilers {
32873289 llvm_utils->create_ptr_gep (key_mask, key_hash));
32883290 llvm::Value* is_prob_not_neeeded = builder->CreateICmpEQ (key_mask_value,
32893291 llvm::ConstantInt::get (llvm::Type::getInt8Ty (context), llvm::APInt (8 , 1 )));
3292+ llvm::AllocaInst *flag_ptr = builder->CreateAlloca (llvm::Type::getInt1Ty (context), nullptr );
3293+ LLVM::CreateStore (*builder, llvm::ConstantInt::get (llvm::Type::getInt1Ty (context), 0 ), flag_ptr);
3294+ LLVM::CreateStore (*builder, llvm::ConstantInt::get (llvm::Type::getInt32Ty (context), 0 ), pos_ptr);
32903295 builder->CreateCondBr (is_prob_not_neeeded, thenBB, elseBB);
32913296 builder->SetInsertPoint (thenBB);
32923297 {
@@ -3304,6 +3309,9 @@ namespace LCompilers {
33043309 llvm_utils->create_if_else (is_key_matching, [=]() {
33053310 LLVM::CreateStore (*builder, key_hash, pos_ptr);
33063311 }, [&]() {
3312+ if (check_if_exists) {
3313+ LLVM::CreateStore (*builder, llvm::ConstantInt::get (llvm::Type::getInt1Ty (context), 1 ), flag_ptr);
3314+ } else {
33073315 std::string message = " The dict does not contain the specified key" ;
33083316 llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr (" KeyError: %s\n " );
33093317 llvm::Value *fmt_ptr2 = builder->CreateGlobalStringPtr (message);
@@ -3312,7 +3320,7 @@ namespace LCompilers {
33123320 llvm::Value *exit_code = llvm::ConstantInt::get (context,
33133321 llvm::APInt (32 , exit_code_int));
33143322 exit (context, module , *builder, exit_code);
3315- });
3323+ }} );
33163324 }
33173325 builder->CreateBr (mergeBB);
33183326 llvm_utils->start_new_block (elseBB);
@@ -3321,11 +3329,24 @@ namespace LCompilers {
33213329 module , key_asr_type, true );
33223330 }
33233331 llvm_utils->start_new_block (mergeBB);
3324- llvm::Value* pos = LLVM::CreateLoad (*builder, pos_ptr);
3325- // Check if the actual key is present or not
3326- llvm::Value* is_key_matching = llvm_utils->is_equal_by_value (key,
3332+ llvm::Value *flag = LLVM::CreateLoad (*builder, flag_ptr);
3333+ llvm::Value *pos = LLVM::CreateLoad (*builder, pos_ptr);
3334+ llvm::AllocaInst *is_key_matching_ptr = builder->CreateAlloca (llvm::Type::getInt1Ty (context), nullptr );
3335+
3336+ llvm_utils->create_if_else (flag, [&](){
3337+ LLVM::CreateStore (*builder, llvm::ConstantInt::get (llvm::Type::getInt1Ty (context), 0 ), is_key_matching_ptr);
3338+ }, [&](){
3339+ // Check if the actual element is present or not
3340+ LLVM::CreateStore (*builder, llvm_utils->is_equal_by_value (key,
33273341 llvm_utils->list_api ->read_item (key_list, pos, false , module ,
3328- LLVM::is_llvm_struct (key_asr_type)), module , key_asr_type);
3342+ LLVM::is_llvm_struct (key_asr_type)), module , key_asr_type), is_key_matching_ptr);
3343+ });
3344+
3345+ llvm::Value *is_key_matching = LLVM::CreateLoad (*builder, is_key_matching_ptr);
3346+
3347+ if (check_if_exists) {
3348+ return is_key_matching;
3349+ }
33293350
33303351 llvm_utils->create_if_else (is_key_matching, [&]() {
33313352 }, [&]() {
@@ -3471,7 +3492,7 @@ namespace LCompilers {
34713492 llvm::Value* LLVMDictSeparateChaining::resolve_collision_for_read_with_bound_check (
34723493 llvm::Value* dict, llvm::Value* key_hash,
34733494 llvm::Value* key, llvm::Module& module ,
3474- ASR::ttype_t * key_asr_type, ASR::ttype_t * value_asr_type) {
3495+ ASR::ttype_t * key_asr_type, ASR::ttype_t * value_asr_type, bool check_if_exists ) {
34753496 /* *
34763497 * C++ equivalent:
34773498 *
@@ -3506,6 +3527,10 @@ namespace LCompilers {
35063527 llvm::ConstantPointerNull::get (llvm::Type::getInt8PtrTy (context)))
35073528 );
35083529
3530+ if (check_if_exists) {
3531+ return does_kv_exists;
3532+ }
3533+
35093534 llvm_utils->create_if_else (does_kv_exists, [&]() {
35103535 llvm::Value* kv_struct_i8 = LLVM::CreateLoad (*builder, chain_itr);
35113536 llvm::Value* kv_struct = builder->CreateBitCast (kv_struct_i8, kv_struct_type->getPointerTo ());
@@ -4358,6 +4383,7 @@ namespace LCompilers {
43584383 // end
43594384 llvm_utils->start_new_block (loopend);
43604385 }
4386+
43614387
43624388 llvm::Value* LLVMList::read_item (llvm::Value* list, llvm::Value* pos,
43634389 bool enable_bounds_checking,
@@ -6393,9 +6419,9 @@ namespace LCompilers {
63936419 el_asr_type, name2memidx);
63946420 }
63956421
6396- void LLVMSetLinearProbing::resolve_collision_for_read_with_bound_check (
6422+ llvm::Value* LLVMSetLinearProbing::resolve_collision_for_read_with_bound_check (
63976423 llvm::Value* set, llvm::Value* el_hash, llvm::Value* el,
6398- llvm::Module& module , ASR::ttype_t * el_asr_type, bool throw_key_error) {
6424+ llvm::Module& module , ASR::ttype_t * el_asr_type, bool throw_key_error, bool check_if_exists ) {
63996425
64006426 /* *
64016427 * C++ equivalent:
@@ -6423,18 +6449,22 @@ namespace LCompilers {
64236449 */
64246450
64256451 get_builder0 ()
6452+ pos_ptr = builder0.CreateAlloca (llvm::Type::getInt32Ty (context), nullptr );
64266453 llvm::Value* el_list = get_el_list (set);
64276454 llvm::Value* el_mask = LLVM::CreateLoad (*builder, get_pointer_to_mask (set));
64286455 llvm::Value* capacity = LLVM::CreateLoad (*builder, get_pointer_to_capacity (set));
6429- pos_ptr = builder0.CreateAlloca (llvm::Type::getInt32Ty (context), nullptr );
64306456 llvm::Function *fn = builder->GetInsertBlock ()->getParent ();
6431- llvm::BasicBlock *thenBB = llvm::BasicBlock::Create (context, " then" , fn);
6432- llvm::BasicBlock *elseBB = llvm::BasicBlock::Create (context, " else" );
6433- llvm::BasicBlock *mergeBB = llvm::BasicBlock::Create (context, " ifcont" );
6457+ std::string s = check_if_exists ? " qq" : " pp" ;
6458+ llvm::BasicBlock *thenBB = llvm::BasicBlock::Create (context, " then" +s, fn);
6459+ llvm::BasicBlock *elseBB = llvm::BasicBlock::Create (context, " else" +s);
6460+ llvm::BasicBlock *mergeBB = llvm::BasicBlock::Create (context, " ifcont" +s);
64346461 llvm::Value* el_mask_value = LLVM::CreateLoad (*builder,
64356462 llvm_utils->create_ptr_gep (el_mask, el_hash));
64366463 llvm::Value* is_prob_not_needed = builder->CreateICmpEQ (el_mask_value,
64376464 llvm::ConstantInt::get (llvm::Type::getInt8Ty (context), llvm::APInt (8 , 1 )));
6465+ llvm::AllocaInst *flag_ptr = builder->CreateAlloca (llvm::Type::getInt1Ty (context), nullptr );
6466+ LLVM::CreateStore (*builder, llvm::ConstantInt::get (llvm::Type::getInt32Ty (context), 0 ), pos_ptr);
6467+ LLVM::CreateStore (*builder, llvm::ConstantInt::get (llvm::Type::getInt1Ty (context), 0 ), flag_ptr);
64386468 builder->CreateCondBr (is_prob_not_needed, thenBB, elseBB);
64396469 builder->SetInsertPoint (thenBB);
64406470 {
@@ -6447,6 +6477,9 @@ namespace LCompilers {
64476477 llvm_utils->create_if_else (is_el_matching, [=]() {
64486478 LLVM::CreateStore (*builder, el_hash, pos_ptr);
64496479 }, [&]() {
6480+ if (check_if_exists) {
6481+ LLVM::CreateStore (*builder, llvm::ConstantInt::get (llvm::Type::getInt1Ty (context), 1 ), flag_ptr);
6482+ } else {
64506483 if (throw_key_error) {
64516484 std::string message = " The set does not contain the specified element" ;
64526485 llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr (" KeyError: %s\n " );
@@ -6457,7 +6490,7 @@ namespace LCompilers {
64576490 llvm::APInt (32 , exit_code_int));
64586491 exit (context, module , *builder, exit_code);
64596492 }
6460- });
6493+ }} );
64616494 }
64626495 builder->CreateBr (mergeBB);
64636496 llvm_utils->start_new_block (elseBB);
@@ -6466,11 +6499,25 @@ namespace LCompilers {
64666499 module , el_asr_type, true );
64676500 }
64686501 llvm_utils->start_new_block (mergeBB);
6469- llvm::Value* pos = LLVM::CreateLoad (*builder, pos_ptr);
6502+ llvm::Value *flag = LLVM::CreateLoad (*builder, flag_ptr);
6503+ llvm::AllocaInst *is_el_matching_ptr = builder->CreateAlloca (llvm::Type::getInt1Ty (context), nullptr );
6504+
6505+ llvm_utils->create_if_else (flag, [&](){
6506+ LLVM::CreateStore (*builder, llvm::ConstantInt::get (llvm::Type::getInt1Ty (context), 0 ), is_el_matching_ptr);
6507+ }, [&](){
64706508 // Check if the actual element is present or not
6471- llvm::Value* is_el_matching = llvm_utils->is_equal_by_value (el,
6472- llvm_utils->list_api ->read_item (el_list, pos, false , module ,
6473- LLVM::is_llvm_struct (el_asr_type)), module , el_asr_type);
6509+ llvm::Value* pos = LLVM::CreateLoad (*builder, pos_ptr);
6510+ llvm::Value* item = llvm_utils->list_api ->read_item (el_list, pos, false , module ,
6511+ LLVM::is_llvm_struct (el_asr_type)) ;
6512+ llvm::Value *iseq =llvm_utils->is_equal_by_value (el,
6513+ item, module , el_asr_type) ;
6514+ LLVM::CreateStore (*builder, iseq, is_el_matching_ptr);
6515+ });
6516+
6517+ llvm::Value *is_el_matching = LLVM::CreateLoad (*builder, is_el_matching_ptr);
6518+ if (check_if_exists) {
6519+ return is_el_matching;
6520+ }
64746521
64756522 llvm_utils->create_if_else (is_el_matching, []() {}, [&]() {
64766523 if (throw_key_error) {
@@ -6484,11 +6531,13 @@ namespace LCompilers {
64846531 exit (context, module , *builder, exit_code);
64856532 }
64866533 });
6534+
6535+ return nullptr ;
64876536 }
64886537
6489- void LLVMSetSeparateChaining::resolve_collision_for_read_with_bound_check (
6538+ llvm::Value* LLVMSetSeparateChaining::resolve_collision_for_read_with_bound_check (
64906539 llvm::Value* set, llvm::Value* el_hash, llvm::Value* el,
6491- llvm::Module& module , ASR::ttype_t * el_asr_type, bool throw_key_error) {
6540+ llvm::Module& module , ASR::ttype_t * el_asr_type, bool throw_key_error, bool check_if_exists ) {
64926541 /* *
64936542 * C++ equivalent:
64946543 *
@@ -6515,6 +6564,10 @@ namespace LCompilers {
65156564 llvm::ConstantPointerNull::get (llvm::Type::getInt8PtrTy (context)))
65166565 );
65176566
6567+ if (check_if_exists) {
6568+ return does_el_exist;
6569+ }
6570+
65186571 llvm_utils->create_if_else (does_el_exist, []() {}, [&]() {
65196572 if (throw_key_error) {
65206573 std::string message = " The set does not contain the specified element" ;
@@ -6527,6 +6580,8 @@ namespace LCompilers {
65276580 exit (context, module , *builder, exit_code);
65286581 }
65296582 });
6583+
6584+ return nullptr ;
65306585 }
65316586
65326587 void LLVMSetLinearProbing::remove_item (
0 commit comments