Skip to content

Commit f9e0562

Browse files
committed
Add invalidate target LLVM instruction
1 parent c99bb9f commit f9e0562

File tree

9 files changed

+43
-0
lines changed

9 files changed

+43
-0
lines changed

src/engine/internal/icodebuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ class ICodeBuilder
102102
virtual void createThreadStop() = 0;
103103
virtual void createStopWithoutSync() = 0;
104104

105+
virtual void invalidateTarget() = 0;
106+
105107
virtual void createProcedureCall(BlockPrototype *prototype, const Compiler::Args &args) = 0;
106108
};
107109

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ ProcessResult Control::process(LLVMInstruction *ins)
6868
ret.next = buildStopWithoutSync(ins);
6969
break;
7070

71+
case LLVMInstruction::Type::InvalidateTarget:
72+
ret.next = buildInvalidateTarget(ins);
73+
break;
74+
7175
default:
7276
ret.match = false;
7377
break;
@@ -363,3 +367,9 @@ LLVMInstruction *Control::buildStopWithoutSync(LLVMInstruction *ins)
363367

364368
return ins->next;
365369
}
370+
371+
LLVMInstruction *Control::buildInvalidateTarget(LLVMInstruction *ins)
372+
{
373+
m_utils.invalidateTarget();
374+
return ins->next;
375+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class Control : public InstructionGroup
2929
LLVMInstruction *buildStop(LLVMInstruction *ins);
3030
LLVMInstruction *buildThreadStop(LLVMInstruction *ins);
3131
LLVMInstruction *buildStopWithoutSync(LLVMInstruction *ins);
32+
LLVMInstruction *buildInvalidateTarget(LLVMInstruction *ins);
3233
};
3334

3435
} // namespace libscratchcpp::llvmins

src/engine/internal/llvm/llvmbuildutils.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ void LLVMBuildUtils::init(llvm::Function *function, BlockPrototype *procedurePro
161161
reloadVariables();
162162
reloadLists();
163163

164+
// Mark the target as valid
165+
m_targetValidFlag = m_builder.CreateAlloca(m_builder.getInt1Ty());
166+
m_builder.CreateStore(m_builder.getInt1(true), m_targetValidFlag);
167+
164168
// Create end branches
165169
m_endBranch = llvm::BasicBlock::Create(m_llvmCtx, "end", m_function);
166170
m_endThreadBranch = llvm::BasicBlock::Create(m_llvmCtx, "endThread", m_function);
@@ -438,6 +442,12 @@ LLVMListPtr &LLVMBuildUtils::listPtr(List *list)
438442

439443
void LLVMBuildUtils::syncVariables()
440444
{
445+
llvm::BasicBlock *syncBlock = llvm::BasicBlock::Create(m_llvmCtx, "syncVariables", m_function);
446+
llvm::BasicBlock *syncNextBlock = llvm::BasicBlock::Create(m_llvmCtx, "syncVariables.next", m_function);
447+
m_builder.CreateCondBr(m_builder.CreateLoad(m_builder.getInt1Ty(), m_targetValidFlag), syncBlock, syncNextBlock);
448+
449+
m_builder.SetInsertPoint(syncBlock);
450+
441451
// Copy stack variables to the actual variables
442452
for (auto &[var, varPtr] : m_variablePtrs) {
443453
llvm::BasicBlock *copyBlock = llvm::BasicBlock::Create(m_llvmCtx, "syncVar", m_function);
@@ -451,6 +461,8 @@ void LLVMBuildUtils::syncVariables()
451461

452462
m_builder.SetInsertPoint(nextBlock);
453463
}
464+
465+
m_builder.SetInsertPoint(syncNextBlock);
454466
}
455467

456468
void LLVMBuildUtils::reloadVariables()
@@ -481,6 +493,11 @@ void LLVMBuildUtils::reloadLists()
481493
}
482494
}
483495

496+
void LLVMBuildUtils::invalidateTarget()
497+
{
498+
m_builder.CreateStore(m_builder.getInt1(false), m_targetValidFlag);
499+
}
500+
484501
std::vector<LLVMIfStatement> &LLVMBuildUtils::ifStatements()
485502
{
486503
return m_ifStatements;

src/engine/internal/llvm/llvmbuildutils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class LIBSCRATCHCPP_TEST_EXPORT LLVMBuildUtils
8282
void syncVariables();
8383
void reloadVariables();
8484
void reloadLists();
85+
void invalidateTarget();
8586

8687
std::vector<LLVMIfStatement> &ifStatements();
8788
std::vector<LLVMLoop> &loops();
@@ -186,6 +187,7 @@ class LIBSCRATCHCPP_TEST_EXPORT LLVMBuildUtils
186187
llvm::Value *m_targetVariables = nullptr;
187188
llvm::Value *m_targetLists = nullptr;
188189
llvm::Value *m_warpArg = nullptr;
190+
llvm::Value *m_targetValidFlag = nullptr;
189191

190192
std::unique_ptr<LLVMCoroutine> m_coroutine;
191193

src/engine/internal/llvm/llvmcodebuilder.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,12 @@ void LLVMCodeBuilder::createStopWithoutSync()
579579
m_instructions.addInstruction(ins);
580580
}
581581

582+
void LLVMCodeBuilder::invalidateTarget()
583+
{
584+
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::InvalidateTarget, m_loopCondition);
585+
m_instructions.addInstruction(ins);
586+
}
587+
582588
void LLVMCodeBuilder::createProcedureCall(BlockPrototype *prototype, const Compiler::Args &args)
583589
{
584590
assert(prototype);

src/engine/internal/llvm/llvmcodebuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ class LIBSCRATCHCPP_TEST_EXPORT LLVMCodeBuilder : public ICodeBuilder
116116
void createThreadStop() override;
117117
void createStopWithoutSync() override;
118118

119+
void invalidateTarget() override;
120+
119121
void createProcedureCall(BlockPrototype *prototype, const Compiler::Args &args) override;
120122

121123
private:

src/engine/internal/llvm/llvminstruction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ struct LLVMInstruction
7979
Stop,
8080
ThreadStop,
8181
StopWithoutSync,
82+
InvalidateTarget,
8283
CallProcedure,
8384
ProcedureArg
8485
};

test/mocks/codebuildermock.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,7 @@ class CodeBuilderMock : public ICodeBuilder
9191
MOCK_METHOD(void, createThreadStop, (), (override));
9292
MOCK_METHOD(void, createStopWithoutSync, (), (override));
9393

94+
MOCK_METHOD(void, invalidateTarget, (), (override));
95+
9496
MOCK_METHOD(void, createProcedureCall, (BlockPrototype *, const Compiler::Args &), (override));
9597
};

0 commit comments

Comments
 (0)