Skip to content

Commit 36f2955

Browse files
committed
IRGen support for GuaranteedAddress result convention
1 parent 78a165d commit 36f2955

File tree

6 files changed

+710
-1
lines changed

6 files changed

+710
-1
lines changed

lib/IRGen/CallEmission.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class CallEmission {
103103
virtual void emitCallToUnmappedExplosion(llvm::CallBase *call,
104104
Explosion &out) = 0;
105105
void emitYieldsToExplosion(Explosion &out);
106+
void emitGuaranteedAddressToExplosion(Explosion &out);
106107
void setKeyPathAccessorArguments(Explosion &in, bool isOutlined,
107108
Explosion &out);
108109
virtual FunctionPointer getCalleeFunctionPointer() = 0;

lib/IRGen/GenCall.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,10 @@ namespace {
591591
/// function type.
592592
void expandCoroutineContinuationType();
593593

594+
/// Initializes the result type for functions with @guaranteed_addr return
595+
/// convention.
596+
void expandGuaranteedAddressResult();
597+
594598
// Expand the components for the async continuation entrypoint of the
595599
// function type (the function to be called on returning).
596600
void expandAsyncReturnType();
@@ -694,6 +698,10 @@ void SignatureExpansion::expandResult(
694698

695699
auto fnConv = getSILFuncConventions();
696700

701+
if (fnConv.hasGuaranteedAddressResult()) {
702+
return expandGuaranteedAddressResult();
703+
}
704+
697705
// Disable the use of sret if we have multiple indirect results.
698706
if (fnConv.getNumIndirectSILResults() > 1)
699707
CanUseSRet = false;
@@ -911,6 +919,11 @@ void SignatureExpansion::expandCoroutineContinuationParameters() {
911919
}
912920
}
913921

922+
void SignatureExpansion::expandGuaranteedAddressResult() {
923+
CanUseSRet = false;
924+
ResultIRType = IGM.PtrTy;
925+
}
926+
914927
void SignatureExpansion::addAsyncParameters() {
915928
// using TaskContinuationFunction =
916929
// SWIFT_CC(swift)
@@ -3933,6 +3946,11 @@ void CallEmission::emitYieldsToExplosion(Explosion &out) {
39333946
}
39343947
}
39353948

3949+
void CallEmission::emitGuaranteedAddressToExplosion(Explosion &out) {
3950+
auto call = emitCallSite();
3951+
out.add(call);
3952+
}
3953+
39363954
/// Emit the result of this call to an explosion.
39373955
void CallEmission::emitToExplosion(Explosion &out, bool isOutlined) {
39383956
assert(state == State::Emitting);
@@ -3948,6 +3966,14 @@ void CallEmission::emitToExplosion(Explosion &out, bool isOutlined) {
39483966

39493967
SILFunctionConventions fnConv(getCallee().getSubstFunctionType(),
39503968
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+
39513977
SILType substResultType =
39523978
fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext());
39533979

@@ -7001,6 +7027,16 @@ void irgen::emitYieldOnceCoroutineResult(IRGenFunction &IGF, Explosion &result,
70017027
}
70027028
}
70037029

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+
70047040
FunctionPointer
70057041
IRGenFunction::getFunctionPointerForResumeIntrinsic(llvm::Value *resume) {
70067042
auto *fnTy = llvm::FunctionType::get(

lib/IRGen/GenCall.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ namespace irgen {
281281
void emitYieldOnceCoroutineResult(IRGenFunction &IGF, Explosion &result,
282282
SILType funcResultType, SILType returnResultType);
283283

284+
void emitGuaranteedAddressResult(IRGenFunction &IGF, Explosion &result,
285+
SILType funcResultType,
286+
SILType returnResultType);
287+
284288
Address emitAutoDiffCreateLinearMapContextWithType(
285289
IRGenFunction &IGF, llvm::Value *topLevelSubcontextMetatype);
286290

lib/IRGen/IRGenSIL.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2032,6 +2032,11 @@ static ArrayRef<SILArgument *> emitEntryPointIndirectReturn(
20322032
SILFunctionConventions fnConv(funcTy, IGF.getSILModule());
20332033
SILType directResultType = IGF.CurSILFn->mapTypeIntoContext(
20342034
fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()));
2035+
2036+
if (fnConv.hasGuaranteedAddressResult()) {
2037+
return entry->getArguments();
2038+
}
2039+
20352040
if (requiresIndirectResult(directResultType)) {
20362041
auto &paramTI = IGF.IGM.getTypeInfo(directResultType);
20372042
auto &retTI =
@@ -3934,7 +3939,11 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) {
39343939

39353940
// For a simple apply, just bind the apply result to the result of the call.
39363941
if (auto apply = dyn_cast<ApplyInst>(i)) {
3937-
setLoweredExplosion(apply, result);
3942+
if (apply->hasGuaranteedAddressResult()) {
3943+
setCorrespondingLoweredValues(apply->getResults(), result);
3944+
} else {
3945+
setLoweredExplosion(apply, result);
3946+
}
39383947
emission->end();
39393948

39403949
// For begin_apply, we have to destructure the call.
@@ -4451,6 +4460,16 @@ static void emitReturnInst(IRGenSILFunction &IGF,
44514460
return;
44524461
}
44534462

4463+
if (conv.hasGuaranteedAddressResult()) {
4464+
assert(IGF.CurSILFn->getLoweredFunctionType()->getLanguage() ==
4465+
SILFunctionLanguage::Swift);
4466+
auto funcResultType = IGF.CurSILFn->mapTypeIntoContext(
4467+
conv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()));
4468+
4469+
emitGuaranteedAddressResult(IGF, result, funcResultType, resultTy);
4470+
return;
4471+
}
4472+
44544473
// The invariant on the out-parameter is that it's always zeroed, so
44554474
// there's nothing to do here.
44564475

0 commit comments

Comments
 (0)