Skip to content

Commit a10ba00

Browse files
committed
Add conditional exit after control point.
Since the stopgap interpreter may interpret through the exit from the main interpreter loop, we can't just continue running from the control point after it returns. The stopgap interpreter now tells us via its return value whether we need to continue as normal, or exit the main interpreter loop. This is currently done by returning a boolean from the control point, where `true` means the stopgap interpreter has run out of the main interpreter loop. In this case we simply need to return. Note, that we actually also need to return the value of the return that was interpreted by the stopgap interpreter. We currently don't do this since it requires more changes to the control point (passing in a pointer in which to store the return value).
1 parent f6ff7b1 commit a10ba00

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

llvm/lib/Transforms/Yk/ControlPoint.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,10 @@ class YkControlPoint : public ModulePass {
184184
OldCtrlPointCall->getArgOperand(YK_CONTROL_POINT_ARG_LOC_IDX)
185185
->getType();
186186

187-
// Create the new control point.
187+
// Create the new control point, which is of the form:
188+
// bool new_control_point(YkMT*, YkLocation*, CtrlPointVars*)
188189
FunctionType *FType = FunctionType::get(
189-
Type::getVoidTy(Context),
190+
Type::getInt1Ty(Context),
190191
{YkMTTy, YkLocTy, CtrlPointVarsTy->getPointerTo()}, false);
191192
Function *NF = Function::Create(FType, GlobalVariable::ExternalLinkage,
192193
YK_NEW_CONTROL_POINT, M);
@@ -219,11 +220,12 @@ class YkControlPoint : public ModulePass {
219220
// their corresponding live variables. In LLVM IR we can do this by simply
220221
// replacing all future references with the new values.
221222
LvIdx = 0;
223+
Instruction *New;
222224
for (Value *LV : LiveVals) {
223225
Value *FieldPtr =
224226
Builder.CreateGEP(CtrlPointVarsTy, InputStruct,
225227
{Builder.getInt32(0), Builder.getInt32(LvIdx)});
226-
Value *New = Builder.CreateLoad(TypeParams[LvIdx], FieldPtr);
228+
New = Builder.CreateLoad(TypeParams[LvIdx], FieldPtr);
227229
LV->replaceUsesWithIf(
228230
New, [&](Use &U) { return DT.dominates(NewCtrlPointCallInst, U); });
229231
assert(LvIdx != UINT_MAX);
@@ -233,6 +235,28 @@ class YkControlPoint : public ModulePass {
233235
// Replace the call to the dummy control point.
234236
OldCtrlPointCall->eraseFromParent();
235237

238+
// Get the result of the control point call. If it returns true, that means
239+
// the stopgap interpreter has interpreted a return so we need to return as
240+
// well.
241+
242+
// Create the new exit block.
243+
BasicBlock *ExitBB = BasicBlock::Create(Context, "", Caller);
244+
Builder.SetInsertPoint(ExitBB);
245+
// YKFIXME: We need to return the value of interpreted return and the return
246+
// type must be that of the control point's caller.
247+
Builder.CreateRet(ConstantInt::get(Type::getInt32Ty(Context), 0));
248+
249+
// To do so we need to first split up the current block and then
250+
// insert a conditional branch that either continues or returns.
251+
252+
BasicBlock *BB = NewCtrlPointCallInst->getParent();
253+
BasicBlock *ContBB = BB->splitBasicBlock(New);
254+
255+
Instruction &OldBr = BB->back();
256+
OldBr.eraseFromParent();
257+
Builder.SetInsertPoint(BB);
258+
Builder.CreateCondBr(NewCtrlPointCallInst, ExitBB, ContBB);
259+
236260
// Generate new control point logic.
237261
return true;
238262
}

0 commit comments

Comments
 (0)