@@ -203,8 +203,8 @@ void createControlPoint(Module &Mod, Function *F, std::vector<Value *> LiveVars,
203203 for (Value *LV : LiveVars) {
204204 TypeParams.push_back (LV->getType ());
205205 }
206- FunctionType *FType =
207- FunctionType::get (YkCtrlPointStruct , {YkCtrlPointStruct}, false );
206+ FunctionType *FType = FunctionType::get (
207+ Type::getVoidTy (Context) , {YkCtrlPointStruct-> getPointerTo () }, false );
208208 Value *JITActionPtr =
209209 Builder.CreateIntToPtr (JITAction, Type::getInt8PtrTy (Context));
210210 Value *CastTrace = Builder.CreateBitCast (JITActionPtr, FType->getPointerTo ());
@@ -226,16 +226,9 @@ void createControlPoint(Module &Mod, Function *F, std::vector<Value *> LiveVars,
226226 createJITStatePrint (Builder, &Mod, " stop-tracing" );
227227 Builder.CreateBr (BBReturn);
228228
229- // Create return block. Returns the unchanged YkCtrlPointStruct if no
230- // compiled trace was executed, otherwise return a new YkCtrlPointStruct
231- // which contains the changed interpreter state.
229+ // Populate the return block.
232230 Builder.SetInsertPoint (BBReturn);
233- Value *YkCtrlPointVars = F->getArg (1 );
234- PHINode *Phi = Builder.CreatePHI (YkCtrlPointStruct, 2 );
235- Phi->addIncoming (YkCtrlPointVars, CtrlPointEntry);
236- Phi->addIncoming (YkCtrlPointVars, BBStartTracing);
237- Phi->addIncoming (YkCtrlPointVars, BBStopTracing);
238- Builder.CreateRet (Phi);
231+ Builder.CreateRetVoid ();
239232}
240233
241234// / Extract all live variables that need to be passed into the control point.
@@ -278,9 +271,6 @@ class YkControlPoint : public ModulePass {
278271 return false ;
279272 }
280273
281- // Replace old control point call.
282- IRBuilder<> Builder (OldCtrlPointCall);
283-
284274 // Get function containing the control point.
285275 Function *Caller = OldCtrlPointCall->getFunction ();
286276
@@ -305,27 +295,36 @@ class YkControlPoint : public ModulePass {
305295 for (Value *V : LiveVals) {
306296 TypeParams.push_back (V->getType ());
307297 }
308- StructType *CtrlPointReturnTy =
298+ StructType *CtrlPointVarsTy =
309299 StructType::create (TypeParams, " YkCtrlPointVars" );
310300
311301 // Create the new control point.
312302 Type *YkLocTy = OldCtrlPointCall->getArgOperand (0 )->getType ();
313- FunctionType *FType = FunctionType::get (
314- CtrlPointReturnTy, {YkLocTy, CtrlPointReturnTy}, false );
303+ FunctionType *FType =
304+ FunctionType::get (Type::getVoidTy (Context),
305+ {YkLocTy, CtrlPointVarsTy->getPointerTo ()}, false );
315306 Function *NF = Function::Create (FType, GlobalVariable::ExternalLinkage,
316307 YK_NEW_CONTROL_POINT, M);
317308
318- // Instantiate the YkCtrlPointStruct to pass in to the control point.
319- Value *InputStruct = cast<Value>(Constant::getNullValue (CtrlPointReturnTy));
309+ // At the top of the function, instantiate a `YkCtrlPointStruct` to pass in
310+ // to the control point. We do so on the stack, so that we can pass the
311+ // struct by pointer.
312+ IRBuilder<> Builder (Caller->getEntryBlock ().getFirstNonPHI ());
313+ Value *InputStruct = Builder.CreateAlloca (CtrlPointVarsTy, 0 , " " );
314+
315+ Builder.SetInsertPoint (OldCtrlPointCall);
320316 unsigned LvIdx = 0 ;
321317 for (Value *LV : LiveVals) {
322- InputStruct = Builder.CreateInsertValue (InputStruct, LV, LvIdx);
318+ Value *FieldPtr =
319+ Builder.CreateGEP (CtrlPointVarsTy, InputStruct,
320+ {Builder.getInt32 (0 ), Builder.getInt32 (LvIdx)});
321+ Builder.CreateStore (LV, FieldPtr);
323322 assert (LvIdx != UINT_MAX);
324323 LvIdx++;
325324 }
326325
327326 // Insert call to the new control point.
328- CallInst *CtrlPointRet = Builder.CreateCall (
327+ Instruction *NewCtrlPointCallInst = Builder.CreateCall (
329328 NF, {OldCtrlPointCall->getArgOperand (0 ), InputStruct});
330329
331330 // Once the control point returns we need to extract the (potentially
@@ -334,9 +333,12 @@ class YkControlPoint : public ModulePass {
334333 // replacing all future references with the new values.
335334 LvIdx = 0 ;
336335 for (Value *LV : LiveVals) {
337- Value *New = Builder.CreateExtractValue (cast<Value>(CtrlPointRet), LvIdx);
336+ Value *FieldPtr =
337+ Builder.CreateGEP (CtrlPointVarsTy, InputStruct,
338+ {Builder.getInt32 (0 ), Builder.getInt32 (LvIdx)});
339+ Value *New = Builder.CreateLoad (TypeParams[LvIdx], FieldPtr);
338340 LV->replaceUsesWithIf (
339- New, [&](Use &U) { return DT.dominates (CtrlPointRet , U); });
341+ New, [&](Use &U) { return DT.dominates (NewCtrlPointCallInst , U); });
340342 assert (LvIdx != UINT_MAX);
341343 LvIdx++;
342344 }
@@ -345,7 +347,7 @@ class YkControlPoint : public ModulePass {
345347 OldCtrlPointCall->eraseFromParent ();
346348
347349 // Generate new control point logic.
348- createControlPoint (M, NF, LiveVals, CtrlPointReturnTy , YkLocTy);
350+ createControlPoint (M, NF, LiveVals, CtrlPointVarsTy , YkLocTy);
349351 return true ;
350352 }
351353};
0 commit comments