@@ -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+
932947void 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+
17551820llvm::Value *LLVMCodeBuilder::createValue (LLVMRegisterPtr reg)
17561821{
17571822 if (reg->isConstValue ) {
0 commit comments