Skip to content

Commit 6a5b537

Browse files
committed
LLVMCodeBuilder: Store loop condition info in instructions
1 parent 95867e7 commit 6a5b537

File tree

3 files changed

+43
-30
lines changed

3 files changed

+43
-30
lines changed

src/engine/internal/llvm/llvmcodebuilder.cpp

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,7 +1227,7 @@ CompilerValue *LLVMCodeBuilder::addFunctionCall(const std::string &functionName,
12271227
{
12281228
assert(argTypes.size() == args.size());
12291229

1230-
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, currentLoopScope());
1230+
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, currentLoopScope(), m_loopCondition);
12311231
ins->functionName = functionName;
12321232

12331233
for (size_t i = 0; i < args.size(); i++)
@@ -1278,7 +1278,7 @@ CompilerValue *LLVMCodeBuilder::addLocalVariableValue(CompilerLocalVariable *var
12781278

12791279
CompilerValue *LLVMCodeBuilder::addVariableValue(Variable *variable)
12801280
{
1281-
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::ReadVariable, currentLoopScope());
1281+
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::ReadVariable, currentLoopScope(), m_loopCondition);
12821282
ins->workVariable = variable;
12831283

12841284
if (m_variablePtrs.find(variable) == m_variablePtrs.cend())
@@ -1295,7 +1295,7 @@ CompilerValue *LLVMCodeBuilder::addVariableValue(Variable *variable)
12951295

12961296
CompilerValue *LLVMCodeBuilder::addListContents(List *list)
12971297
{
1298-
LLVMInstruction ins(LLVMInstruction::Type::GetListContents, currentLoopScope());
1298+
LLVMInstruction ins(LLVMInstruction::Type::GetListContents, currentLoopScope(), m_loopCondition);
12991299
ins.workList = list;
13001300

13011301
if (m_listPtrs.find(list) == m_listPtrs.cend())
@@ -1306,7 +1306,7 @@ CompilerValue *LLVMCodeBuilder::addListContents(List *list)
13061306

13071307
CompilerValue *LLVMCodeBuilder::addListItem(List *list, CompilerValue *index)
13081308
{
1309-
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::GetListItem, currentLoopScope());
1309+
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::GetListItem, currentLoopScope(), m_loopCondition);
13101310
ins->workList = list;
13111311

13121312
if (m_listPtrs.find(list) == m_listPtrs.cend())
@@ -1324,7 +1324,7 @@ CompilerValue *LLVMCodeBuilder::addListItem(List *list, CompilerValue *index)
13241324

13251325
CompilerValue *LLVMCodeBuilder::addListItemIndex(List *list, CompilerValue *item)
13261326
{
1327-
LLVMInstruction ins(LLVMInstruction::Type::GetListItemIndex, currentLoopScope());
1327+
LLVMInstruction ins(LLVMInstruction::Type::GetListItemIndex, currentLoopScope(), m_loopCondition);
13281328
ins.workList = list;
13291329

13301330
if (m_listPtrs.find(list) == m_listPtrs.cend())
@@ -1335,7 +1335,7 @@ CompilerValue *LLVMCodeBuilder::addListItemIndex(List *list, CompilerValue *item
13351335

13361336
CompilerValue *LLVMCodeBuilder::addListContains(List *list, CompilerValue *item)
13371337
{
1338-
LLVMInstruction ins(LLVMInstruction::Type::ListContainsItem, currentLoopScope());
1338+
LLVMInstruction ins(LLVMInstruction::Type::ListContainsItem, currentLoopScope(), m_loopCondition);
13391339
ins.workList = list;
13401340

13411341
if (m_listPtrs.find(list) == m_listPtrs.cend())
@@ -1346,7 +1346,7 @@ CompilerValue *LLVMCodeBuilder::addListContains(List *list, CompilerValue *item)
13461346

13471347
CompilerValue *LLVMCodeBuilder::addListSize(List *list)
13481348
{
1349-
LLVMInstruction ins(LLVMInstruction::Type::GetListSize, currentLoopScope());
1349+
LLVMInstruction ins(LLVMInstruction::Type::GetListSize, currentLoopScope(), m_loopCondition);
13501350
ins.workList = list;
13511351

13521352
if (m_listPtrs.find(list) == m_listPtrs.cend())
@@ -1370,7 +1370,7 @@ CompilerValue *LLVMCodeBuilder::addProcedureArgument(const std::string &name)
13701370

13711371
const auto index = it - argNames.begin();
13721372
const Compiler::StaticType type = getProcedureArgType(m_procedurePrototype->argumentTypes()[index]);
1373-
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::ProcedureArg, currentLoopScope());
1373+
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::ProcedureArg, currentLoopScope(), m_loopCondition);
13741374
auto ret = std::make_shared<LLVMRegister>(type);
13751375
ret->isRawValue = (type != Compiler::StaticType::Unknown);
13761376
ins->functionReturnReg = ret.get();
@@ -1550,7 +1550,7 @@ void LLVMCodeBuilder::createLocalVariableWrite(CompilerLocalVariable *variable,
15501550

15511551
void LLVMCodeBuilder::createVariableWrite(Variable *variable, CompilerValue *value)
15521552
{
1553-
LLVMInstruction ins(LLVMInstruction::Type::WriteVariable, currentLoopScope());
1553+
LLVMInstruction ins(LLVMInstruction::Type::WriteVariable, currentLoopScope(), m_loopCondition);
15541554
ins.workVariable = variable;
15551555
createOp(ins, Compiler::StaticType::Void, Compiler::StaticType::Unknown, { value });
15561556

@@ -1567,7 +1567,7 @@ void LLVMCodeBuilder::createVariableWrite(Variable *variable, CompilerValue *val
15671567

15681568
void LLVMCodeBuilder::createListClear(List *list)
15691569
{
1570-
LLVMInstruction ins(LLVMInstruction::Type::ClearList, currentLoopScope());
1570+
LLVMInstruction ins(LLVMInstruction::Type::ClearList, currentLoopScope(), m_loopCondition);
15711571
ins.workList = list;
15721572
createOp(ins, Compiler::StaticType::Void);
15731573

@@ -1577,7 +1577,7 @@ void LLVMCodeBuilder::createListClear(List *list)
15771577

15781578
void LLVMCodeBuilder::createListRemove(List *list, CompilerValue *index)
15791579
{
1580-
LLVMInstruction ins(LLVMInstruction::Type::RemoveListItem, currentLoopScope());
1580+
LLVMInstruction ins(LLVMInstruction::Type::RemoveListItem, currentLoopScope(), m_loopCondition);
15811581
ins.workList = list;
15821582
createOp(ins, Compiler::StaticType::Void, Compiler::StaticType::Number, { index });
15831583

@@ -1587,7 +1587,7 @@ void LLVMCodeBuilder::createListRemove(List *list, CompilerValue *index)
15871587

15881588
void LLVMCodeBuilder::createListAppend(List *list, CompilerValue *item)
15891589
{
1590-
LLVMInstruction ins(LLVMInstruction::Type::AppendToList, currentLoopScope());
1590+
LLVMInstruction ins(LLVMInstruction::Type::AppendToList, currentLoopScope(), m_loopCondition);
15911591
ins.workList = list;
15921592
createOp(ins, Compiler::StaticType::Void, Compiler::StaticType::Unknown, { item });
15931593

@@ -1597,7 +1597,7 @@ void LLVMCodeBuilder::createListAppend(List *list, CompilerValue *item)
15971597

15981598
void LLVMCodeBuilder::createListInsert(List *list, CompilerValue *index, CompilerValue *item)
15991599
{
1600-
LLVMInstruction ins(LLVMInstruction::Type::InsertToList, currentLoopScope());
1600+
LLVMInstruction ins(LLVMInstruction::Type::InsertToList, currentLoopScope(), m_loopCondition);
16011601
ins.workList = list;
16021602
createOp(ins, Compiler::StaticType::Void, { Compiler::StaticType::Number, Compiler::StaticType::Unknown }, { index, item });
16031603

@@ -1607,7 +1607,7 @@ void LLVMCodeBuilder::createListInsert(List *list, CompilerValue *index, Compile
16071607

16081608
void LLVMCodeBuilder::createListReplace(List *list, CompilerValue *index, CompilerValue *item)
16091609
{
1610-
LLVMInstruction ins(LLVMInstruction::Type::ListReplace, currentLoopScope());
1610+
LLVMInstruction ins(LLVMInstruction::Type::ListReplace, currentLoopScope(), m_loopCondition);
16111611
ins.workList = list;
16121612
createOp(ins, Compiler::StaticType::Void, { Compiler::StaticType::Number, Compiler::StaticType::Unknown }, { index, item });
16131613

@@ -1617,70 +1617,80 @@ void LLVMCodeBuilder::createListReplace(List *list, CompilerValue *index, Compil
16171617

16181618
void LLVMCodeBuilder::beginIfStatement(CompilerValue *cond)
16191619
{
1620-
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginIf, currentLoopScope());
1620+
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginIf, currentLoopScope(), m_loopCondition);
16211621
ins->args.push_back({ Compiler::StaticType::Bool, static_cast<LLVMRegister *>(cond) });
16221622
m_instructions.push_back(ins);
16231623
}
16241624

16251625
void LLVMCodeBuilder::beginElseBranch()
16261626
{
1627-
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginElse, currentLoopScope()));
1627+
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginElse, currentLoopScope(), m_loopCondition));
16281628
}
16291629

16301630
void LLVMCodeBuilder::endIf()
16311631
{
1632-
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::EndIf, currentLoopScope()));
1632+
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::EndIf, currentLoopScope(), m_loopCondition));
16331633
}
16341634

16351635
void LLVMCodeBuilder::beginRepeatLoop(CompilerValue *count)
16361636
{
1637-
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginRepeatLoop, currentLoopScope());
1637+
assert(!m_loopCondition);
1638+
1639+
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginRepeatLoop, currentLoopScope(), m_loopCondition);
16381640
ins->args.push_back({ Compiler::StaticType::Number, static_cast<LLVMRegister *>(count) });
16391641
m_instructions.push_back(ins);
16401642
pushLoopScope(false);
16411643
}
16421644

16431645
void LLVMCodeBuilder::beginWhileLoop(CompilerValue *cond)
16441646
{
1645-
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginWhileLoop, currentLoopScope());
1647+
assert(m_loopCondition);
1648+
m_loopCondition = false;
1649+
1650+
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginWhileLoop, currentLoopScope(), m_loopCondition);
16461651
ins->args.push_back({ Compiler::StaticType::Bool, static_cast<LLVMRegister *>(cond) });
16471652
m_instructions.push_back(ins);
16481653
pushLoopScope(false);
16491654
}
16501655

16511656
void LLVMCodeBuilder::beginRepeatUntilLoop(CompilerValue *cond)
16521657
{
1653-
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginRepeatUntilLoop, currentLoopScope());
1658+
assert(m_loopCondition);
1659+
m_loopCondition = false;
1660+
1661+
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginRepeatUntilLoop, currentLoopScope(), m_loopCondition);
16541662
ins->args.push_back({ Compiler::StaticType::Bool, static_cast<LLVMRegister *>(cond) });
16551663
m_instructions.push_back(ins);
16561664
pushLoopScope(false);
16571665
}
16581666

16591667
void LLVMCodeBuilder::beginLoopCondition()
16601668
{
1661-
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginLoopCondition, currentLoopScope()));
1669+
assert(!m_loopCondition);
1670+
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginLoopCondition, currentLoopScope(), m_loopCondition));
1671+
m_loopCondition = true;
16621672
}
16631673

16641674
void LLVMCodeBuilder::endLoop()
16651675
{
16661676
if (!m_warp)
1667-
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::Yield, currentLoopScope()));
1677+
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::Yield, currentLoopScope(), m_loopCondition));
16681678

1669-
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::EndLoop, currentLoopScope()));
1679+
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::EndLoop, currentLoopScope(), m_loopCondition));
16701680
popLoopScope();
16711681
}
16721682

16731683
void LLVMCodeBuilder::yield()
16741684
{
1675-
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::Yield, currentLoopScope()));
1685+
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::Yield, currentLoopScope(), m_loopCondition));
16761686

16771687
if (m_loopScope >= 0)
16781688
m_loopScopes[m_loopScope]->containsYield = true;
16791689
}
16801690

16811691
void LLVMCodeBuilder::createStop()
16821692
{
1683-
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::Stop, currentLoopScope()));
1693+
m_instructions.push_back(std::make_shared<LLVMInstruction>(LLVMInstruction::Type::Stop, currentLoopScope(), m_loopCondition));
16841694
}
16851695

16861696
void LLVMCodeBuilder::createProcedureCall(BlockPrototype *prototype, const Compiler::Args &args)
@@ -1693,7 +1703,7 @@ void LLVMCodeBuilder::createProcedureCall(BlockPrototype *prototype, const Compi
16931703
for (BlockPrototype::ArgType type : procedureArgs)
16941704
types.push_back(getProcedureArgType(type));
16951705

1696-
LLVMInstruction ins(LLVMInstruction::Type::CallProcedure, currentLoopScope());
1706+
LLVMInstruction ins(LLVMInstruction::Type::CallProcedure, currentLoopScope(), m_loopCondition);
16971707
ins.procedurePrototype = prototype;
16981708
createOp(ins, Compiler::StaticType::Void, types, args);
16991709
}
@@ -2384,12 +2394,12 @@ bool LLVMCodeBuilder::isVariableWriteResultTypeSafe(std::shared_ptr<LLVMInstruct
23842394

23852395
LLVMRegister *LLVMCodeBuilder::createOp(LLVMInstruction::Type type, Compiler::StaticType retType, Compiler::StaticType argType, const Compiler::Args &args)
23862396
{
2387-
return createOp({ type, currentLoopScope() }, retType, argType, args);
2397+
return createOp({ type, currentLoopScope(), m_loopCondition }, retType, argType, args);
23882398
}
23892399

23902400
LLVMRegister *LLVMCodeBuilder::createOp(LLVMInstruction::Type type, Compiler::StaticType retType, const Compiler::ArgTypes &argTypes, const Compiler::Args &args)
23912401
{
2392-
return createOp({ type, currentLoopScope() }, retType, argTypes, args);
2402+
return createOp({ type, currentLoopScope(), m_loopCondition }, retType, argTypes, args);
23932403
}
23942404

23952405
LLVMRegister *LLVMCodeBuilder::createOp(const LLVMInstruction &ins, Compiler::StaticType retType, Compiler::StaticType argType, const Compiler::Args &args)

src/engine/internal/llvm/llvmcodebuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ class LLVMCodeBuilder : public ICodeBuilder
236236
std::vector<std::shared_ptr<LLVMLoopScope>> m_loopScopes;
237237
long m_loopScopeCounter = 0; // replacement for m_loopScopes size in build phase
238238
std::vector<long> m_loopScopeTree;
239+
bool m_loopCondition = false; // whether we're currently compiling a loop condition
239240
std::vector<std::shared_ptr<LLVMInstruction>> m_variableInstructions;
240241
std::vector<std::vector<llvm::Value *>> m_heap; // scopes
241242

src/engine/internal/llvm/llvminstruction.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,10 @@ struct LLVMInstruction
7878
ProcedureArg
7979
};
8080

81-
LLVMInstruction(Type type, std::shared_ptr<LLVMLoopScope> loopScope) :
81+
LLVMInstruction(Type type, std::shared_ptr<LLVMLoopScope> loopScope, bool loopCondition) :
8282
type(type),
83-
loopScope(loopScope)
83+
loopScope(loopScope),
84+
loopCondition(loopCondition)
8485
{
8586
}
8687

@@ -95,6 +96,7 @@ struct LLVMInstruction
9596
BlockPrototype *procedurePrototype = nullptr;
9697
size_t procedureArgIndex = 0;
9798
std::shared_ptr<LLVMLoopScope> loopScope;
99+
bool loopCondition = false; // whether the instruction is part of a loop condition
98100
};
99101

100102
} // namespace libscratchcpp

0 commit comments

Comments
 (0)