@@ -670,8 +670,8 @@ namespace LFortran {
670
670
llvm_utils->start_new_block (loopbody);
671
671
{
672
672
llvm::Value* pos = LLVM::CreateLoad (*builder, pos_ptr);
673
- llvm::Value* srci = read_item (src, pos, true );
674
- llvm::Value* desti = read_item (dest, pos, true );
673
+ llvm::Value* srci = read_item (src, pos, false , module , true );
674
+ llvm::Value* desti = read_item (dest, pos, false , module , true );
675
675
llvm_utils->deepcopy (srci, desti, element_type, module );
676
676
llvm::Value* tmp = builder->CreateAdd (
677
677
pos,
@@ -951,25 +951,55 @@ namespace LFortran {
951
951
LLVM::CreateStore (*builder, dest_key_value_pairs, get_pointer_to_key_value_pairs (dest));
952
952
}
953
953
954
- void LLVMList::check_index_within_bounds (llvm::Value* /* list*/ , llvm::Value* /* pos*/ ) {
954
+ void LLVMList::check_index_within_bounds (llvm::Value* list,
955
+ llvm::Value* pos, llvm::Module& module ) {
956
+ llvm::Value* end_point = LLVM::CreateLoad (*builder,
957
+ get_pointer_to_current_end_point (list));
958
+ llvm::Value* zero = llvm::ConstantInt::get (llvm::Type::getInt32Ty (context),
959
+ llvm::APInt (32 , 0 ));
955
960
961
+ llvm::Function *fn = builder->GetInsertBlock ()->getParent ();
962
+ llvm::BasicBlock *thenBB = llvm::BasicBlock::Create (context, " then" , fn);
963
+ llvm::BasicBlock *elseBB = llvm::BasicBlock::Create (context, " else" );
964
+ llvm::BasicBlock *mergeBB = llvm::BasicBlock::Create (context, " ifcont" );
965
+
966
+ llvm::Value* cond = builder->CreateOr (
967
+ builder->CreateICmpSGE (pos, end_point),
968
+ builder->CreateICmpSLT (pos, zero));
969
+ builder->CreateCondBr (cond, thenBB, elseBB);
970
+ builder->SetInsertPoint (thenBB);
971
+ {
972
+ std::string message = " list index out of range" ;
973
+ llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr (" IndexError: %s\n " );
974
+ llvm::Value *fmt_ptr2 = builder->CreateGlobalStringPtr (message);
975
+ print_error (context, module , *builder, {fmt_ptr, fmt_ptr2});
976
+ int exit_code_int = 1 ;
977
+ llvm::Value *exit_code = llvm::ConstantInt::get (context,
978
+ llvm::APInt (32 , exit_code_int));
979
+ exit (context, module , *builder, exit_code);
980
+ }
981
+ builder->CreateBr (mergeBB);
982
+
983
+ llvm_utils->start_new_block (elseBB);
984
+ llvm_utils->start_new_block (mergeBB);
956
985
}
957
986
958
987
void LLVMList::write_item (llvm::Value* list, llvm::Value* pos,
959
988
llvm::Value* item, ASR::ttype_t * asr_type,
960
- llvm::Module& module , bool check_index_bound ) {
961
- if ( check_index_bound ) {
962
- check_index_within_bounds (list, pos);
989
+ bool enable_bounds_checking, llvm::Module& module ) {
990
+ if ( enable_bounds_checking ) {
991
+ check_index_within_bounds (list, pos, module );
963
992
}
964
993
llvm::Value* list_data = LLVM::CreateLoad (*builder, get_pointer_to_list_data (list));
965
994
llvm::Value* element_ptr = llvm_utils->create_ptr_gep (list_data, pos);
966
995
llvm_utils->deepcopy (item, element_ptr, asr_type, module );
967
996
}
968
997
969
998
void LLVMList::write_item (llvm::Value* list, llvm::Value* pos,
970
- llvm::Value* item, bool check_index_bound) {
971
- if ( check_index_bound ) {
972
- check_index_within_bounds (list, pos);
999
+ llvm::Value* item, bool enable_bounds_checking,
1000
+ llvm::Module& module ) {
1001
+ if ( enable_bounds_checking ) {
1002
+ check_index_within_bounds (list, pos, module );
973
1003
}
974
1004
llvm::Value* list_data = LLVM::CreateLoad (*builder, get_pointer_to_list_data (list));
975
1005
llvm::Value* element_ptr = llvm_utils->create_ptr_gep (list_data, pos);
@@ -1108,7 +1138,7 @@ namespace LFortran {
1108
1138
builder->SetInsertPoint (thenBB);
1109
1139
{
1110
1140
llvm::Value* original_key = llvm_utils->list_api ->read_item (key_list, pos,
1111
- LLVM::is_llvm_struct (key_asr_type), false );
1141
+ false , module , LLVM::is_llvm_struct (key_asr_type));
1112
1142
is_key_matching = llvm_utils->is_equal_by_value (key, original_key, module ,
1113
1143
key_asr_type);
1114
1144
LLVM::CreateStore (*builder, is_key_matching, is_key_matching_var);
@@ -1196,7 +1226,7 @@ namespace LFortran {
1196
1226
builder->SetInsertPoint (thenBB);
1197
1227
{
1198
1228
llvm::Value* original_key = llvm_utils->list_api ->read_item (key_list, pos,
1199
- LLVM::is_llvm_struct (key_asr_type), false );
1229
+ false , module , LLVM::is_llvm_struct (key_asr_type));
1200
1230
is_key_matching = llvm_utils->is_equal_by_value (key, original_key, module ,
1201
1231
key_asr_type);
1202
1232
LLVM::CreateStore (*builder, is_key_matching, is_key_matching_var);
@@ -1323,9 +1353,9 @@ namespace LFortran {
1323
1353
this ->resolve_collision (capacity, key_hash, key, key_list, key_mask, *module , key_asr_type);
1324
1354
llvm::Value* pos = LLVM::CreateLoad (*builder, pos_ptr);
1325
1355
llvm_utils->list_api ->write_item (key_list, pos, key,
1326
- key_asr_type, * module , false );
1356
+ key_asr_type, false , * module );
1327
1357
llvm_utils->list_api ->write_item (value_list, pos, value,
1328
- value_asr_type, * module , false );
1358
+ value_asr_type, false , * module );
1329
1359
llvm::Value* key_mask_value = LLVM::CreateLoad (*builder,
1330
1360
llvm_utils->create_ptr_gep (key_mask, pos));
1331
1361
llvm::Value* is_slot_empty = builder->CreateICmpEQ (key_mask_value,
@@ -1352,9 +1382,9 @@ namespace LFortran {
1352
1382
this ->resolve_collision (capacity, key_hash, key, key_list, key_mask, *module , key_asr_type);
1353
1383
llvm::Value* pos = LLVM::CreateLoad (*builder, pos_ptr);
1354
1384
llvm_utils->list_api ->write_item (key_list, pos, key,
1355
- key_asr_type, * module , false );
1385
+ key_asr_type, false , * module );
1356
1386
llvm_utils->list_api ->write_item (value_list, pos, value,
1357
- value_asr_type, * module , false );
1387
+ value_asr_type, false , * module );
1358
1388
1359
1389
llvm::Value* key_mask_value = LLVM::CreateLoad (*builder,
1360
1390
llvm_utils->create_ptr_gep (key_mask, pos));
@@ -1455,7 +1485,7 @@ namespace LFortran {
1455
1485
llvm::Value* capacity = LLVM::CreateLoad (*builder, get_pointer_to_capacity (dict));
1456
1486
this ->resolve_collision (capacity, key_hash, key, key_list, key_mask, module , key_asr_type, true );
1457
1487
llvm::Value* pos = LLVM::CreateLoad (*builder, pos_ptr);
1458
- llvm::Value* item = llvm_utils->list_api ->read_item (value_list, pos, true , false );
1488
+ llvm::Value* item = llvm_utils->list_api ->read_item (value_list, pos, false , module , true );
1459
1489
return item;
1460
1490
}
1461
1491
@@ -1493,9 +1523,8 @@ namespace LFortran {
1493
1523
llvm::BasicBlock *elseBB_single_match = llvm::BasicBlock::Create (context, " else" );
1494
1524
llvm::BasicBlock *mergeBB_single_match = llvm::BasicBlock::Create (context, " ifcont" );
1495
1525
llvm::Value* is_key_matching = llvm_utils->is_equal_by_value (key,
1496
- llvm_utils->list_api ->read_item (key_list, key_hash,
1497
- LLVM::is_llvm_struct (key_asr_type), false ),
1498
- module , key_asr_type);
1526
+ llvm_utils->list_api ->read_item (key_list, key_hash, false , module ,
1527
+ LLVM::is_llvm_struct (key_asr_type)), module , key_asr_type);
1499
1528
builder->CreateCondBr (is_key_matching, thenBB_single_match, elseBB_single_match);
1500
1529
builder->SetInsertPoint (thenBB_single_match);
1501
1530
LLVM::CreateStore (*builder, key_hash, pos_ptr);
@@ -1521,7 +1550,8 @@ namespace LFortran {
1521
1550
}
1522
1551
llvm_utils->start_new_block (mergeBB);
1523
1552
llvm::Value* pos = LLVM::CreateLoad (*builder, pos_ptr);
1524
- llvm::Value* item = llvm_utils->list_api ->read_item (value_list, pos, true , false );
1553
+ llvm::Value* item = llvm_utils->list_api ->read_item (value_list, pos,
1554
+ false , module , true );
1525
1555
return item;
1526
1556
}
1527
1557
@@ -1757,18 +1787,18 @@ namespace LFortran {
1757
1787
builder->SetInsertPoint (thenBB);
1758
1788
{
1759
1789
llvm::Value* key = llvm_utils->list_api ->read_item (key_list, idx,
1760
- LLVM::is_llvm_struct (key_asr_type), false );
1761
- llvm::Value* value = llvm_utils->list_api ->read_item (value_list, idx,
1762
- LLVM::is_llvm_struct (value_asr_type), false );
1790
+ false , * module , LLVM::is_llvm_struct (key_asr_type));
1791
+ llvm::Value* value = llvm_utils->list_api ->read_item (value_list,
1792
+ idx, false , * module , LLVM::is_llvm_struct (value_asr_type));
1763
1793
llvm::Value* key_hash = get_key_hash (current_capacity, key, key_asr_type, *module );
1764
1794
this ->resolve_collision (current_capacity, key_hash, key, new_key_list,
1765
1795
new_key_mask, *module , key_asr_type);
1766
1796
llvm::Value* pos = LLVM::CreateLoad (*builder, pos_ptr);
1767
- llvm::Value* key_dest = llvm_utils->list_api ->read_item (new_key_list, pos,
1768
- true , false );
1797
+ llvm::Value* key_dest = llvm_utils->list_api ->read_item (
1798
+ new_key_list, pos, false , * module , true );
1769
1799
llvm_utils->deepcopy (key, key_dest, key_asr_type, *module );
1770
- llvm::Value* value_dest = llvm_utils->list_api ->read_item (new_value_list, pos,
1771
- true , false );
1800
+ llvm::Value* value_dest = llvm_utils->list_api ->read_item (
1801
+ new_value_list, pos, false , * module , true );
1772
1802
llvm_utils->deepcopy (value, value_dest, value_asr_type, *module );
1773
1803
1774
1804
llvm::Value* linear_prob_happened = builder->CreateICmpNE (key_hash, pos);
@@ -2143,10 +2173,11 @@ namespace LFortran {
2143
2173
return LLVM::CreateLoad (*builder, value_ptr);
2144
2174
}
2145
2175
2146
- llvm::Value* LLVMList::read_item (llvm::Value* list, llvm::Value* pos, bool get_pointer,
2147
- bool check_index_bound) {
2148
- if ( check_index_bound ) {
2149
- check_index_within_bounds (list, pos);
2176
+ llvm::Value* LLVMList::read_item (llvm::Value* list, llvm::Value* pos,
2177
+ bool enable_bounds_checking,
2178
+ llvm::Module& module , bool get_pointer) {
2179
+ if ( enable_bounds_checking ) {
2180
+ check_index_within_bounds (list, pos, module );
2150
2181
}
2151
2182
llvm::Value* list_data = LLVM::CreateLoad (*builder, get_pointer_to_list_data (list));
2152
2183
llvm::Value* element_ptr = llvm_utils->create_ptr_gep (list_data, pos);
@@ -2233,7 +2264,7 @@ namespace LFortran {
2233
2264
llvm::Type* el_type = std::get<2 >(typecode2listtype[type_code]);
2234
2265
resize_if_needed (list, current_end_point, current_capacity,
2235
2266
type_size, el_type, module );
2236
- write_item (list, current_end_point, item, asr_type, module );
2267
+ write_item (list, current_end_point, item, asr_type, false , module );
2237
2268
shift_end_point_by_one (list);
2238
2269
}
2239
2270
@@ -2271,7 +2302,7 @@ namespace LFortran {
2271
2302
// LLVMList should treat them as data members and create them
2272
2303
// only if they are NULL
2273
2304
llvm::AllocaInst *tmp_ptr = builder->CreateAlloca (el_type, nullptr );
2274
- LLVM::CreateStore (*builder, read_item (list, pos, false ), tmp_ptr);
2305
+ LLVM::CreateStore (*builder, read_item (list, pos, false , module , false ), tmp_ptr);
2275
2306
llvm::Value* tmp = nullptr ;
2276
2307
2277
2308
// TODO: Should be created outside the user loop and not here.
@@ -2300,8 +2331,8 @@ namespace LFortran {
2300
2331
llvm::Value* next_index = builder->CreateAdd (
2301
2332
LLVM::CreateLoad (*builder, pos_ptr),
2302
2333
llvm::ConstantInt::get (context, llvm::APInt (32 , 1 )));
2303
- tmp = read_item (list, next_index, false );
2304
- write_item (list, next_index, LLVM::CreateLoad (*builder, tmp_ptr));
2334
+ tmp = read_item (list, next_index, false , module , false );
2335
+ write_item (list, next_index, LLVM::CreateLoad (*builder, tmp_ptr), false , module );
2305
2336
LLVM::CreateStore (*builder, tmp, tmp_ptr);
2306
2337
2307
2338
tmp = builder->CreateAdd (
@@ -2314,7 +2345,7 @@ namespace LFortran {
2314
2345
// end
2315
2346
llvm_utils->start_new_block (loopend);
2316
2347
2317
- write_item (list, pos, item, asr_type, module );
2348
+ write_item (list, pos, item, asr_type, false , module );
2318
2349
shift_end_point_by_one (list);
2319
2350
}
2320
2351
@@ -2350,7 +2381,7 @@ namespace LFortran {
2350
2381
llvm_utils->start_new_block (loophead);
2351
2382
{
2352
2383
llvm::Value* left_arg = read_item (list, LLVM::CreateLoad (*builder, i),
2353
- LLVM::is_llvm_struct (item_type));
2384
+ false , module , LLVM::is_llvm_struct (item_type));
2354
2385
llvm::Value* is_item_not_equal = builder->CreateNot (
2355
2386
llvm_utils->is_equal_by_value (
2356
2387
left_arg, item,
@@ -2445,7 +2476,7 @@ namespace LFortran {
2445
2476
LLVM::CreateLoad (*builder, item_pos),
2446
2477
llvm::ConstantInt::get (context, llvm::APInt (32 , 1 )));
2447
2478
write_item (list, LLVM::CreateLoad (*builder, item_pos),
2448
- read_item (list, tmp, false ) );
2479
+ read_item (list, tmp, false , module , false ), false , module );
2449
2480
LLVM::CreateStore (*builder, tmp, item_pos);
2450
2481
}
2451
2482
builder->CreateBr (loophead);
0 commit comments