@@ -100,17 +100,16 @@ LLVMInstruction *Lists::buildRemoveListItem(LLVMInstruction *ins)
100100 LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
101101
102102 // Range check
103- llvm::Value *indexDouble = m_utils.castValue (arg.second , arg.first );
104- llvm::Value *indexInt = getIndex (listPtr, indexDouble);
105- llvm::Value *inRange = createSizeRangeCheck (listPtr, indexInt, " removeListItem.indexInRange" );
103+ llvm::Value *index = m_utils.castValue (arg.second , Compiler::StaticType::Number, LLVMBuildUtils::NumberType::Int);
104+ llvm::Value *inRange = createIndexRangeCheck (listPtr, index, " removeListItem.indexInRange" );
106105
107106 llvm::BasicBlock *removeBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
108107 llvm::BasicBlock *nextBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
109108 m_builder.CreateCondBr (inRange, removeBlock, nextBlock);
110109
111110 // Remove
112111 m_builder.SetInsertPoint (removeBlock);
113- m_builder.CreateCall (m_utils.functions ().resolve_list_remove (), { listPtr.ptr , indexInt });
112+ m_builder.CreateCall (m_utils.functions ().resolve_list_remove (), { listPtr.ptr , index });
114113
115114 if (listPtr.size ) {
116115 // Update size
@@ -144,17 +143,21 @@ LLVMInstruction *Lists::buildAppendToList(LLVMInstruction *ins)
144143 llvm::BasicBlock *nextBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
145144 m_builder.CreateCondBr (isAllocated, ifBlock, elseBlock);
146145
146+ // TODO: Add integer support for lists
147+ llvm::Value *isIntVar = m_utils.addAlloca (m_builder.getInt1Ty ());
148+ llvm::Value *intVar = m_utils.addAlloca (m_builder.getInt64Ty ());
149+
147150 // If there's enough space, use the allocated memory
148151 m_builder.SetInsertPoint (ifBlock);
149152 llvm::Value *itemPtr = m_utils.getListItem (listPtr, size);
150- m_utils.createValueStore (itemPtr, m_utils.getValueTypePtr (itemPtr), arg.second , type);
153+ m_utils.createValueStore (itemPtr, m_utils.getValueTypePtr (itemPtr), isIntVar, intVar, arg.second , type);
151154 m_builder.CreateStore (m_builder.CreateAdd (size, m_builder.getInt64 (1 )), listPtr.sizePtr ); // update size stored in *sizePtr
152155 m_builder.CreateBr (nextBlock);
153156
154157 // Otherwise call appendEmpty()
155158 m_builder.SetInsertPoint (elseBlock);
156159 itemPtr = m_builder.CreateCall (m_utils.functions ().resolve_list_append_empty (), listPtr.ptr );
157- m_utils.createValueStore (itemPtr, m_utils.getValueTypePtr (itemPtr), arg.second , type);
160+ m_utils.createValueStore (itemPtr, m_utils.getValueTypePtr (itemPtr), isIntVar, intVar, arg.second , type);
158161 m_builder.CreateBr (nextBlock);
159162
160163 m_builder.SetInsertPoint (nextBlock);
@@ -182,18 +185,21 @@ LLVMInstruction *Lists::buildInsertToList(LLVMInstruction *ins)
182185 LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
183186
184187 // Range check
185- llvm::Value *indexDouble = m_utils.castValue (indexArg.second , indexArg.first );
186- llvm::Value *indexInt = getIndex (listPtr, indexDouble);
187- llvm::Value *inRange = createSizeRangeCheck (listPtr, indexInt, " insertToList.indexInRange" , true );
188+ llvm::Value *index = m_utils.castValue (indexArg.second , Compiler::StaticType::Number, LLVMBuildUtils::NumberType::Int);
189+ llvm::Value *inRange = createIndexRangeCheck (listPtr, index, " insertToList.indexInRange" , true );
188190
189191 llvm::BasicBlock *insertBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
190192 llvm::BasicBlock *nextBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
191193 m_builder.CreateCondBr (inRange, insertBlock, nextBlock);
192194
195+ // TODO: Add integer support for lists
196+ llvm::Value *isIntVar = m_utils.addAlloca (m_builder.getInt1Ty ());
197+ llvm::Value *intVar = m_utils.addAlloca (m_builder.getInt64Ty ());
198+
193199 // Insert
194200 m_builder.SetInsertPoint (insertBlock);
195- llvm::Value *itemPtr = m_builder.CreateCall (m_utils.functions ().resolve_list_insert_empty (), { listPtr.ptr , indexInt });
196- m_utils.createValueStore (itemPtr, m_utils.getValueTypePtr (itemPtr), valueArg.second , type);
201+ llvm::Value *itemPtr = m_builder.CreateCall (m_utils.functions ().resolve_list_insert_empty (), { listPtr.ptr , index });
202+ m_utils.createValueStore (itemPtr, m_utils.getValueTypePtr (itemPtr), isIntVar, intVar, valueArg.second , type);
197203
198204 if (listPtr.size ) {
199205 // Update size
@@ -227,9 +233,8 @@ LLVMInstruction *Lists::buildListReplace(LLVMInstruction *ins)
227233 Compiler::StaticType listType = ins->targetType ;
228234
229235 // Range check
230- llvm::Value *indexDouble = m_utils.castValue (indexArg.second , indexArg.first );
231- llvm::Value *indexInt = getIndex (listPtr, indexDouble);
232- llvm::Value *inRange = createSizeRangeCheck (listPtr, indexInt, " listReplace.indexInRange" );
236+ llvm::Value *index = m_utils.castValue (indexArg.second , Compiler::StaticType::Number, LLVMBuildUtils::NumberType::Int);
237+ llvm::Value *inRange = createIndexRangeCheck (listPtr, index, " listReplace.indexInRange" );
233238
234239 llvm::BasicBlock *replaceBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
235240 llvm::BasicBlock *nextBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
@@ -238,13 +243,17 @@ LLVMInstruction *Lists::buildListReplace(LLVMInstruction *ins)
238243 // Replace
239244 m_builder.SetInsertPoint (replaceBlock);
240245
241- llvm::Value *itemPtr = m_utils.getListItem (listPtr, indexInt );
246+ llvm::Value *itemPtr = m_utils.getListItem (listPtr, index );
242247 llvm::Value *typePtr = m_utils.getValueTypePtr (itemPtr);
243248 llvm::Value *loadedType = m_builder.CreateLoad (m_builder.getInt32Ty (), typePtr);
244249 llvm::Value *typeVar = createListTypeVar (listPtr, loadedType);
245250
251+ // TODO: Add integer support for lists
252+ llvm::Value *isIntVar = m_utils.addAlloca (m_builder.getInt1Ty ());
253+ llvm::Value *intVar = m_utils.addAlloca (m_builder.getInt64Ty ());
254+
246255 createListTypeAssumption (listPtr, typeVar, ins->targetType );
247- m_utils.createValueStore (itemPtr, typeVar, valueArg.second , listType, type);
256+ m_utils.createValueStore (itemPtr, typeVar, isIntVar, intVar, valueArg.second , listType, type);
248257
249258 // Value store may change type, make sure to update it
250259 loadedType = m_builder.CreateLoad (m_builder.getInt32Ty (), typeVar);
@@ -285,9 +294,8 @@ LLVMInstruction *Lists::buildGetListItem(LLVMInstruction *ins)
285294 LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
286295
287296 // Range check
288- llvm::Value *indexDouble = m_utils.castValue (arg.second , arg.first );
289- llvm::Value *indexInt = getIndex (listPtr, indexDouble);
290- llvm::Value *inRange = createSizeRangeCheck (listPtr, indexInt, " getListItem.indexInRange" );
297+ llvm::Value *index = m_utils.castValue (arg.second , Compiler::StaticType::Number, LLVMBuildUtils::NumberType::Int);
298+ llvm::Value *inRange = createIndexRangeCheck (listPtr, index, " getListItem.indexInRange" );
291299
292300 llvm::BasicBlock *inRangeBlock = llvm::BasicBlock::Create (llvmCtx, " getListItem.inRange" , function);
293301 llvm::BasicBlock *outOfRangeBlock = llvm::BasicBlock::Create (llvmCtx, " getListItem.outOfRange" , function);
@@ -296,7 +304,7 @@ LLVMInstruction *Lists::buildGetListItem(LLVMInstruction *ins)
296304
297305 // In range
298306 m_builder.SetInsertPoint (inRangeBlock);
299- llvm::Value *itemPtr = m_utils.getListItem (listPtr, indexInt );
307+ llvm::Value *itemPtr = m_utils.getListItem (listPtr, index );
300308 llvm::Value *itemType = m_builder.CreateLoad (m_builder.getInt32Ty (), m_utils.getValueTypePtr (itemPtr));
301309 m_builder.CreateBr (nextBlock);
302310
@@ -332,6 +340,8 @@ LLVMInstruction *Lists::buildGetListSize(LLVMInstruction *ins)
332340 const LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
333341 llvm::Value *size = m_utils.getListSize (listPtr);
334342 ins->functionReturnReg ->value = m_builder.CreateUIToFP (size, m_builder.getDoubleTy ());
343+ ins->functionReturnReg ->isInt = m_builder.getInt1 (true );
344+ ins->functionReturnReg ->intValue = size;
335345
336346 return ins->next ;
337347}
@@ -362,31 +372,14 @@ LLVMInstruction *Lists::buildListContainsItem(LLVMInstruction *ins)
362372 return ins->next ;
363373}
364374
365- llvm::Value *Lists::getIndex (const LLVMListPtr &listPtr, llvm::Value *indexDouble)
366- {
367- llvm::Function *expectIntrinsic = llvm::Intrinsic::getDeclaration (m_utils.module (), llvm::Intrinsic::expect, m_builder.getInt64Ty ());
368-
369- llvm::Value *zero = llvm::ConstantFP::get (m_utils.llvmCtx (), llvm::APFloat (0.0 ));
370- llvm::Value *isNegative = m_builder.CreateFCmpOLT (indexDouble, zero, " listIndex.isNegative" );
371- llvm::Value *intMax = llvm::ConstantInt::get (m_builder.getInt64Ty (), INT64_MAX);
372- llvm::Value *intIndex = m_builder.CreateFPToUI (indexDouble, m_builder.getInt64Ty (), " listIndex.int" );
373-
374- // Tell the optimizer that negative indices are uncommon
375- llvm::Value *index = m_builder.CreateSelect (isNegative, intMax, intIndex);
376- return m_builder.CreateCall (expectIntrinsic, { index, intIndex });
377- }
378-
379- llvm::Value *Lists::createSizeRangeCheck (const LLVMListPtr &listPtr, llvm::Value *indexInt, const std::string &name, bool includeSize)
375+ llvm::Value *Lists::createIndexRangeCheck (const LLVMListPtr &listPtr, llvm::Value *index, const std::string &name, bool includeSize)
380376{
381377 llvm::Function *expectIntrinsic = llvm::Intrinsic::getDeclaration (m_utils.module (), llvm::Intrinsic::expect, m_builder.getInt1Ty ());
382378
379+ llvm::Value *min = llvm::ConstantInt::get (m_builder.getInt64Ty (), 0 , true );
383380 llvm::Value *size = m_utils.getListSize (listPtr);
384- llvm::Value *inRange;
385-
386- if (includeSize)
387- inRange = m_builder.CreateICmpULE (indexInt, size, name);
388- else
389- inRange = m_builder.CreateICmpULT (indexInt, size, name);
381+ llvm::Value *sizeCheck = includeSize ? m_builder.CreateICmpSLE (index, size) : m_builder.CreateICmpSLT (index, size);
382+ llvm::Value *inRange = m_builder.CreateAnd (m_builder.CreateICmpSGE (index, min), sizeCheck, name);
390383
391384 // Tell the optimizer that indices in range are more common
392385 return m_builder.CreateCall (expectIntrinsic, { inRange, m_builder.getInt1 (true ) });
0 commit comments