| 1415 | } |
| 1416 | |
| 1417 | void SlotDescriptor::CodegenWriteCollectionItemsToSlot(LlvmCodeGen* codegen, |
| 1418 | LlvmBuilder* builder, llvm::Value* collection_value_ptr, llvm::Value* num_tuples, |
| 1419 | llvm::Value* pool_val, const NonWritableBasicBlock& insert_before) const { |
| 1420 | DCHECK(pool_val != nullptr); |
| 1421 | // We construct a while-like loop using basic blocks and conditional branches to iterate |
| 1422 | // through the items of the collection, recursively. |
| 1423 | llvm::Function* fn = builder->GetInsertBlock()->getParent(); |
| 1424 | llvm::BasicBlock* loop_condition_block = insert_before.CreateBasicBlockBefore( |
| 1425 | codegen->context(), "loop_condition_block", fn); |
| 1426 | llvm::BasicBlock* loop_body_block = insert_before.CreateBasicBlockBefore( |
| 1427 | codegen->context(), "loop_body_block", fn); |
| 1428 | llvm::BasicBlock* loop_increment_block = insert_before.CreateBasicBlockBefore( |
| 1429 | codegen->context(), "loop_increment_block", fn); |
| 1430 | llvm::BasicBlock* loop_exit_block = insert_before.CreateBasicBlockBefore( |
| 1431 | codegen->context(), "loop_exit_block", fn); |
| 1432 | |
| 1433 | // Initialise the loop counter. |
| 1434 | llvm::Value* item_index_addr = codegen->CreateEntryBlockAlloca( |
| 1435 | *builder, codegen->i32_type(), "item_index_addr"); |
| 1436 | builder->CreateStore(codegen->GetI32Constant(0), item_index_addr); |
| 1437 | |
| 1438 | builder->CreateBr(loop_condition_block); |
| 1439 | |
| 1440 | // Loop condition block |
| 1441 | builder->SetInsertPoint(loop_condition_block); |
| 1442 | llvm::Value* item_index = builder->CreateLoad(item_index_addr, "item_index"); |
| 1443 | llvm::Value* continue_loop = builder->CreateICmpSLT( |
| 1444 | item_index, num_tuples, "continue_loop"); |
| 1445 | builder->CreateCondBr(continue_loop, loop_body_block, loop_exit_block); |
| 1446 | |
| 1447 | // Loop body |
| 1448 | builder->SetInsertPoint(loop_body_block); |
| 1449 | CodegenWriteCollectionItemLoopBody(codegen, builder, collection_value_ptr, num_tuples, |
| 1450 | item_index, fn, insert_before, pool_val); |
| 1451 | builder->CreateBr(loop_increment_block); |
| 1452 | |
| 1453 | // Loop increment |
| 1454 | builder->SetInsertPoint(loop_increment_block); |
| 1455 | llvm::Value* item_index_incremented = builder->CreateAdd( |
| 1456 | item_index, codegen->GetI32Constant(1), "item_index_incremented"); |
| 1457 | builder->CreateStore(item_index_incremented, item_index_addr); |
| 1458 | builder->CreateBr(loop_condition_block); |
| 1459 | |
| 1460 | // Loop exit |
| 1461 | builder->SetInsertPoint(loop_exit_block); |
| 1462 | } |
| 1463 | |
| 1464 | void SlotDescriptor::CodegenWriteCollectionItemLoopBody(LlvmCodeGen* codegen, |
| 1465 | LlvmBuilder* builder, llvm::Value* collection_value_ptr, llvm::Value* num_tuples, |
no test coverage detected