Skip to content

Commit d429e0a

Browse files
committed
LLVMCodeBuilder: Optimize list append
1 parent 94fc6b1 commit d429e0a

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

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

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,12 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
9898
// Create list pointers
9999
for (auto &[list, listPtr] : m_listPtrs) {
100100
listPtr.ptr = getListPtr(targetLists, list);
101+
101102
listPtr.dataPtr = m_builder.CreateAlloca(m_valueDataType->getPointerTo());
102103
m_builder.CreateStore(m_builder.CreateCall(resolve_list_data(), listPtr.ptr), listPtr.dataPtr);
104+
103105
listPtr.sizePtr = m_builder.CreateCall(resolve_list_size_ptr(), listPtr.ptr);
106+
listPtr.allocatedSizePtr = m_builder.CreateCall(resolve_list_alloc_size_ptr(), listPtr.ptr);
104107
}
105108

106109
// Execute recorded steps
@@ -502,9 +505,32 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
502505
const auto &arg = step.args[0];
503506
Compiler::StaticType type = optimizeRegisterType(arg.second);
504507
const LLVMListPtr &listPtr = m_listPtrs[step.workList];
505-
llvm::Value *itemPtr = m_builder.CreateCall(resolve_list_append_empty(), listPtr.ptr);
508+
509+
// Check if enough space is allocated
510+
llvm::Value *allocatedSize = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.allocatedSizePtr);
511+
llvm::Value *size = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.sizePtr);
512+
llvm::Value *isAllocated = m_builder.CreateICmpUGT(allocatedSize, size);
513+
llvm::BasicBlock *ifBlock = llvm::BasicBlock::Create(m_ctx, "", func);
514+
llvm::BasicBlock *elseBlock = llvm::BasicBlock::Create(m_ctx, "", func);
515+
llvm::BasicBlock *nextBlock = llvm::BasicBlock::Create(m_ctx, "", func);
516+
m_builder.CreateCondBr(isAllocated, ifBlock, elseBlock);
517+
518+
// If there's enough space, use the allocated memory
519+
m_builder.SetInsertPoint(ifBlock);
520+
llvm::Value *itemPtr = getListItem(m_builder.CreateLoad(m_valueDataType->getPointerTo(), listPtr.dataPtr), size);
521+
createInitialValueStore(arg.second, itemPtr, type);
522+
m_builder.CreateStore(m_builder.CreateAdd(size, m_builder.getInt64(1)), listPtr.sizePtr);
523+
m_builder.CreateBr(nextBlock);
524+
525+
// Otherwise call appendEmpty()
526+
m_builder.SetInsertPoint(elseBlock);
527+
itemPtr = m_builder.CreateCall(resolve_list_append_empty(), listPtr.ptr);
506528
createInitialValueStore(arg.second, itemPtr, type);
529+
// TODO: Update list data only when needed
507530
m_builder.CreateStore(m_builder.CreateCall(resolve_list_data(), listPtr.ptr), listPtr.dataPtr);
531+
m_builder.CreateBr(nextBlock);
532+
533+
m_builder.SetInsertPoint(nextBlock);
508534
// TODO: Implement list type prediction
509535
break;
510536
}
@@ -2058,6 +2084,12 @@ llvm::FunctionCallee LLVMCodeBuilder::resolve_list_size_ptr()
20582084
return resolveFunction("list_size_ptr", llvm::FunctionType::get(m_builder.getInt64Ty()->getPointerTo()->getPointerTo(), { listPtr }, false));
20592085
}
20602086

2087+
llvm::FunctionCallee LLVMCodeBuilder::resolve_list_alloc_size_ptr()
2088+
{
2089+
llvm::Type *listPtr = llvm::PointerType::get(llvm::Type::getInt8Ty(m_ctx), 0);
2090+
return resolveFunction("list_alloc_size_ptr", llvm::FunctionType::get(m_builder.getInt64Ty()->getPointerTo()->getPointerTo(), { listPtr }, false));
2091+
}
2092+
20612093
llvm::FunctionCallee LLVMCodeBuilder::resolve_strcasecmp()
20622094
{
20632095
llvm::Type *pointerType = llvm::PointerType::get(llvm::Type::getInt8Ty(m_ctx), 0);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ class LLVMCodeBuilder : public ICodeBuilder
150150
llvm::FunctionCallee resolve_list_insert_empty();
151151
llvm::FunctionCallee resolve_list_data();
152152
llvm::FunctionCallee resolve_list_size_ptr();
153+
llvm::FunctionCallee resolve_list_alloc_size_ptr();
153154
llvm::FunctionCallee resolve_strcasecmp();
154155

155156
Target *m_target = nullptr;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct LLVMListPtr
1919
llvm::Value *ptr = nullptr;
2020
llvm::Value *dataPtr = nullptr;
2121
llvm::Value *sizePtr = nullptr;
22+
llvm::Value *allocatedSizePtr = nullptr;
2223
Compiler::StaticType type = Compiler::StaticType::Unknown;
2324
};
2425

0 commit comments

Comments
 (0)