Skip to content

Commit b05996c

Browse files
committed
LLVMCodeBuilder: Implement list item index
1 parent b1319ed commit b05996c

File tree

6 files changed

+161
-0
lines changed

6 files changed

+161
-0
lines changed

src/dev/engine/internal/icodebuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ICodeBuilder
2424
virtual void addVariableValue(Variable *variable) = 0;
2525
virtual void addListContents(List *list) = 0;
2626
virtual void addListItem(List *list) = 0;
27+
virtual void addListItemIndex(List *list) = 0;
2728
virtual void addListSize(List *list) = 0;
2829

2930
virtual void createAdd() = 0;

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

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,14 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
590590
break;
591591
}
592592

593+
case LLVMInstruction::Type::GetListItemIndex: {
594+
assert(step.args.size() == 1);
595+
const auto &arg = step.args[0];
596+
const LLVMListPtr &listPtr = m_listPtrs[step.workList];
597+
step.functionReturnReg->value = getListItemIndex(listPtr, arg.second, func);
598+
break;
599+
}
600+
593601
case LLVMInstruction::Type::Yield:
594602
if (!m_warp) {
595603
freeHeap();
@@ -929,6 +937,13 @@ void LLVMCodeBuilder::addListItem(List *list)
929937
m_instructions.push_back(ins);
930938
}
931939

940+
void LLVMCodeBuilder::addListItemIndex(List *list)
941+
{
942+
LLVMInstruction &ins = createOp(LLVMInstruction::Type::GetListItemIndex, Compiler::StaticType::Number, Compiler::StaticType::Unknown, 1);
943+
ins.workList = list;
944+
m_listPtrs[list] = LLVMListPtr();
945+
}
946+
932947
void LLVMCodeBuilder::addListSize(List *list)
933948
{
934949
LLVMInstruction &ins = createOp(LLVMInstruction::Type::GetListSize, Compiler::StaticType::Number, {}, 0);
@@ -1752,6 +1767,56 @@ llvm::Value *LLVMCodeBuilder::getListItem(const LLVMListPtr &listPtr, llvm::Valu
17521767
return m_builder.CreateGEP(m_valueDataType, m_builder.CreateLoad(m_valueDataType->getPointerTo(), listPtr.dataPtr), index);
17531768
}
17541769

1770+
llvm::Value *LLVMCodeBuilder::getListItemIndex(const LLVMListPtr &listPtr, LLVMRegisterPtr item, llvm::Function *func)
1771+
{
1772+
llvm::Value *size = m_builder.CreateLoad(m_builder.getInt64Ty(), listPtr.sizePtr);
1773+
llvm::BasicBlock *condBlock = llvm::BasicBlock::Create(m_ctx, "", func);
1774+
llvm::BasicBlock *bodyBlock = llvm::BasicBlock::Create(m_ctx, "", func);
1775+
llvm::BasicBlock *cmpIfBlock = llvm::BasicBlock::Create(m_ctx, "", func);
1776+
llvm::BasicBlock *cmpElseBlock = llvm::BasicBlock::Create(m_ctx, "", func);
1777+
llvm::BasicBlock *notFoundBlock = llvm::BasicBlock::Create(m_ctx, "", func);
1778+
llvm::BasicBlock *nextBlock = llvm::BasicBlock::Create(m_ctx, "", func);
1779+
1780+
// index = 0
1781+
llvm::Value *index = m_builder.CreateAlloca(m_builder.getInt64Ty());
1782+
m_builder.CreateStore(m_builder.getInt64(0), index);
1783+
m_builder.CreateBr(condBlock);
1784+
1785+
// while (index < size)
1786+
m_builder.SetInsertPoint(condBlock);
1787+
llvm::Value *cond = m_builder.CreateICmpULT(m_builder.CreateLoad(m_builder.getInt64Ty(), index), size);
1788+
m_builder.CreateCondBr(cond, bodyBlock, notFoundBlock);
1789+
1790+
// if (list[index] == item)
1791+
m_builder.SetInsertPoint(bodyBlock);
1792+
LLVMRegisterPtr currentItem = std::make_shared<LLVMRegister>(listPtr.type);
1793+
currentItem->isRawValue = false;
1794+
currentItem->value = getListItem(listPtr, m_builder.CreateLoad(m_builder.getInt64Ty(), index), func);
1795+
llvm::Value *cmp = createComparison(currentItem, item, Comparison::EQ);
1796+
m_builder.CreateCondBr(cmp, cmpIfBlock, cmpElseBlock);
1797+
1798+
// goto nextBlock
1799+
m_builder.SetInsertPoint(cmpIfBlock);
1800+
m_builder.CreateBr(nextBlock);
1801+
1802+
// else index++
1803+
m_builder.SetInsertPoint(cmpElseBlock);
1804+
m_builder.CreateStore(m_builder.CreateAdd(m_builder.CreateLoad(m_builder.getInt64Ty(), index), m_builder.getInt64(1)), index);
1805+
m_builder.CreateBr(condBlock);
1806+
1807+
// notFoundBlock:
1808+
// index = -1
1809+
// goto nextBlock
1810+
m_builder.SetInsertPoint(notFoundBlock);
1811+
m_builder.CreateStore(llvm::ConstantInt::get(llvm::Type::getInt64Ty(m_ctx), -1, true), index);
1812+
m_builder.CreateBr(nextBlock);
1813+
1814+
// nextBlock:
1815+
m_builder.SetInsertPoint(nextBlock);
1816+
1817+
return m_builder.CreateSIToFP(m_builder.CreateLoad(m_builder.getInt64Ty(), index), m_builder.getDoubleTy());
1818+
}
1819+
17551820
llvm::Value *LLVMCodeBuilder::createValue(LLVMRegisterPtr reg)
17561821
{
17571822
if (reg->isConstValue) {

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class LLVMCodeBuilder : public ICodeBuilder
3030
void addVariableValue(Variable *variable) override;
3131
void addListContents(List *list) override;
3232
void addListItem(List *list) override;
33+
void addListItemIndex(List *list) override;
3334
void addListSize(List *list) override;
3435

3536
void createAdd() override;
@@ -123,6 +124,7 @@ class LLVMCodeBuilder : public ICodeBuilder
123124
void createValueCopy(llvm::Value *source, llvm::Value *target);
124125
void copyStructField(llvm::Value *source, llvm::Value *target, int index, llvm::StructType *structType, llvm::Type *fieldType);
125126
llvm::Value *getListItem(const LLVMListPtr &listPtr, llvm::Value *index, llvm::Function *func);
127+
llvm::Value *getListItemIndex(const LLVMListPtr &listPtr, LLVMRegisterPtr item, llvm::Function *func);
126128
llvm::Value *createValue(LLVMRegisterPtr reg);
127129
llvm::Value *createComparison(LLVMRegisterPtr arg1, LLVMRegisterPtr arg2, Comparison type);
128130

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ struct LLVMInstruction
4949
ListReplace,
5050
GetListItem,
5151
GetListSize,
52+
GetListItemIndex,
5253
Yield,
5354
BeginIf,
5455
BeginElse,

test/dev/llvm/llvmcodebuilder_test.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,6 +2304,97 @@ TEST_F(LLVMCodeBuilderTest, GetListSize)
23042304
ASSERT_EQ(localList->toString(), "Lorem ipsum dolor sit");
23052305
}
23062306

2307+
TEST_F(LLVMCodeBuilderTest, GetListItemIndex)
2308+
{
2309+
EngineMock engine;
2310+
Stage stage;
2311+
Sprite sprite;
2312+
sprite.setEngine(&engine);
2313+
EXPECT_CALL(engine, stage()).WillRepeatedly(Return(&stage));
2314+
2315+
auto globalList = std::make_shared<List>("", "");
2316+
stage.addList(globalList);
2317+
2318+
auto localList = std::make_shared<List>("", "");
2319+
sprite.addList(localList);
2320+
2321+
globalList->append(1);
2322+
globalList->append(2);
2323+
globalList->append(3);
2324+
2325+
localList->append("Lorem");
2326+
localList->append("ipsum");
2327+
localList->append("dolor");
2328+
localList->append("sit");
2329+
2330+
createBuilder(&sprite, true);
2331+
2332+
m_builder->addConstValue(2);
2333+
m_builder->addListItemIndex(globalList.get());
2334+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
2335+
2336+
m_builder->addConstValue(1);
2337+
m_builder->addListItemIndex(globalList.get());
2338+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
2339+
2340+
m_builder->addConstValue(0);
2341+
m_builder->addListItemIndex(globalList.get());
2342+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
2343+
2344+
m_builder->addConstValue(1);
2345+
m_builder->addConstValue("test");
2346+
m_builder->createListReplace(globalList.get());
2347+
2348+
m_builder->addConstValue(2);
2349+
m_builder->addListItemIndex(globalList.get());
2350+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
2351+
2352+
m_builder->addConstValue(1);
2353+
m_builder->addListItemIndex(globalList.get());
2354+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
2355+
2356+
m_builder->addConstValue("test");
2357+
m_builder->addListItemIndex(globalList.get());
2358+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
2359+
2360+
m_builder->addConstValue("abc");
2361+
m_builder->addListItemIndex(globalList.get());
2362+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
2363+
2364+
m_builder->addConstValue("doLor");
2365+
m_builder->addListItemIndex(localList.get());
2366+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
2367+
2368+
m_builder->addConstValue(true);
2369+
m_builder->addListItemIndex(localList.get());
2370+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
2371+
2372+
m_builder->addConstValue("site");
2373+
m_builder->addListItemIndex(localList.get());
2374+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
2375+
2376+
static const std::string expected =
2377+
"1\n"
2378+
"0\n"
2379+
"-1\n"
2380+
"-1\n"
2381+
"0\n"
2382+
"1\n"
2383+
"-1\n"
2384+
"2\n"
2385+
"-1\n"
2386+
"-1\n";
2387+
2388+
auto code = m_builder->finalize();
2389+
auto ctx = code->createExecutionContext(&sprite);
2390+
testing::internal::CaptureStdout();
2391+
code->run(ctx.get());
2392+
ASSERT_EQ(testing::internal::GetCapturedStdout(), expected);
2393+
2394+
ASSERT_EQ(globalList->toString(), "1 test 3");
2395+
ASSERT_EQ(localList->toString(), "Lorem ipsum dolor sit");
2396+
}
2397+
23072398
TEST_F(LLVMCodeBuilderTest, Yield)
23082399
{
23092400
auto build = [this]() {

test/mocks/codebuildermock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class CodeBuilderMock : public ICodeBuilder
1414
MOCK_METHOD(void, addVariableValue, (Variable *), (override));
1515
MOCK_METHOD(void, addListContents, (List *), (override));
1616
MOCK_METHOD(void, addListItem, (List *), (override));
17+
MOCK_METHOD(void, addListItemIndex, (List *), (override));
1718
MOCK_METHOD(void, addListSize, (List *), (override));
1819

1920
MOCK_METHOD(void, createAdd, (), (override));

0 commit comments

Comments
 (0)