Skip to content

Commit f982aae

Browse files
committed
LLVMCodeBuilder: Update list data pointer when needed
1 parent d429e0a commit f982aae

File tree

3 files changed

+32
-9
lines changed

3 files changed

+32
-9
lines changed

src/dev/engine/internal/llvm/llvmcodebuilder.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
15651585
LLVMInstruction &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

17331754
llvm::Value *LLVMCodeBuilder::createValue(LLVMRegisterPtr reg)

src/dev/engine/internal/llvm/llvmcodebuilder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ class LLVMCodeBuilder : public ICodeBuilder
113113
void syncVariables(llvm::Value *targetVariables);
114114
void reloadVariables(llvm::Value *targetVariables);
115115
void reloadLists();
116+
void updateListDataPtr(const LLVMListPtr &listPtr, llvm::Function *func);
116117

117118
LLVMInstruction &createOp(LLVMInstruction::Type type, Compiler::StaticType retType, Compiler::StaticType argType, size_t argCount);
118119
LLVMInstruction &createOp(LLVMInstruction::Type type, Compiler::StaticType retType, const std::vector<Compiler::StaticType> &argTypes, size_t argCount);
@@ -121,7 +122,7 @@ class LLVMCodeBuilder : public ICodeBuilder
121122
void createInitialValueStore(LLVMRegisterPtr reg, llvm::Value *targetPtr, Compiler::StaticType sourceType);
122123
void createValueCopy(llvm::Value *source, llvm::Value *target);
123124
void copyStructField(llvm::Value *source, llvm::Value *target, int index, llvm::StructType *structType, llvm::Type *fieldType);
124-
llvm::Value *getListItem(llvm::Value *dataPtr, llvm::Value *index);
125+
llvm::Value *getListItem(const LLVMListPtr &listPtr, llvm::Value *index, llvm::Function *func);
125126
llvm::Value *createValue(LLVMRegisterPtr reg);
126127
llvm::Value *createComparison(LLVMRegisterPtr arg1, LLVMRegisterPtr arg2, Comparison type);
127128

src/dev/engine/internal/llvm/llvmlistptr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct LLVMListPtr
2020
llvm::Value *dataPtr = nullptr;
2121
llvm::Value *sizePtr = nullptr;
2222
llvm::Value *allocatedSizePtr = nullptr;
23+
llvm::Value *dataPtrDirty = nullptr;
2324
Compiler::StaticType type = Compiler::StaticType::Unknown;
2425
};
2526

0 commit comments

Comments
 (0)