@@ -591,6 +591,10 @@ namespace {
591
591
// / function type.
592
592
void expandCoroutineContinuationType ();
593
593
594
+ // / Initializes the result type for functions with @guaranteed_addr return
595
+ // / convention.
596
+ void expandGuaranteedAddressResult ();
597
+
594
598
// Expand the components for the async continuation entrypoint of the
595
599
// function type (the function to be called on returning).
596
600
void expandAsyncReturnType ();
@@ -694,6 +698,10 @@ void SignatureExpansion::expandResult(
694
698
695
699
auto fnConv = getSILFuncConventions ();
696
700
701
+ if (fnConv.hasGuaranteedAddressResult ()) {
702
+ return expandGuaranteedAddressResult ();
703
+ }
704
+
697
705
// Disable the use of sret if we have multiple indirect results.
698
706
if (fnConv.getNumIndirectSILResults () > 1 )
699
707
CanUseSRet = false ;
@@ -911,6 +919,11 @@ void SignatureExpansion::expandCoroutineContinuationParameters() {
911
919
}
912
920
}
913
921
922
+ void SignatureExpansion::expandGuaranteedAddressResult () {
923
+ CanUseSRet = false ;
924
+ ResultIRType = IGM.PtrTy ;
925
+ }
926
+
914
927
void SignatureExpansion::addAsyncParameters () {
915
928
// using TaskContinuationFunction =
916
929
// SWIFT_CC(swift)
@@ -3933,6 +3946,11 @@ void CallEmission::emitYieldsToExplosion(Explosion &out) {
3933
3946
}
3934
3947
}
3935
3948
3949
+ void CallEmission::emitGuaranteedAddressToExplosion (Explosion &out) {
3950
+ auto call = emitCallSite ();
3951
+ out.add (call);
3952
+ }
3953
+
3936
3954
// / Emit the result of this call to an explosion.
3937
3955
void CallEmission::emitToExplosion (Explosion &out, bool isOutlined) {
3938
3956
assert (state == State::Emitting);
@@ -3948,6 +3966,14 @@ void CallEmission::emitToExplosion(Explosion &out, bool isOutlined) {
3948
3966
3949
3967
SILFunctionConventions fnConv (getCallee ().getSubstFunctionType (),
3950
3968
IGF.getSILModule ());
3969
+
3970
+ if (fnConv.hasGuaranteedAddressResult ()) {
3971
+ assert (LastArgWritten == 0 &&
3972
+ " @guaranteed_addr along with indirect result?" );
3973
+ emitGuaranteedAddressToExplosion (out);
3974
+ return ;
3975
+ }
3976
+
3951
3977
SILType substResultType =
3952
3978
fnConv.getSILResultType (IGF.IGM .getMaximalTypeExpansionContext ());
3953
3979
@@ -7001,6 +7027,16 @@ void irgen::emitYieldOnceCoroutineResult(IRGenFunction &IGF, Explosion &result,
7001
7027
}
7002
7028
}
7003
7029
7030
+ void irgen::emitGuaranteedAddressResult (IRGenFunction &IGF, Explosion &result,
7031
+ SILType funcResultType,
7032
+ SILType returnResultType) {
7033
+ assert (funcResultType == returnResultType);
7034
+ assert (funcResultType.isAddress ());
7035
+ auto &Builder = IGF.Builder ;
7036
+ Builder.CreateRet (result.claimNext ());
7037
+ assert (result.empty ());
7038
+ }
7039
+
7004
7040
FunctionPointer
7005
7041
IRGenFunction::getFunctionPointerForResumeIntrinsic (llvm::Value *resume) {
7006
7042
auto *fnTy = llvm::FunctionType::get (
0 commit comments