@@ -219,19 +219,26 @@ llvm::Value *IRGenFunction::getAsyncContext() {
219
219
return Builder.CreateLoad (asyncContextLocation);
220
220
}
221
221
222
- llvm::CallInst *
223
- IRGenFunction::emitSuspendAsyncCall (unsigned asyncContextIndex,
224
- llvm::StructType *resultTy,
225
- ArrayRef<llvm::Value *> args) {
226
- auto *id = Builder.CreateIntrinsicCall (llvm::Intrinsic::coro_suspend_async,
227
- {resultTy}, args);
228
- llvm::Value *calleeContext =
229
- Builder.CreateExtractValue (id, asyncContextIndex);
230
- calleeContext = Builder.CreateBitOrPointerCast (calleeContext, IGM.Int8PtrTy );
231
- llvm::Constant *projectFn = cast<llvm::Constant>(args[2 ])->stripPointerCasts ();
232
- llvm::Value *context = Builder.CreateCall (projectFn, {calleeContext});
222
+ void IRGenFunction::storeCurrentAsyncContext (llvm::Value *context) {
233
223
context = Builder.CreateBitCast (context, IGM.SwiftContextPtrTy );
234
224
Builder.CreateStore (context, asyncContextLocation);
225
+ }
226
+
227
+ llvm::CallInst *IRGenFunction::emitSuspendAsyncCall (
228
+ unsigned asyncContextIndex, llvm::StructType *resultTy,
229
+ ArrayRef<llvm::Value *> args, bool restoreCurrentContext) {
230
+ auto *id = Builder.CreateIntrinsicCall (llvm::Intrinsic::coro_suspend_async,
231
+ {resultTy}, args);
232
+ if (restoreCurrentContext) {
233
+ llvm::Value *calleeContext =
234
+ Builder.CreateExtractValue (id, asyncContextIndex);
235
+ calleeContext =
236
+ Builder.CreateBitOrPointerCast (calleeContext, IGM.Int8PtrTy );
237
+ llvm::Constant *projectFn =
238
+ cast<llvm::Constant>(args[2 ])->stripPointerCasts ();
239
+ llvm::Value *context = Builder.CreateCall (projectFn, {calleeContext});
240
+ storeCurrentAsyncContext (context);
241
+ }
235
242
236
243
return id;
237
244
}
@@ -2023,10 +2030,9 @@ std::pair<llvm::Value *, llvm::Value *> irgen::getAsyncFunctionAndSize(
2023
2030
Address (addrPtr, IGF.IGM .getPointerAlignment ()), /* isFar*/ false ,
2024
2031
/* expectedType*/ functionPointer.getFunctionType ()->getPointerTo ());
2025
2032
}
2026
- if (auto authInfo = functionPointer.getAuthInfo ()) {
2027
- auto newAuthInfo = PointerAuthInfo (authInfo.getCorrespondingCodeKey (),
2028
- authInfo.getDiscriminator ());
2029
- fn = emitPointerAuthSign (IGF, fn, newAuthInfo);
2033
+ if (auto authInfo =
2034
+ functionPointer.getAuthInfo ().getCorrespondingCodeAuthInfo ()) {
2035
+ fn = emitPointerAuthSign (IGF, fn, authInfo);
2030
2036
}
2031
2037
}
2032
2038
llvm::Value *size = nullptr ;
@@ -2354,13 +2360,11 @@ class AsyncCallEmission final : public CallEmission {
2354
2360
}
2355
2361
2356
2362
FunctionPointer getCalleeFunctionPointer () override {
2357
- PointerAuthInfo newAuthInfo;
2358
- if (auto authInfo = CurCallee.getFunctionPointer ().getAuthInfo ()) {
2359
- newAuthInfo = PointerAuthInfo (authInfo.getCorrespondingCodeKey (),
2360
- authInfo.getDiscriminator ());
2361
- }
2363
+ PointerAuthInfo codeAuthInfo = CurCallee.getFunctionPointer ()
2364
+ .getAuthInfo ()
2365
+ .getCorrespondingCodeAuthInfo ();
2362
2366
return FunctionPointer (
2363
- FunctionPointer::Kind::Function, calleeFunction, newAuthInfo ,
2367
+ FunctionPointer::Kind::Function, calleeFunction, codeAuthInfo ,
2364
2368
Signature::forAsyncAwait (IGF.IGM , getCallee ().getOrigFunctionType ()));
2365
2369
}
2366
2370
@@ -2571,20 +2575,6 @@ class AsyncCallEmission final : public CallEmission {
2571
2575
return IGF.getCalleeErrorResultSlot (errorType);
2572
2576
}
2573
2577
2574
- FunctionPointer getFunctionPointerForDispatchCall (const FunctionPointer &fn) {
2575
- auto &IGM = IGF.IGM ;
2576
- // Strip off the return type. The original function pointer signature
2577
- // captured both the entry point type and the resume function type.
2578
- auto *fnTy = llvm::FunctionType::get (
2579
- IGM.VoidTy , fn.getSignature ().getType ()->params (), false /* vaargs*/ );
2580
- auto signature =
2581
- Signature (fnTy, fn.getSignature ().getAttributes (), IGM.SwiftAsyncCC );
2582
- auto fnPtr =
2583
- FunctionPointer (FunctionPointer::Kind::Function, fn.getRawPointer (),
2584
- fn.getAuthInfo (), signature);
2585
- return fnPtr;
2586
- }
2587
-
2588
2578
llvm::CallInst *createCall (const FunctionPointer &fn,
2589
2579
ArrayRef<llvm::Value *> args) override {
2590
2580
auto &IGM = IGF.IGM ;
@@ -2604,8 +2594,8 @@ class AsyncCallEmission final : public CallEmission {
2604
2594
auto resumeProjFn = IGF.getOrCreateResumePrjFn ();
2605
2595
arguments.push_back (
2606
2596
Builder.CreateBitOrPointerCast (resumeProjFn, IGM.Int8PtrTy ));
2607
- auto dispatchFn =
2608
- IGF. createAsyncDispatchFn ( getFunctionPointerForDispatchCall (fn), args);
2597
+ auto dispatchFn = IGF. createAsyncDispatchFn (
2598
+ getFunctionPointerForDispatchCall (IGM, fn), args);
2609
2599
arguments.push_back (
2610
2600
Builder.CreateBitOrPointerCast (dispatchFn, IGM.Int8PtrTy ));
2611
2601
arguments.push_back (
@@ -4731,10 +4721,8 @@ llvm::Value *FunctionPointer::getPointer(IRGenFunction &IGF) const {
4731
4721
auto *result = IGF.emitLoadOfRelativePointer (
4732
4722
Address (addrPtr, IGF.IGM .getPointerAlignment ()), /* isFar*/ false ,
4733
4723
/* expectedType*/ getFunctionType ()->getPointerTo ());
4734
- if (auto authInfo = AuthInfo) {
4735
- auto newAuthInfo = PointerAuthInfo (authInfo.getCorrespondingCodeKey (),
4736
- authInfo.getDiscriminator ());
4737
- result = emitPointerAuthSign (IGF, result, newAuthInfo);
4724
+ if (auto codeAuthInfo = AuthInfo.getCorrespondingCodeAuthInfo ()) {
4725
+ result = emitPointerAuthSign (IGF, result, codeAuthInfo);
4738
4726
}
4739
4727
return result;
4740
4728
}
@@ -4775,11 +4763,7 @@ FunctionPointer FunctionPointer::getAsFunction(IRGenFunction &IGF) const {
4775
4763
case FunctionPointer::BasicKind::Function:
4776
4764
return *this ;
4777
4765
case FunctionPointer::BasicKind::AsyncFunctionPointer: {
4778
- auto authInfo = AuthInfo;
4779
- if (authInfo) {
4780
- authInfo = PointerAuthInfo (AuthInfo.getCorrespondingCodeKey (),
4781
- AuthInfo.getDiscriminator ());
4782
- }
4766
+ auto authInfo = AuthInfo.getCorrespondingCodeAuthInfo ();
4783
4767
return FunctionPointer (Kind::Function, getPointer (IGF), authInfo, Sig);
4784
4768
}
4785
4769
}
@@ -4924,3 +4908,51 @@ Address irgen::emitAutoDiffAllocateSubcontext(
4924
4908
call->setCallingConv (IGF.IGM .SwiftCC );
4925
4909
return Address (call, IGF.IGM .getPointerAlignment ());
4926
4910
}
4911
+
4912
+ FunctionPointer
4913
+ irgen::getFunctionPointerForDispatchCall (IRGenModule &IGM,
4914
+ const FunctionPointer &fn) {
4915
+ // Strip off the return type. The original function pointer signature
4916
+ // captured both the entry point type and the resume function type.
4917
+ auto *fnTy = llvm::FunctionType::get (
4918
+ IGM.VoidTy , fn.getSignature ().getType ()->params (), false /* vaargs*/ );
4919
+ auto signature =
4920
+ Signature (fnTy, fn.getSignature ().getAttributes (), IGM.SwiftAsyncCC );
4921
+ auto fnPtr = FunctionPointer (FunctionPointer::Kind::Function,
4922
+ fn.getRawPointer (), fn.getAuthInfo (), signature);
4923
+ return fnPtr;
4924
+ }
4925
+
4926
+ void irgen::forwardAsyncCallResult (IRGenFunction &IGF,
4927
+ CanSILFunctionType fnType,
4928
+ AsyncContextLayout &layout,
4929
+ llvm::CallInst *call) {
4930
+ auto &IGM = IGF.IGM ;
4931
+ auto numAsyncContextParams =
4932
+ Signature::forAsyncReturn (IGM, fnType).getAsyncContextIndex () + 1 ;
4933
+ llvm::Value *result = call;
4934
+ auto *suspendResultTy = cast<llvm::StructType>(result->getType ());
4935
+ Explosion resultExplosion;
4936
+ Explosion errorExplosion;
4937
+ auto hasError = fnType->hasErrorResult ();
4938
+ Optional<ArrayRef<llvm::Value *>> nativeResults = llvm::None;
4939
+ SmallVector<llvm::Value *, 16 > nativeResultsStorage;
4940
+
4941
+ if (suspendResultTy->getNumElements () == numAsyncContextParams) {
4942
+ // no result to forward.
4943
+ assert (!hasError);
4944
+ } else {
4945
+ auto &Builder = IGF.Builder ;
4946
+ auto resultTys =
4947
+ makeArrayRef (suspendResultTy->element_begin () + numAsyncContextParams,
4948
+ suspendResultTy->element_end ());
4949
+
4950
+ for (unsigned i = 0 , e = resultTys.size (); i != e; ++i) {
4951
+ llvm::Value *elt =
4952
+ Builder.CreateExtractValue (result, numAsyncContextParams + i);
4953
+ nativeResultsStorage.push_back (elt);
4954
+ }
4955
+ nativeResults = nativeResultsStorage;
4956
+ }
4957
+ emitAsyncReturn (IGF, layout, fnType, nativeResults);
4958
+ }
0 commit comments