Skip to content

Commit bce615b

Browse files
committed
LLVMCodeBuilder: Optimize list writing
1 parent 6e0624c commit bce615b

File tree

2 files changed

+33
-47
lines changed

2 files changed

+33
-47
lines changed

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

Lines changed: 32 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,16 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
672672
Compiler::StaticType type = optimizeRegisterType(arg.second);
673673
LLVMListPtr &listPtr = m_listPtrs[step.workList];
674674

675+
auto &typeMap = m_scopeLists.back();
676+
677+
if (typeMap.find(&listPtr) == typeMap.cend()) {
678+
listPtr.type = type;
679+
typeMap[&listPtr] = listPtr.type;
680+
} else if (listPtr.type != type) {
681+
listPtr.type = Compiler::StaticType::Unknown;
682+
typeMap[&listPtr] = listPtr.type;
683+
}
684+
675685
// Check if enough space is allocated
676686
llvm::Value *allocatedSize = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.allocatedSizePtr);
677687
llvm::Value *size = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.sizePtr);
@@ -684,27 +694,18 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
684694
// If there's enough space, use the allocated memory
685695
m_builder.SetInsertPoint(ifBlock);
686696
llvm::Value *itemPtr = getListItem(listPtr, size);
687-
createReusedValueStore(arg.second, itemPtr, type);
697+
createReusedValueStore(arg.second, itemPtr, type, listPtr.type);
688698
m_builder.CreateStore(m_builder.CreateAdd(size, m_builder.getInt64(1)), listPtr.sizePtr);
689699
m_builder.CreateBr(nextBlock);
690700

691701
// Otherwise call appendEmpty()
692702
m_builder.SetInsertPoint(elseBlock);
693703
itemPtr = m_builder.CreateCall(resolve_list_append_empty(), listPtr.ptr);
694-
createReusedValueStore(arg.second, itemPtr, type);
704+
createReusedValueStore(arg.second, itemPtr, type, listPtr.type);
695705
m_builder.CreateStore(m_builder.getInt1(true), listPtr.dataPtrDirty);
696706
m_builder.CreateBr(nextBlock);
697707

698708
m_builder.SetInsertPoint(nextBlock);
699-
auto &typeMap = m_scopeLists.back();
700-
701-
if (typeMap.find(&listPtr) == typeMap.cend()) {
702-
listPtr.type = type;
703-
typeMap[&listPtr] = listPtr.type;
704-
} else if (listPtr.type != type) {
705-
listPtr.type = Compiler::StaticType::Unknown;
706-
typeMap[&listPtr] = listPtr.type;
707-
}
708709

709710
break;
710711
}
@@ -716,17 +717,6 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
716717
Compiler::StaticType type = optimizeRegisterType(valueArg.second);
717718
LLVMListPtr &listPtr = m_listPtrs[step.workList];
718719

719-
// dataPtrDirty
720-
llvm::Value *dataPtrDirty = m_builder.CreateLoad(m_builder.getInt1Ty(), listPtr.dataPtrDirty);
721-
llvm::Value *allocatedSize = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.allocatedSizePtr);
722-
llvm::Value *size = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.sizePtr);
723-
m_builder.CreateStore(m_builder.CreateOr(dataPtrDirty, m_builder.CreateICmpEQ(allocatedSize, size)), listPtr.dataPtrDirty);
724-
725-
// Insert
726-
llvm::Value *index = m_builder.CreateFPToUI(castValue(indexArg.second, indexArg.first), m_builder.getInt64Ty());
727-
llvm::Value *itemPtr = m_builder.CreateCall(resolve_list_insert_empty(), { listPtr.ptr, index });
728-
createReusedValueStore(valueArg.second, itemPtr, type);
729-
730720
auto &typeMap = m_scopeLists.back();
731721

732722
if (typeMap.find(&listPtr) == typeMap.cend()) {
@@ -737,6 +727,17 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
737727
typeMap[&listPtr] = listPtr.type;
738728
}
739729

730+
// dataPtrDirty
731+
llvm::Value *dataPtrDirty = m_builder.CreateLoad(m_builder.getInt1Ty(), listPtr.dataPtrDirty);
732+
llvm::Value *allocatedSize = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.allocatedSizePtr);
733+
llvm::Value *size = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.sizePtr);
734+
m_builder.CreateStore(m_builder.CreateOr(dataPtrDirty, m_builder.CreateICmpEQ(allocatedSize, size)), listPtr.dataPtrDirty);
735+
736+
// Insert
737+
llvm::Value *index = m_builder.CreateFPToUI(castValue(indexArg.second, indexArg.first), m_builder.getInt64Ty());
738+
llvm::Value *itemPtr = m_builder.CreateCall(resolve_list_insert_empty(), { listPtr.ptr, index });
739+
createReusedValueStore(valueArg.second, itemPtr, type, listPtr.type);
740+
740741
break;
741742
}
742743

@@ -2153,33 +2154,18 @@ void LLVMCodeBuilder::createValueStore(LLVMRegister *reg, llvm::Value *targetPtr
21532154
}
21542155
}
21552156

2156-
void LLVMCodeBuilder::createReusedValueStore(LLVMRegister *reg, llvm::Value *targetPtr, Compiler::StaticType sourceType)
2157+
void LLVMCodeBuilder::createReusedValueStore(LLVMRegister *reg, llvm::Value *targetPtr, Compiler::StaticType sourceType, Compiler::StaticType targetType)
21572158
{
2158-
llvm::Value *converted = nullptr;
2159-
2160-
if (sourceType != Compiler::StaticType::Unknown)
2161-
converted = castValue(reg, sourceType);
2162-
2163-
switch (sourceType) {
2164-
case Compiler::StaticType::Number:
2165-
m_builder.CreateCall(resolve_value_assign_double(), { targetPtr, converted });
2166-
break;
2159+
// Same as createValueStore(), but ensures that type is updated
2160+
createValueStore(reg, targetPtr, sourceType, targetType);
21672161

2168-
case Compiler::StaticType::Bool:
2169-
m_builder.CreateCall(resolve_value_assign_bool(), { targetPtr, converted });
2170-
break;
2171-
2172-
case Compiler::StaticType::String:
2173-
m_builder.CreateCall(resolve_value_assign_cstring(), { targetPtr, converted });
2174-
break;
2175-
2176-
case Compiler::StaticType::Unknown:
2177-
m_builder.CreateCall(resolve_value_assign_copy(), { targetPtr, reg->value });
2178-
break;
2162+
auto it = std::find_if(TYPE_MAP.begin(), TYPE_MAP.end(), [sourceType](const std::pair<ValueType, Compiler::StaticType> &pair) { return pair.second == sourceType; });
2163+
const ValueType mappedType = it == TYPE_MAP.cend() ? ValueType::Number : it->first; // unknown type can be ignored
21792164

2180-
default:
2181-
assert(false);
2182-
break;
2165+
if ((sourceType == Compiler::StaticType::Number || sourceType == Compiler::StaticType::Bool) && sourceType == targetType) {
2166+
// Update type when writing number to number and bool to bool
2167+
llvm::Value *typePtr = m_builder.CreateStructGEP(m_valueDataType, targetPtr, 1);
2168+
m_builder.CreateStore(m_builder.getInt32(static_cast<uint32_t>(mappedType)), typePtr);
21832169
}
21842170
}
21852171

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ class LLVMCodeBuilder : public ICodeBuilder
149149
LLVMRegister *createOp(const LLVMInstruction &ins, Compiler::StaticType retType, const Compiler::ArgTypes &argTypes = {}, const Compiler::Args &args = {});
150150

151151
void createValueStore(LLVMRegister *reg, llvm::Value *targetPtr, Compiler::StaticType sourceType, Compiler::StaticType targetType);
152-
void createReusedValueStore(LLVMRegister *reg, llvm::Value *targetPtr, Compiler::StaticType sourceType);
152+
void createReusedValueStore(LLVMRegister *reg, llvm::Value *targetPtr, Compiler::StaticType sourceType, Compiler::StaticType targetType);
153153
void createValueCopy(llvm::Value *source, llvm::Value *target);
154154
void copyStructField(llvm::Value *source, llvm::Value *target, int index, llvm::StructType *structType, llvm::Type *fieldType);
155155
llvm::Value *getListItem(const LLVMListPtr &listPtr, llvm::Value *index);

0 commit comments

Comments
 (0)