@@ -100,17 +100,16 @@ LLVMInstruction *Lists::buildRemoveListItem(LLVMInstruction *ins)
100
100
LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
101
101
102
102
// 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" );
106
105
107
106
llvm::BasicBlock *removeBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
108
107
llvm::BasicBlock *nextBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
109
108
m_builder.CreateCondBr (inRange, removeBlock, nextBlock);
110
109
111
110
// Remove
112
111
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 });
114
113
115
114
if (listPtr.size ) {
116
115
// Update size
@@ -144,17 +143,21 @@ LLVMInstruction *Lists::buildAppendToList(LLVMInstruction *ins)
144
143
llvm::BasicBlock *nextBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
145
144
m_builder.CreateCondBr (isAllocated, ifBlock, elseBlock);
146
145
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
+
147
150
// If there's enough space, use the allocated memory
148
151
m_builder.SetInsertPoint (ifBlock);
149
152
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);
151
154
m_builder.CreateStore (m_builder.CreateAdd (size, m_builder.getInt64 (1 )), listPtr.sizePtr ); // update size stored in *sizePtr
152
155
m_builder.CreateBr (nextBlock);
153
156
154
157
// Otherwise call appendEmpty()
155
158
m_builder.SetInsertPoint (elseBlock);
156
159
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);
158
161
m_builder.CreateBr (nextBlock);
159
162
160
163
m_builder.SetInsertPoint (nextBlock);
@@ -182,18 +185,21 @@ LLVMInstruction *Lists::buildInsertToList(LLVMInstruction *ins)
182
185
LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
183
186
184
187
// 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 );
188
190
189
191
llvm::BasicBlock *insertBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
190
192
llvm::BasicBlock *nextBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
191
193
m_builder.CreateCondBr (inRange, insertBlock, nextBlock);
192
194
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
+
193
199
// Insert
194
200
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);
197
203
198
204
if (listPtr.size ) {
199
205
// Update size
@@ -227,9 +233,8 @@ LLVMInstruction *Lists::buildListReplace(LLVMInstruction *ins)
227
233
Compiler::StaticType listType = ins->targetType ;
228
234
229
235
// 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" );
233
238
234
239
llvm::BasicBlock *replaceBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
235
240
llvm::BasicBlock *nextBlock = llvm::BasicBlock::Create (llvmCtx, " " , function);
@@ -238,13 +243,17 @@ LLVMInstruction *Lists::buildListReplace(LLVMInstruction *ins)
238
243
// Replace
239
244
m_builder.SetInsertPoint (replaceBlock);
240
245
241
- llvm::Value *itemPtr = m_utils.getListItem (listPtr, indexInt );
246
+ llvm::Value *itemPtr = m_utils.getListItem (listPtr, index );
242
247
llvm::Value *typePtr = m_utils.getValueTypePtr (itemPtr);
243
248
llvm::Value *loadedType = m_builder.CreateLoad (m_builder.getInt32Ty (), typePtr);
244
249
llvm::Value *typeVar = createListTypeVar (listPtr, loadedType);
245
250
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
+
246
255
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);
248
257
249
258
// Value store may change type, make sure to update it
250
259
loadedType = m_builder.CreateLoad (m_builder.getInt32Ty (), typeVar);
@@ -285,9 +294,8 @@ LLVMInstruction *Lists::buildGetListItem(LLVMInstruction *ins)
285
294
LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
286
295
287
296
// 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" );
291
299
292
300
llvm::BasicBlock *inRangeBlock = llvm::BasicBlock::Create (llvmCtx, " getListItem.inRange" , function);
293
301
llvm::BasicBlock *outOfRangeBlock = llvm::BasicBlock::Create (llvmCtx, " getListItem.outOfRange" , function);
@@ -296,7 +304,7 @@ LLVMInstruction *Lists::buildGetListItem(LLVMInstruction *ins)
296
304
297
305
// In range
298
306
m_builder.SetInsertPoint (inRangeBlock);
299
- llvm::Value *itemPtr = m_utils.getListItem (listPtr, indexInt );
307
+ llvm::Value *itemPtr = m_utils.getListItem (listPtr, index );
300
308
llvm::Value *itemType = m_builder.CreateLoad (m_builder.getInt32Ty (), m_utils.getValueTypePtr (itemPtr));
301
309
m_builder.CreateBr (nextBlock);
302
310
@@ -332,6 +340,8 @@ LLVMInstruction *Lists::buildGetListSize(LLVMInstruction *ins)
332
340
const LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
333
341
llvm::Value *size = m_utils.getListSize (listPtr);
334
342
ins->functionReturnReg ->value = m_builder.CreateUIToFP (size, m_builder.getDoubleTy ());
343
+ ins->functionReturnReg ->isInt = m_builder.getInt1 (true );
344
+ ins->functionReturnReg ->intValue = size;
335
345
336
346
return ins->next ;
337
347
}
@@ -362,31 +372,14 @@ LLVMInstruction *Lists::buildListContainsItem(LLVMInstruction *ins)
362
372
return ins->next ;
363
373
}
364
374
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)
380
376
{
381
377
llvm::Function *expectIntrinsic = llvm::Intrinsic::getDeclaration (m_utils.module (), llvm::Intrinsic::expect, m_builder.getInt1Ty ());
382
378
379
+ llvm::Value *min = llvm::ConstantInt::get (m_builder.getInt64Ty (), 0 , true );
383
380
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);
390
383
391
384
// Tell the optimizer that indices in range are more common
392
385
return m_builder.CreateCall (expectIntrinsic, { inRange, m_builder.getInt1 (true ) });
0 commit comments