Skip to content

Commit

Permalink
Merge rust-lang#73
Browse files Browse the repository at this point in the history
73: Simplify the control point. r=ltratt a=ptersilie



Co-authored-by: Lukas Diekmann <lukas.diekmann@gmail.com>
  • Loading branch information
bors[bot] and ptersilie authored Jun 30, 2023
2 parents 5f36f1f + 4c3be08 commit 23597b1
Showing 1 changed file with 3 additions and 49 deletions.
52 changes: 3 additions & 49 deletions llvm/lib/Transforms/Yk/ControlPoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,11 @@ class YkControlPoint : public ModulePass {
->getType();

// Create the new control point, which is of the form:
// void* new_control_point(YkMT*, YkLocation*, CtrlPointVars*, void*)
// void new_control_point(YkMT*, YkLocation*, CtrlPointVars*, void*)
PointerType *VoidPtr = PointerType::get(Context, 0);
FunctionType *FType = FunctionType::get(
VoidPtr, {YkMTTy, YkLocTy, CtrlPointVarsTy->getPointerTo(), VoidPtr},
false);
Type::getVoidTy(Context),
{YkMTTy, YkLocTy, CtrlPointVarsTy->getPointerTo(), VoidPtr}, false);
Function *NF = Function::Create(FType, GlobalVariable::ExternalLinkage,
YK_NEW_CONTROL_POINT, M);

Expand Down Expand Up @@ -199,55 +199,9 @@ class YkControlPoint : public ModulePass {
OldCtrlPointCall->getArgOperand(YK_CONTROL_POINT_ARG_LOC_IDX),
InputStruct, FAddr});

// Once the control point returns we need to extract the (potentially
// mutated) values from the returned YkCtrlPointStruct and reassign them to
// their corresponding live variables. In LLVM IR we can do this by simply
// replacing all future references with the new values.
LvIdx = 0;
Instruction *New;
for (Value *LV : LiveVals) {
Value *FieldPtr =
Builder.CreateGEP(CtrlPointVarsTy, InputStruct,
{Builder.getInt32(0), Builder.getInt32(LvIdx)});
New = Builder.CreateLoad(TypeParams[LvIdx], FieldPtr);
LV->replaceUsesWithIf(
New, [&](Use &U) { return DT.dominates(NewCtrlPointCallInst, U); });
assert(LvIdx != UINT_MAX);
LvIdx++;
}

// Replace the call to the dummy control point.
OldCtrlPointCall->eraseFromParent();

// Create the new exit block.
BasicBlock *ExitBB = BasicBlock::Create(Context, "", Caller);
Builder.SetInsertPoint(ExitBB);

// Create call to frame reconstructor.
FunctionType *YKFRType =
FunctionType::get(Type::getVoidTy(Context), {VoidPtr}, false);
Function *YKFR = Function::Create(YKFRType, GlobalVariable::ExternalLinkage,
YK_RECONSTRUCT_FRAMES, M);
Builder.CreateCall(YKFR, {NewCtrlPointCallInst});
Builder.CreateUnreachable();

// Split up the current block and then insert a conditional branch that
// either continues after the control point or invokes frame reconstruction.
BasicBlock *BB = NewCtrlPointCallInst->getParent();
BasicBlock *ContBB = BB->splitBasicBlock(New->getNextNonDebugInstruction());
Instruction &OldBr = BB->back();
assert(OldBr.getPrevNonDebugInstruction() == New &&
"Split block at the wrong spot.");
OldBr.eraseFromParent();
Builder.SetInsertPoint(BB);
// The return value of the control point tells us whether a guard has failed
// or not (i.e. anything other than a nullptr means a guard has failed). If
// it has jump to `ExitBB` which calls the code that copies over the new
// stack from the given pointer.
Value *HasGuardFailed = Builder.CreateICmpEQ(
NewCtrlPointCallInst, ConstantPointerNull::get(VoidPtr));
Builder.CreateCondBr(HasGuardFailed, ContBB, ExitBB);

#ifndef NDEBUG
// Our pass runs after LLVM normally does its verify pass. In debug builds
// we run it again to check that our pass is generating valid IR.
Expand Down

0 comments on commit 23597b1

Please sign in to comment.