@@ -104,6 +104,9 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
104104
105105 listPtr.sizePtr = m_builder.CreateCall (resolve_list_size_ptr (), listPtr.ptr );
106106 listPtr.allocatedSizePtr = m_builder.CreateCall (resolve_list_alloc_size_ptr (), listPtr.ptr );
107+
108+ listPtr.dataPtrDirty = m_builder.CreateAlloca (m_builder.getInt1Ty ());
109+ m_builder.CreateStore (m_builder.getInt1 (false ), listPtr.dataPtrDirty );
107110 }
108111
109112 // Execute recorded steps
@@ -488,6 +491,7 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
488491 assert (step.args .size () == 0 );
489492 const LLVMListPtr &listPtr = m_listPtrs[step.workList ];
490493 m_builder.CreateCall (resolve_list_clear (), listPtr.ptr );
494+ // NOTE: Clearing doesn't deallocate (see List::clear()), so there's no need to update the data pointer
491495 break ;
492496 }
493497
@@ -497,6 +501,7 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
497501 const LLVMListPtr &listPtr = m_listPtrs[step.workList ];
498502 llvm::Value *index = m_builder.CreateFPToUI (castValue (arg.second , arg.first ), m_builder.getInt64Ty ());
499503 m_builder.CreateCall (resolve_list_remove (), { listPtr.ptr , index });
504+ // NOTE: Removing doesn't deallocate (see List::removeAt()), so there's no need to update the data pointer
500505 break ;
501506 }
502507
@@ -517,7 +522,7 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
517522
518523 // If there's enough space, use the allocated memory
519524 m_builder.SetInsertPoint (ifBlock);
520- llvm::Value *itemPtr = getListItem (m_builder. CreateLoad (m_valueDataType-> getPointerTo (), listPtr. dataPtr ) , size);
525+ llvm::Value *itemPtr = getListItem (listPtr, size, func );
521526 createInitialValueStore (arg.second , itemPtr, type);
522527 m_builder.CreateStore (m_builder.CreateAdd (size, m_builder.getInt64 (1 )), listPtr.sizePtr );
523528 m_builder.CreateBr (nextBlock);
@@ -526,8 +531,7 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
526531 m_builder.SetInsertPoint (elseBlock);
527532 itemPtr = m_builder.CreateCall (resolve_list_append_empty (), listPtr.ptr );
528533 createInitialValueStore (arg.second , itemPtr, type);
529- // TODO: Update list data only when needed
530- m_builder.CreateStore (m_builder.CreateCall (resolve_list_data (), listPtr.ptr ), listPtr.dataPtr );
534+ m_builder.CreateStore (m_builder.getInt1 (true ), listPtr.dataPtrDirty );
531535 m_builder.CreateBr (nextBlock);
532536
533537 m_builder.SetInsertPoint (nextBlock);
@@ -541,10 +545,16 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
541545 const auto &valueArg = step.args [1 ];
542546 Compiler::StaticType type = optimizeRegisterType (valueArg.second );
543547 const LLVMListPtr &listPtr = m_listPtrs[step.workList ];
548+
549+ // dataPtrDirty
550+ llvm::Value *allocatedSize = m_builder.CreateLoad (m_builder.getInt64Ty (), listPtr.allocatedSizePtr );
551+ llvm::Value *size = m_builder.CreateLoad (m_builder.getInt64Ty (), listPtr.sizePtr );
552+ m_builder.CreateStore (m_builder.CreateICmpEQ (allocatedSize, size), listPtr.dataPtrDirty );
553+
554+ // Insert
544555 llvm::Value *index = m_builder.CreateFPToUI (castValue (indexArg.second , indexArg.first ), m_builder.getInt64Ty ());
545556 llvm::Value *itemPtr = m_builder.CreateCall (resolve_list_insert_empty (), { listPtr.ptr , index });
546557 createInitialValueStore (valueArg.second , itemPtr, type);
547- m_builder.CreateStore (m_builder.CreateCall (resolve_list_data (), listPtr.ptr ), listPtr.dataPtr );
548558 // TODO: Implement list type prediction
549559 break ;
550560 }
@@ -556,7 +566,7 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
556566 Compiler::StaticType type = optimizeRegisterType (valueArg.second );
557567 const LLVMListPtr &listPtr = m_listPtrs[step.workList ];
558568 llvm::Value *index = m_builder.CreateFPToUI (castValue (indexArg.second , indexArg.first ), m_builder.getInt64Ty ());
559- llvm::Value *itemPtr = getListItem (m_builder. CreateLoad (m_valueDataType-> getPointerTo (), listPtr. dataPtr ) , index);
569+ llvm::Value *itemPtr = getListItem (listPtr, index, func );
560570 createValueStore (valueArg.second , itemPtr, type, listPtr.type );
561571 // TODO: Implement list type prediction
562572 break ;
@@ -567,7 +577,7 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
567577 const auto &arg = step.args [0 ];
568578 const LLVMListPtr &listPtr = m_listPtrs[step.workList ];
569579 llvm::Value *index = m_builder.CreateFPToUI (castValue (arg.second , arg.first ), m_builder.getInt64Ty ());
570- step.functionReturnReg ->value = getListItem (m_builder. CreateLoad (m_valueDataType-> getPointerTo (), listPtr. dataPtr ) , index);
580+ step.functionReturnReg ->value = getListItem (listPtr, index, func );
571581 step.functionReturnReg ->type = listPtr.type ;
572582 break ;
573583 }
@@ -1562,6 +1572,16 @@ void LLVMCodeBuilder::reloadLists()
15621572 m_builder.CreateStore (m_builder.CreateCall (resolve_list_data (), listPtr.ptr ), listPtr.dataPtr );
15631573}
15641574
1575+ void LLVMCodeBuilder::updateListDataPtr (const LLVMListPtr &listPtr, llvm::Function *func)
1576+ {
1577+ // dataPtr = dirty ? list_data(list) : dataPtr
1578+ // dirty = false
1579+ llvm::Value *dirty = m_builder.CreateLoad (m_builder.getInt1Ty (), listPtr.dataPtrDirty );
1580+ llvm::Value *dataPtr = m_builder.CreateSelect (dirty, m_builder.CreateCall (resolve_list_data (), listPtr.ptr ), m_builder.CreateLoad (m_valueDataType->getPointerTo (), listPtr.dataPtr ));
1581+ m_builder.CreateStore (dataPtr, listPtr.dataPtr );
1582+ m_builder.CreateStore (m_builder.getInt1 (false ), listPtr.dataPtrDirty );
1583+ }
1584+
15651585LLVMInstruction &LLVMCodeBuilder::createOp (LLVMInstruction::Type type, Compiler::StaticType retType, Compiler::StaticType argType, size_t argCount)
15661586{
15671587 std::vector<Compiler::StaticType> types;
@@ -1725,9 +1745,10 @@ void LLVMCodeBuilder::copyStructField(llvm::Value *source, llvm::Value *target,
17251745 m_builder.CreateStore (m_builder.CreateLoad (fieldType, sourceField), targetField);
17261746}
17271747
1728- llvm::Value *LLVMCodeBuilder::getListItem (llvm::Value *dataPtr , llvm::Value *index )
1748+ llvm::Value *LLVMCodeBuilder::getListItem (const LLVMListPtr &listPtr, llvm::Value *index , llvm::Function *func )
17291749{
1730- return m_builder.CreateGEP (m_valueDataType, dataPtr, index);
1750+ updateListDataPtr (listPtr, func);
1751+ return m_builder.CreateGEP (m_valueDataType, m_builder.CreateLoad (m_valueDataType->getPointerTo (), listPtr.dataPtr ), index);
17311752}
17321753
17331754llvm::Value *LLVMCodeBuilder::createValue (LLVMRegisterPtr reg)
0 commit comments