Skip to content

Commit 119c4a5

Browse files
committed
Add initial LLVM integer value support
1 parent 6173c34 commit 119c4a5

File tree

8 files changed

+198
-122
lines changed

8 files changed

+198
-122
lines changed

src/engine/internal/llvm/instructions/lists.cpp

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -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) });

src/engine/internal/llvm/instructions/lists.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ class Lists : public InstructionGroup
3434
LLVMInstruction *buildGetListItemIndex(LLVMInstruction *ins);
3535
LLVMInstruction *buildListContainsItem(LLVMInstruction *ins);
3636

37-
llvm::Value *getIndex(const LLVMListPtr &listPtr, llvm::Value *indexDouble);
38-
llvm::Value *createSizeRangeCheck(const LLVMListPtr &listPtr, llvm::Value *indexInt, const std::string &name, bool includeSize = false);
37+
llvm::Value *createIndexRangeCheck(const LLVMListPtr &listPtr, llvm::Value *index, const std::string &name, bool includeSize = false);
3938

4039
void createListTypeUpdate(const LLVMListPtr &listPtr, const LLVMRegister *newValue, Compiler::StaticType newValueType);
4140
llvm::Value *createListTypeVar(const LLVMListPtr &listPtr, llvm::Value *type);

src/engine/internal/llvm/instructions/variables.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ LLVMInstruction *Variables::buildWriteVariable(LLVMInstruction *ins)
112112
Compiler::StaticType argType = m_utils.optimizeRegisterType(arg.second);
113113
LLVMVariablePtr &varPtr = m_utils.variablePtr(ins->targetVariable);
114114

115-
m_utils.createValueStore(varPtr.stackPtr, m_utils.getValueTypePtr(varPtr.stackPtr), arg.second, ins->targetType, argType);
115+
m_utils.createValueStore(varPtr.stackPtr, m_utils.getValueTypePtr(varPtr.stackPtr), varPtr.isInt, varPtr.intValue, arg.second, ins->targetType, argType);
116116
return ins->next;
117117
}
118118

@@ -122,5 +122,7 @@ LLVMInstruction *Variables::buildReadVariable(LLVMInstruction *ins)
122122
LLVMVariablePtr &varPtr = m_utils.variablePtr(ins->targetVariable);
123123

124124
ins->functionReturnReg->value = varPtr.stackPtr;
125+
ins->functionReturnReg->isInt = m_builder.CreateLoad(m_builder.getInt1Ty(), varPtr.isInt);
126+
ins->functionReturnReg->intValue = m_builder.CreateLoad(m_builder.getInt64Ty(), varPtr.intValue);
125127
return ins->next;
126128
}

0 commit comments

Comments
 (0)