Skip to content

Commit fd3cc6c

Browse files
committed
LLVMCodeBuilder: Implement list append
1 parent 9e790d0 commit fd3cc6c

File tree

6 files changed

+121
-0
lines changed

6 files changed

+121
-0
lines changed

src/dev/engine/internal/icodebuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class ICodeBuilder
5858

5959
virtual void createListClear(List *list) = 0;
6060
virtual void createListRemove(List *list) = 0;
61+
virtual void createListAppend(List *list) = 0;
6162

6263
virtual void beginIfStatement() = 0;
6364
virtual void beginElseBranch() = 0;

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

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,17 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
493493
break;
494494
}
495495

496+
case LLVMInstruction::Type::AppendToList: {
497+
assert(step.args.size() == 1);
498+
const auto &arg = step.args[0];
499+
Compiler::StaticType type = optimizeRegisterType(arg.second);
500+
const LLVMListPtr &listPtr = m_listPtrs[step.workList];
501+
llvm::Value *itemPtr = m_builder.CreateCall(resolve_list_append_empty(), listPtr.ptr);
502+
createInitialValueStore(arg.second, itemPtr, type);
503+
// TODO: Implement list type prediction
504+
break;
505+
}
506+
496507
case LLVMInstruction::Type::Yield:
497508
if (!m_warp) {
498509
freeHeap();
@@ -962,6 +973,13 @@ void LLVMCodeBuilder::createListRemove(List *list)
962973
m_listPtrs[list] = LLVMListPtr();
963974
}
964975

976+
void LLVMCodeBuilder::createListAppend(List *list)
977+
{
978+
LLVMInstruction &ins = createOp(LLVMInstruction::Type::AppendToList, Compiler::StaticType::Void, Compiler::StaticType::Unknown, 1);
979+
ins.workList = list;
980+
m_listPtrs[list] = LLVMListPtr();
981+
}
982+
965983
void LLVMCodeBuilder::beginIfStatement()
966984
{
967985
LLVMInstruction ins(LLVMInstruction::Type::BeginIf);
@@ -1519,6 +1537,41 @@ void LLVMCodeBuilder::createValueStore(LLVMRegisterPtr reg, llvm::Value *targetP
15191537
}
15201538
}
15211539

1540+
void LLVMCodeBuilder::createInitialValueStore(LLVMRegisterPtr reg, llvm::Value *targetPtr, Compiler::StaticType sourceType)
1541+
{
1542+
llvm::Value *converted = nullptr;
1543+
1544+
if (sourceType != Compiler::StaticType::Unknown)
1545+
converted = castValue(reg, sourceType);
1546+
1547+
auto it = std::find_if(TYPE_MAP.begin(), TYPE_MAP.end(), [sourceType](const std::pair<ValueType, Compiler::StaticType> &pair) { return pair.second == sourceType; });
1548+
const ValueType mappedType = it == TYPE_MAP.cend() ? ValueType::Number : it->first; // unknown type can be ignored
1549+
1550+
llvm::Value *valuePtr = m_builder.CreateStructGEP(m_valueDataType, targetPtr, 0);
1551+
llvm::Value *typePtr = m_builder.CreateStructGEP(m_valueDataType, targetPtr, 1);
1552+
m_builder.CreateStore(m_builder.getInt32(static_cast<uint32_t>(mappedType)), typePtr);
1553+
1554+
switch (sourceType) {
1555+
case Compiler::StaticType::Number:
1556+
case Compiler::StaticType::Bool:
1557+
// Write number/bool directly
1558+
m_builder.CreateStore(converted, valuePtr);
1559+
break;
1560+
1561+
case Compiler::StaticType::String:
1562+
m_builder.CreateCall(resolve_value_assign_cstring(), { targetPtr, converted });
1563+
break;
1564+
1565+
case Compiler::StaticType::Unknown:
1566+
m_builder.CreateCall(resolve_value_assign_copy(), { targetPtr, reg->value });
1567+
break;
1568+
1569+
default:
1570+
assert(false);
1571+
break;
1572+
}
1573+
}
1574+
15221575
void LLVMCodeBuilder::createValueCopy(llvm::Value *source, llvm::Value *target)
15231576
{
15241577
// NOTE: This doesn't copy strings, but only the pointers
@@ -1864,6 +1917,12 @@ llvm::FunctionCallee LLVMCodeBuilder::resolve_list_remove()
18641917
return resolveFunction("list_remove", llvm::FunctionType::get(m_builder.getVoidTy(), { listPtr, m_builder.getInt64Ty() }, false));
18651918
}
18661919

1920+
llvm::FunctionCallee LLVMCodeBuilder::resolve_list_append_empty()
1921+
{
1922+
llvm::Type *listPtr = llvm::PointerType::get(llvm::Type::getInt8Ty(m_ctx), 0);
1923+
return resolveFunction("list_append_empty", llvm::FunctionType::get(m_valueDataType->getPointerTo(), { listPtr }, false));
1924+
}
1925+
18671926
llvm::FunctionCallee LLVMCodeBuilder::resolve_strcasecmp()
18681927
{
18691928
llvm::Type *pointerType = llvm::PointerType::get(llvm::Type::getInt8Ty(m_ctx), 0);

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class LLVMCodeBuilder : public ICodeBuilder
6464

6565
void createListClear(List *list) override;
6666
void createListRemove(List *list) override;
67+
void createListAppend(List *list) override;
6768

6869
void beginIfStatement() override;
6970
void beginElseBranch() override;
@@ -111,6 +112,7 @@ class LLVMCodeBuilder : public ICodeBuilder
111112
LLVMInstruction &createOp(LLVMInstruction::Type type, Compiler::StaticType retType, Compiler::StaticType argType, size_t argCount);
112113

113114
void createValueStore(LLVMRegisterPtr reg, llvm::Value *targetPtr, Compiler::StaticType sourceType, Compiler::StaticType targetType);
115+
void createInitialValueStore(LLVMRegisterPtr reg, llvm::Value *targetPtr, Compiler::StaticType sourceType);
114116
void createValueCopy(llvm::Value *source, llvm::Value *target);
115117
void copyStructField(llvm::Value *source, llvm::Value *target, int index, llvm::StructType *structType, llvm::Type *fieldType);
116118
llvm::Value *createValue(LLVMRegisterPtr reg);
@@ -137,6 +139,7 @@ class LLVMCodeBuilder : public ICodeBuilder
137139
llvm::FunctionCallee resolve_value_lower();
138140
llvm::FunctionCallee resolve_list_clear();
139141
llvm::FunctionCallee resolve_list_remove();
142+
llvm::FunctionCallee resolve_list_append_empty();
140143
llvm::FunctionCallee resolve_strcasecmp();
141144

142145
Target *m_target = nullptr;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct LLVMInstruction
4444
ReadVariable,
4545
ClearList,
4646
RemoveListItem,
47+
AppendToList,
4748
Yield,
4849
BeginIf,
4950
BeginElse,

test/dev/llvm/llvmcodebuilder_test.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,6 +2016,62 @@ TEST_F(LLVMCodeBuilderTest, RemoveFromList)
20162016
ASSERT_EQ(localList->toString(), "Lorem ipsum dolor");
20172017
}
20182018

2019+
TEST_F(LLVMCodeBuilderTest, AppendToList)
2020+
{
2021+
EngineMock engine;
2022+
Stage stage;
2023+
Sprite sprite;
2024+
sprite.setEngine(&engine);
2025+
EXPECT_CALL(engine, stage()).WillRepeatedly(Return(&stage));
2026+
2027+
std::unordered_map<List *, std::string> strings;
2028+
2029+
auto globalList = std::make_shared<List>("", "");
2030+
stage.addList(globalList);
2031+
2032+
auto localList = std::make_shared<List>("", "");
2033+
sprite.addList(localList);
2034+
2035+
globalList->append(1);
2036+
globalList->append(2);
2037+
globalList->append(3);
2038+
2039+
localList->append("Lorem");
2040+
localList->append("ipsum");
2041+
localList->append("dolor");
2042+
localList->append("sit");
2043+
strings[localList.get()] = localList->toString();
2044+
2045+
createBuilder(&sprite, true);
2046+
2047+
m_builder->addConstValue(1);
2048+
m_builder->createListAppend(globalList.get());
2049+
2050+
m_builder->addConstValue("test");
2051+
m_builder->createListAppend(globalList.get());
2052+
2053+
m_builder->addConstValue(3);
2054+
m_builder->createListAppend(localList.get());
2055+
2056+
m_builder->createListClear(localList.get());
2057+
2058+
m_builder->addConstValue(true);
2059+
m_builder->createListAppend(localList.get());
2060+
2061+
m_builder->addConstValue(false);
2062+
m_builder->createListAppend(localList.get());
2063+
2064+
m_builder->addConstValue("hello world");
2065+
m_builder->createListAppend(localList.get());
2066+
2067+
auto code = m_builder->finalize();
2068+
auto ctx = code->createExecutionContext(&sprite);
2069+
code->run(ctx.get());
2070+
2071+
ASSERT_EQ(globalList->toString(), "1 2 3 1 test");
2072+
ASSERT_EQ(localList->toString(), "true false hello world");
2073+
}
2074+
20192075
TEST_F(LLVMCodeBuilderTest, Yield)
20202076
{
20212077
auto build = [this]() {

test/mocks/codebuildermock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class CodeBuilderMock : public ICodeBuilder
4848

4949
MOCK_METHOD(void, createListClear, (List *), (override));
5050
MOCK_METHOD(void, createListRemove, (List *), (override));
51+
MOCK_METHOD(void, createListAppend, (List *), (override));
5152

5253
MOCK_METHOD(void, beginIfStatement, (), (override));
5354
MOCK_METHOD(void, beginElseBranch, (), (override));

0 commit comments

Comments
 (0)