Skip to content

Commit 04c305a

Browse files
committed
Rewrite list type assumptions
1 parent a47a612 commit 04c305a

File tree

1 file changed

+45
-37
lines changed
  • src/engine/internal/llvm/instructions

1 file changed

+45
-37
lines changed

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

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -474,52 +474,60 @@ void Lists::createListTypeAssumption(const LLVMListPtr &listPtr, llvm::Value *ty
474474
llvm::Value *boolType = m_builder.getInt32(static_cast<uint32_t>(ValueType::Bool));
475475
llvm::Value *stringType = m_builder.getInt32(static_cast<uint32_t>(ValueType::String));
476476

477-
// Number
478-
llvm::BasicBlock *noNumberBlock = llvm::BasicBlock::Create(m_utils.llvmCtx(), "listTypeAssumption.noNumber", m_utils.function());
479-
llvm::BasicBlock *afterNoNumberBlock = llvm::BasicBlock::Create(m_utils.llvmCtx(), "listTypeAssumption.afterNoNumber", m_utils.function());
480-
m_builder.CreateCondBr(hasNumber, afterNoNumberBlock, noNumberBlock);
477+
// Create assumptions
478+
llvm::BasicBlock *outOfRangeBlock = llvm::BasicBlock::Create(m_utils.llvmCtx(), "outOfRange", m_utils.function());
479+
llvm::BasicBlock *inRangeBlock = llvm::BasicBlock::Create(m_utils.llvmCtx(), "inRange", m_utils.function());
480+
llvm::BasicBlock *afterBlock = llvm::BasicBlock::Create(m_utils.llvmCtx(), "afterAssume", m_utils.function());
481481

482-
m_builder.SetInsertPoint(noNumberBlock);
483-
llvm::Value *isNotNumber = m_builder.CreateICmpNE(type, numberType);
484-
m_builder.CreateCall(assumeIntrinsic, isNotNumber);
485-
m_builder.CreateBr(afterNoNumberBlock);
482+
m_builder.CreateCondBr(inRange, inRangeBlock, outOfRangeBlock);
486483

487-
m_builder.SetInsertPoint(afterNoNumberBlock);
484+
// In-range assumptions
485+
m_builder.SetInsertPoint(inRangeBlock);
488486

489-
// Bool
490-
llvm::BasicBlock *noBoolBlock = llvm::BasicBlock::Create(m_utils.llvmCtx(), "listTypeAssumption.noBool", m_utils.function());
491-
llvm::BasicBlock *afterNoBoolBlock = llvm::BasicBlock::Create(m_utils.llvmCtx(), "listTypeAssumption.afterNoBool", m_utils.function());
492-
m_builder.CreateCondBr(hasBool, afterNoBoolBlock, noBoolBlock);
487+
auto assume = [&](llvm::Value *cond) { m_builder.CreateCall(assumeIntrinsic, cond); };
493488

494-
m_builder.SetInsertPoint(noBoolBlock);
495-
llvm::Value *isNotBool = m_builder.CreateICmpNE(type, boolType);
496-
m_builder.CreateCall(assumeIntrinsic, isNotBool);
497-
m_builder.CreateBr(afterNoBoolBlock);
489+
llvm::Value *notNumber = m_builder.CreateNot(hasNumber);
490+
llvm::Value *notBool = m_builder.CreateNot(hasBool);
491+
llvm::Value *notString = m_builder.CreateNot(hasString);
498492

499-
m_builder.SetInsertPoint(afterNoBoolBlock);
493+
// if (!hasBool && !hasString) type == Number
494+
llvm::Value *cond1 = m_builder.CreateAnd(notBool, notString);
495+
llvm::Value *assume1 = m_builder.CreateICmpEQ(type, numberType);
496+
assume(m_builder.CreateSelect(cond1, assume1, m_builder.getInt1(true)));
500497

501-
// String
502-
llvm::BasicBlock *noStringBlock = llvm::BasicBlock::Create(m_utils.llvmCtx(), "listTypeAssumption.noString", m_utils.function());
503-
llvm::BasicBlock *afterNoStringBlock = llvm::BasicBlock::Create(m_utils.llvmCtx(), "listTypeAssumption.afterNoString", m_utils.function());
498+
// else if (!hasNumber && !hasString) type == Bool
499+
llvm::Value *cond2 = m_builder.CreateAnd(notNumber, notString);
500+
llvm::Value *assume2 = m_builder.CreateICmpEQ(type, boolType);
501+
assume(m_builder.CreateSelect(cond2, assume2, m_builder.getInt1(true)));
504502

505-
if (inRange)
506-
m_builder.CreateCondBr(m_builder.CreateAnd(m_builder.CreateNot(hasString), inRange), noStringBlock, afterNoStringBlock);
507-
else
508-
m_builder.CreateCondBr(hasString, afterNoStringBlock, noStringBlock);
503+
// else if (!hasNumber && !hasBool) type == String
504+
llvm::Value *cond3 = m_builder.CreateAnd(notNumber, notBool);
505+
llvm::Value *assume3 = m_builder.CreateICmpEQ(type, stringType);
506+
assume(m_builder.CreateSelect(cond3, assume3, m_builder.getInt1(true)));
509507

510-
m_builder.SetInsertPoint(noStringBlock);
511-
llvm::Value *isNotString = m_builder.CreateICmpNE(type, stringType);
512-
m_builder.CreateCall(assumeIntrinsic, isNotString);
513-
m_builder.CreateBr(afterNoStringBlock);
508+
// else if (!hasBool) type == Number || type == String
509+
llvm::Value *cond4 = notBool;
510+
llvm::Value *assume4 = m_builder.CreateOr(m_builder.CreateICmpEQ(type, numberType), m_builder.CreateICmpEQ(type, stringType));
511+
assume(m_builder.CreateSelect(cond4, assume4, m_builder.getInt1(true)));
514512

515-
m_builder.SetInsertPoint(afterNoStringBlock);
513+
// else if (!hasNumber) type == Bool || type == String
514+
llvm::Value *cond5 = notNumber;
515+
llvm::Value *assume5 = m_builder.CreateOr(m_builder.CreateICmpEQ(type, boolType), m_builder.CreateICmpEQ(type, stringType));
516+
assume(m_builder.CreateSelect(cond5, assume5, m_builder.getInt1(true)));
516517

517-
if (inRange) {
518-
llvm::Value *stringType = m_builder.getInt32(static_cast<uint32_t>(ValueType::String));
519-
llvm::Value *canNotBeString = m_builder.CreateNot(hasString);
520-
llvm::Value *isString = m_builder.CreateICmpEQ(type, stringType);
521-
llvm::Value *impossible = m_builder.CreateAnd(m_builder.CreateAnd(inRange, canNotBeString), isString);
522-
m_builder.CreateCall(assumeIntrinsic, m_builder.CreateNot(impossible));
523-
}
518+
// else if (!hasString) type == Number || type == Bool
519+
llvm::Value *cond6 = notString;
520+
llvm::Value *assume6 = m_builder.CreateOr(m_builder.CreateICmpEQ(type, numberType), m_builder.CreateICmpEQ(type, boolType));
521+
assume(m_builder.CreateSelect(cond6, assume6, m_builder.getInt1(true)));
522+
523+
m_builder.CreateBr(afterBlock);
524+
525+
// Out-of-range: always string
526+
m_builder.SetInsertPoint(outOfRangeBlock);
527+
llvm::Value *isString = m_builder.CreateICmpEQ(type, stringType);
528+
assume(isString);
529+
m_builder.CreateBr(afterBlock);
530+
531+
m_builder.SetInsertPoint(afterBlock);
524532
}
525533
}

0 commit comments

Comments
 (0)