Skip to content

Commit fb7ad85

Browse files
committed
LLVMCodeBuilder: Use pointer to list data pointer
Avoid unnecessary function call to list_data().
1 parent 9b7ae5a commit fb7ad85

File tree

3 files changed

+12
-47
lines changed

3 files changed

+12
-47
lines changed

src/engine/internal/llvm/llvmcodebuilder.cpp

Lines changed: 10 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -139,14 +139,11 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
139139
for (auto &[list, listPtr] : m_listPtrs) {
140140
listPtr.ptr = getListPtr(targetLists, list);
141141

142-
listPtr.dataPtr = m_builder.CreateAlloca(m_valueDataType->getPointerTo());
143-
m_builder.CreateStore(m_builder.CreateCall(resolve_list_data(), listPtr.ptr), listPtr.dataPtr);
142+
listPtr.dataPtr = m_builder.CreateAlloca(m_valueDataType->getPointerTo()->getPointerTo());
143+
m_builder.CreateStore(m_builder.CreateCall(resolve_list_data_ptr(), listPtr.ptr), listPtr.dataPtr);
144144

145145
listPtr.sizePtr = m_builder.CreateCall(resolve_list_size_ptr(), listPtr.ptr);
146146
listPtr.allocatedSizePtr = m_builder.CreateCall(resolve_list_alloc_size_ptr(), listPtr.ptr);
147-
148-
listPtr.dataPtrDirty = m_builder.CreateAlloca(m_builder.getInt1Ty());
149-
m_builder.CreateStore(m_builder.getInt1(false), listPtr.dataPtrDirty);
150147
}
151148

152149
assert(m_loopScope == -1);
@@ -790,13 +787,7 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
790787
case LLVMInstruction::Type::ClearList: {
791788
assert(step.args.size() == 0);
792789
LLVMListPtr &listPtr = m_listPtrs[step.workList];
793-
llvm::Value *oldAllocatedSize = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.allocatedSizePtr);
794790
m_builder.CreateCall(resolve_list_clear(), listPtr.ptr);
795-
796-
// Clearing may deallocate, so check if the allocated size changed
797-
llvm::Value *dataPtrDirty = m_builder.CreateLoad(m_builder.getInt1Ty(), listPtr.dataPtrDirty);
798-
llvm::Value *allocatedSize = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.allocatedSizePtr);
799-
m_builder.CreateStore(m_builder.CreateOr(dataPtrDirty, m_builder.CreateICmpNE(allocatedSize, oldAllocatedSize)), listPtr.dataPtrDirty);
800791
break;
801792
}
802793

@@ -819,7 +810,6 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
819810
m_builder.SetInsertPoint(removeBlock);
820811
index = m_builder.CreateFPToUI(castValue(arg.second, arg.first), m_builder.getInt64Ty());
821812
m_builder.CreateCall(resolve_list_remove(), { listPtr.ptr, index });
822-
// NOTE: Removing doesn't deallocate (see List::removeAt()), so there's no need to update the data pointer
823813
m_builder.CreateBr(nextBlock);
824814

825815
m_builder.SetInsertPoint(nextBlock);
@@ -857,7 +847,6 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
857847
m_builder.SetInsertPoint(elseBlock);
858848
itemPtr = m_builder.CreateCall(resolve_list_append_empty(), listPtr.ptr);
859849
createReusedValueStore(arg.second, itemPtr, type, listType);
860-
m_builder.CreateStore(m_builder.getInt1(true), listPtr.dataPtrDirty);
861850
m_builder.CreateBr(nextBlock);
862851

863852
m_builder.SetInsertPoint(nextBlock);
@@ -877,8 +866,6 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
877866
if (m_warp)
878867
listType = m_typeAnalyzer.listType(step.workList, &step, Compiler::StaticType::Unknown, false);
879868

880-
llvm::Value *oldAllocatedSize = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.allocatedSizePtr);
881-
882869
// Range check
883870
llvm::Value *size = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.sizePtr);
884871
llvm::Value *min = llvm::ConstantFP::get(m_llvmCtx, llvm::APFloat(0.0));
@@ -895,11 +882,6 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
895882
llvm::Value *itemPtr = m_builder.CreateCall(resolve_list_insert_empty(), { listPtr.ptr, index });
896883
createReusedValueStore(valueArg.second, itemPtr, type, listType);
897884

898-
// Check if the allocated size changed
899-
llvm::Value *dataPtrDirty = m_builder.CreateLoad(m_builder.getInt1Ty(), listPtr.dataPtrDirty);
900-
llvm::Value *allocatedSize = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.allocatedSizePtr);
901-
m_builder.CreateStore(m_builder.CreateOr(dataPtrDirty, m_builder.CreateICmpNE(allocatedSize, oldAllocatedSize)), listPtr.dataPtrDirty);
902-
903885
m_builder.CreateBr(nextBlock);
904886

905887
m_builder.SetInsertPoint(nextBlock);
@@ -1275,7 +1257,6 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
12751257
}
12761258

12771259
reloadVariables(targetVariables);
1278-
reloadLists();
12791260
break;
12801261
}
12811262

@@ -2384,6 +2365,11 @@ llvm::Value *LLVMCodeBuilder::getListPtr(llvm::Value *targetLists, List *list)
23842365
return m_builder.CreateIntToPtr(addr, m_valueDataType->getPointerTo());
23852366
}
23862367

2368+
llvm::Value *LLVMCodeBuilder::getListDataPtr(const LLVMListPtr &listPtr)
2369+
{
2370+
return m_builder.CreateLoad(m_valueDataType->getPointerTo(), m_builder.CreateLoad(m_valueDataType->getPointerTo()->getPointerTo(), listPtr.dataPtr));
2371+
}
2372+
23872373
void LLVMCodeBuilder::syncVariables(llvm::Value *targetVariables)
23882374
{
23892375
// Copy stack variables to the actual variables
@@ -2404,23 +2390,6 @@ void LLVMCodeBuilder::reloadVariables(llvm::Value *targetVariables)
24042390
}
24052391
}
24062392

2407-
void LLVMCodeBuilder::reloadLists()
2408-
{
2409-
// Reset list data dirty
2410-
for (auto &[list, listPtr] : m_listPtrs)
2411-
m_builder.CreateStore(m_builder.getInt1(true), listPtr.dataPtrDirty);
2412-
}
2413-
2414-
void LLVMCodeBuilder::updateListDataPtr(const LLVMListPtr &listPtr)
2415-
{
2416-
// dataPtr = dirty ? list_data(list) : dataPtr
2417-
// dirty = false
2418-
llvm::Value *dirty = m_builder.CreateLoad(m_builder.getInt1Ty(), listPtr.dataPtrDirty);
2419-
llvm::Value *dataPtr = m_builder.CreateSelect(dirty, m_builder.CreateCall(resolve_list_data(), listPtr.ptr), m_builder.CreateLoad(m_valueDataType->getPointerTo(), listPtr.dataPtr));
2420-
m_builder.CreateStore(dataPtr, listPtr.dataPtr);
2421-
m_builder.CreateStore(m_builder.getInt1(false), listPtr.dataPtrDirty);
2422-
}
2423-
24242393
LLVMRegister *LLVMCodeBuilder::createOp(LLVMInstruction::Type type, Compiler::StaticType retType, Compiler::StaticType argType, const Compiler::Args &args)
24252394
{
24262395
return createOp({ type, currentLoopScope(), m_loopCondition }, retType, argType, args);
@@ -2573,8 +2542,7 @@ void LLVMCodeBuilder::copyStructField(llvm::Value *source, llvm::Value *target,
25732542

25742543
llvm::Value *LLVMCodeBuilder::getListItem(const LLVMListPtr &listPtr, llvm::Value *index)
25752544
{
2576-
updateListDataPtr(listPtr);
2577-
return m_builder.CreateGEP(m_valueDataType, m_builder.CreateLoad(m_valueDataType->getPointerTo(), listPtr.dataPtr), index);
2545+
return m_builder.CreateGEP(m_valueDataType, getListDataPtr(listPtr), index);
25782546
}
25792547

25802548
llvm::Value *LLVMCodeBuilder::getListItemIndex(const LLVMListPtr &listPtr, Compiler::StaticType listType, LLVMRegister *item)
@@ -2932,7 +2900,6 @@ void LLVMCodeBuilder::createSuspend(LLVMCoroutine *coro, llvm::Value *warpArg, l
29322900
syncVariables(targetVariables);
29332901
coro->createSuspend();
29342902
reloadVariables(targetVariables);
2935-
reloadLists();
29362903

29372904
if (warpArg) {
29382905
m_builder.CreateBr(nextBranch);
@@ -3090,10 +3057,10 @@ llvm::FunctionCallee LLVMCodeBuilder::resolve_list_insert_empty()
30903057
return resolveFunction("list_insert_empty", llvm::FunctionType::get(m_valueDataType->getPointerTo(), { listPtr, m_builder.getInt64Ty() }, false));
30913058
}
30923059

3093-
llvm::FunctionCallee LLVMCodeBuilder::resolve_list_data()
3060+
llvm::FunctionCallee LLVMCodeBuilder::resolve_list_data_ptr()
30943061
{
30953062
llvm::Type *listPtr = llvm::PointerType::get(llvm::Type::getInt8Ty(m_llvmCtx), 0);
3096-
llvm::FunctionCallee callee = resolveFunction("list_data", llvm::FunctionType::get(m_valueDataType->getPointerTo(), { listPtr }, false));
3063+
llvm::FunctionCallee callee = resolveFunction("list_data_ptr", llvm::FunctionType::get(m_valueDataType->getPointerTo()->getPointerTo(), { listPtr }, false));
30973064
llvm::Function *func = llvm::cast<llvm::Function>(callee.getCallee());
30983065
func->addFnAttr(llvm::Attribute::ReadOnly);
30993066
return callee;

src/engine/internal/llvm/llvmcodebuilder.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,9 @@ class LLVMCodeBuilder : public ICodeBuilder
150150

151151
llvm::Value *getVariablePtr(llvm::Value *targetVariables, Variable *variable);
152152
llvm::Value *getListPtr(llvm::Value *targetLists, List *list);
153+
llvm::Value *getListDataPtr(const LLVMListPtr &listPtr);
153154
void syncVariables(llvm::Value *targetVariables);
154155
void reloadVariables(llvm::Value *targetVariables);
155-
void reloadLists();
156-
void updateListDataPtr(const LLVMListPtr &listPtr);
157156

158157
LLVMRegister *createOp(LLVMInstruction::Type type, Compiler::StaticType retType, Compiler::StaticType argType, const Compiler::Args &args);
159158
LLVMRegister *createOp(LLVMInstruction::Type type, Compiler::StaticType retType, const Compiler::ArgTypes &argTypes = {}, const Compiler::Args &args = {});
@@ -197,7 +196,7 @@ class LLVMCodeBuilder : public ICodeBuilder
197196
llvm::FunctionCallee resolve_list_remove();
198197
llvm::FunctionCallee resolve_list_append_empty();
199198
llvm::FunctionCallee resolve_list_insert_empty();
200-
llvm::FunctionCallee resolve_list_data();
199+
llvm::FunctionCallee resolve_list_data_ptr();
201200
llvm::FunctionCallee resolve_list_size_ptr();
202201
llvm::FunctionCallee resolve_list_alloc_size_ptr();
203202
llvm::FunctionCallee resolve_list_to_string();

src/engine/internal/llvm/llvmlistptr.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ struct LLVMListPtr
2424
llvm::Value *dataPtr = nullptr;
2525
llvm::Value *sizePtr = nullptr;
2626
llvm::Value *allocatedSizePtr = nullptr;
27-
llvm::Value *dataPtrDirty = nullptr;
2827

2928
// Used in build phase to check the type safety of lists in loops
3029
std::unordered_map<LLVMLoopScope *, std::vector<LLVMInstruction *>> loopListWrites; // loop scope, write instructions

0 commit comments

Comments
 (0)