@@ -304,10 +304,25 @@ class YkControlPoint : public ModulePass {
304
304
->getType ();
305
305
306
306
// Create the new control point, which is of the form:
307
- // bool new_control_point(YkMT*, YkLocation*, CtrlPointVars*)
308
- FunctionType *FType = FunctionType::get (
309
- Type::getInt1Ty (Context),
310
- {YkMTTy, YkLocTy, CtrlPointVarsTy->getPointerTo ()}, false );
307
+ // bool new_control_point(YkMT*, YkLocation*, CtrlPointVars*,
308
+ // ReturnValue*)
309
+ // If the return type of the control point's caller is void (i.e. if a
310
+ // function f calls yk_control_point and f's return type is void), create
311
+ // an Int1 pointer as a dummy. We have to pass something as the yk_stopgap
312
+ // signature expects a pointer, even if its never used.
313
+ Type *ReturnTy = Caller->getReturnType ();
314
+ Type *ReturnPtrTy;
315
+ if (ReturnTy->isVoidTy ()) {
316
+ // Create dummy pointer which we pass in but which is never written to.
317
+ ReturnPtrTy = Type::getInt1Ty (Context);
318
+ } else {
319
+ ReturnPtrTy = ReturnTy;
320
+ }
321
+ FunctionType *FType =
322
+ FunctionType::get (Type::getInt1Ty (Context),
323
+ {YkMTTy, YkLocTy, CtrlPointVarsTy->getPointerTo (),
324
+ ReturnPtrTy->getPointerTo ()},
325
+ false );
311
326
Function *NF = Function::Create (FType, GlobalVariable::ExternalLinkage,
312
327
YK_NEW_CONTROL_POINT, M);
313
328
@@ -317,6 +332,10 @@ class YkControlPoint : public ModulePass {
317
332
IRBuilder<> Builder (Caller->getEntryBlock ().getFirstNonPHI ());
318
333
Value *InputStruct = Builder.CreateAlloca (CtrlPointVarsTy, 0 , " " );
319
334
335
+ // Also at the top, generate storage for the interpreted return of the
336
+ // control points caller.
337
+ Value *ReturnPtr = Builder.CreateAlloca (ReturnPtrTy, 0 , " " );
338
+
320
339
Builder.SetInsertPoint (OldCtrlPointCall);
321
340
unsigned LvIdx = 0 ;
322
341
for (Value *LV : LiveVals) {
@@ -332,7 +351,7 @@ class YkControlPoint : public ModulePass {
332
351
Instruction *NewCtrlPointCallInst = Builder.CreateCall (
333
352
NF, {OldCtrlPointCall->getArgOperand (YK_CONTROL_POINT_ARG_MT_IDX),
334
353
OldCtrlPointCall->getArgOperand (YK_CONTROL_POINT_ARG_LOC_IDX),
335
- InputStruct});
354
+ InputStruct, ReturnPtr });
336
355
337
356
// Once the control point returns we need to extract the (potentially
338
357
// mutated) values from the returned YkCtrlPointStruct and reassign them to
@@ -363,11 +382,11 @@ class YkControlPoint : public ModulePass {
363
382
Builder.SetInsertPoint (ExitBB);
364
383
// YKFIXME: We need to return the value of interpreted return and the return
365
384
// type must be that of the control point's caller.
366
- Type *RetTy = Caller->getReturnType ();
367
- if (RetTy->isVoidTy ()) {
385
+ if (ReturnTy->isVoidTy ()) {
368
386
Builder.CreateRetVoid ();
369
387
} else {
370
- Builder.CreateRet (ConstantInt::get (Type::getInt32Ty (Context), 0 ));
388
+ Value *ReturnValue = Builder.CreateLoad (ReturnTy, ReturnPtr);
389
+ Builder.CreateRet (ReturnValue);
371
390
}
372
391
373
392
// To do so we need to first split up the current block and then
0 commit comments