From e5e3b1dc2344c800acef75d33b49bca97e4334b5 Mon Sep 17 00:00:00 2001 From: Lukas Diekmann Date: Mon, 26 Jun 2023 14:56:15 +0100 Subject: [PATCH 1/2] Remove branch after control point. Since deoptimisation now doesn't require us to return to the control point anymore, we can remove the control points return type and the branch with the call to the frame reconstruction code. --- llvm/lib/Transforms/Yk/ControlPoint.cpp | 35 +++---------------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/llvm/lib/Transforms/Yk/ControlPoint.cpp b/llvm/lib/Transforms/Yk/ControlPoint.cpp index aa3c90076a619c3..dd81d53d67e097b 100644 --- a/llvm/lib/Transforms/Yk/ControlPoint.cpp +++ b/llvm/lib/Transforms/Yk/ControlPoint.cpp @@ -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); @@ -219,35 +219,6 @@ class YkControlPoint : public ModulePass { // 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. From 4c3be08fe0dbf2fb634692ba8bbc1590c4b288d3 Mon Sep 17 00:00:00 2001 From: Lukas Diekmann Date: Fri, 30 Jun 2023 11:46:11 +0100 Subject: [PATCH 2/2] Remove loads after control point. Since we can no longer return naturally from the control point, we don't need to keep these loads around anymore. --- llvm/lib/Transforms/Yk/ControlPoint.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/llvm/lib/Transforms/Yk/ControlPoint.cpp b/llvm/lib/Transforms/Yk/ControlPoint.cpp index dd81d53d67e097b..d3bf53393e6b1ca 100644 --- a/llvm/lib/Transforms/Yk/ControlPoint.cpp +++ b/llvm/lib/Transforms/Yk/ControlPoint.cpp @@ -199,23 +199,6 @@ 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();