Skip to content

Commit a0c939b

Browse files
committed
Use @inout result convention for mutate accessors
1 parent 25af944 commit a0c939b

File tree

24 files changed

+128
-42
lines changed

24 files changed

+128
-42
lines changed

SwiftCompilerSources/Sources/SIL/Argument.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,8 @@ public enum ArgumentConvention : CustomStringConvertible {
488488
self = .directUnowned
489489
case .pack:
490490
self = .packOut
491-
case .guaranteed, .guaranteedAddress:
492-
fatalError("Result conventions @guaranteed and @guaranteed_addr are always returned directly")
491+
case .guaranteed, .guaranteedAddress, .inout:
492+
fatalError("Result conventions @guaranteed, @guaranteed_addr and @inout are always returned directly")
493493
}
494494
}
495495

SwiftCompilerSources/Sources/SIL/FunctionConvention.swift

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,17 @@ public struct FunctionConvention : CustomStringConvertible {
112112
return results[0].convention == .guaranteedAddress
113113
}
114114

115+
public var hasInoutResult: Bool {
116+
if results.count != 1 {
117+
return false
118+
}
119+
return results[0].convention == .inout
120+
}
121+
122+
public var hasAddressResult: Bool {
123+
return hasGuaranteedAddressResult || hasInoutResult
124+
}
125+
115126
public var description: String {
116127
var str = functionType.description
117128
for paramIdx in 0..<parameters.count {
@@ -147,7 +158,7 @@ public struct ResultInfo : CustomStringConvertible {
147158
return hasLoweredAddresses || type.isExistentialArchetypeWithError()
148159
case .pack:
149160
return true
150-
case .owned, .unowned, .unownedInnerPointer, .autoreleased, .guaranteed, .guaranteedAddress:
161+
case .owned, .unowned, .unownedInnerPointer, .autoreleased, .guaranteed, .guaranteedAddress, .inout:
151162
return false
152163
}
153164
}
@@ -373,13 +384,17 @@ public enum ResultConvention : CustomStringConvertible {
373384
case owned
374385

375386
/// The caller is responsible for using the returned address within a valid
376-
/// scope. This is valid only for borrow and mutate accessors.
387+
/// scope. This is valid only for borrow accessors.
377388
case guaranteedAddress
378389

379390
/// The caller is responsible for using the returned value within a valid
380391
/// scope. This is valid only for borrow accessors.
381392
case guaranteed
382393

394+
/// The caller is responsible for mutating the returned address within a valid
395+
/// scope. This is valid only for mutate accessors.
396+
case `inout`
397+
383398
/// The caller is not responsible for destroying this return value. Its type may be trivial, or it may simply be offered unsafely. It is valid at the instant of the return, but further operations may invalidate it.
384399
case unowned
385400

@@ -423,6 +438,8 @@ public enum ResultConvention : CustomStringConvertible {
423438
return "guaranteed"
424439
case .guaranteedAddress:
425440
return "guaranteedAddress"
441+
case .inout:
442+
return "inout"
426443
}
427444
}
428445
}
@@ -456,6 +473,7 @@ extension ResultConvention {
456473
case .Pack: self = .pack
457474
case .Guaranteed: self = .guaranteed
458475
case .GuaranteedAddress: self = .guaranteedAddress
476+
case .Inout: self = .inout
459477
default:
460478
fatalError("unsupported result convention")
461479
}

include/swift/AST/Types.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4814,12 +4814,16 @@ enum class ResultConvention : uint8_t {
48144814
Pack,
48154815

48164816
/// The caller is responsible for using the returned address within a valid
4817-
/// scope. This is valid only for borrow and mutate accessors.
4817+
/// scope. This is valid only for borrow accessors.
48184818
GuaranteedAddress,
48194819

48204820
/// The caller is responsible for using the returned value within a valid
48214821
/// scope. This is valid only for borrow accessors.
48224822
Guaranteed,
4823+
4824+
/// The caller is responsible for mutating the returned address within a valid
4825+
/// scope. This is valid only for mutate accessors.
4826+
Inout,
48234827
};
48244828

48254829
// Does this result require indirect storage for the purpose of reabstraction?
@@ -4980,6 +4984,14 @@ class SILResultInfo {
49804984
return getConvention() == ResultConvention::GuaranteedAddress;
49814985
}
49824986

4987+
bool isInoutResult() const {
4988+
return getConvention() == ResultConvention::Inout;
4989+
}
4990+
4991+
bool isAddressResult() const {
4992+
return isGuaranteedAddressResult() || isInoutResult();
4993+
}
4994+
49834995
bool isGuaranteedResult() const {
49844996
return getConvention() == ResultConvention::Guaranteed;
49854997
}
@@ -5438,6 +5450,17 @@ class SILFunctionType final
54385450
return getResults()[0].isGuaranteedAddressResult();
54395451
}
54405452

5453+
bool hasInoutResult() const {
5454+
if (getNumResults() != 1) {
5455+
return false;
5456+
}
5457+
return getResults()[0].isInoutResult();
5458+
}
5459+
5460+
bool hasAddressResult() const {
5461+
return hasGuaranteedAddressResult() || hasInoutResult();
5462+
}
5463+
54415464
struct IndirectFormalResultFilter {
54425465
bool operator()(SILResultInfo result) const {
54435466
return result.isFormalIndirect();

include/swift/SIL/SILBridging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ enum class BridgedResultConvention {
110110
Pack,
111111
GuaranteedAddress,
112112
Guaranteed,
113+
Inout
113114
};
114115

115116
struct BridgedResultInfo {

include/swift/SIL/SILFunctionConventions.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,17 @@ class SILFunctionConventions {
334334
ResultConvention::GuaranteedAddress;
335335
}
336336

337+
bool hasInoutResult() const {
338+
if (funcTy->getNumResults() != 1) {
339+
return false;
340+
}
341+
return funcTy->getResults()[0].getConvention() == ResultConvention::Inout;
342+
}
343+
344+
bool hasAddressResult() const {
345+
return hasGuaranteedAddressResult() || hasInoutResult();
346+
}
347+
337348
struct SILResultTypeFunc;
338349

339350
// Gratuitous template parameter is to delay instantiating `mapped_iterator`
@@ -675,6 +686,7 @@ inline bool SILModuleConventions::isIndirectSILResult(SILResultInfo result,
675686
case ResultConvention::Autoreleased:
676687
case ResultConvention::GuaranteedAddress:
677688
case ResultConvention::Guaranteed:
689+
case ResultConvention::Inout:
678690
return false;
679691
}
680692

@@ -699,7 +711,7 @@ inline SILType
699711
SILModuleConventions::getSILResultInterfaceType(SILResultInfo result,
700712
bool loweredAddresses) {
701713
return SILModuleConventions::isIndirectSILResult(result, loweredAddresses) ||
702-
result.isGuaranteedAddressResult()
714+
result.isAddressResult()
703715
? SILType::getPrimitiveAddressType(result.getInterfaceType())
704716
: SILType::getPrimitiveObjectType(result.getInterfaceType());
705717
}

include/swift/SIL/SILInstruction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3157,6 +3157,10 @@ class ApplyInst final
31573157
bool hasGuaranteedAddressResult() const {
31583158
return getSubstCalleeConv().hasGuaranteedAddressResult();
31593159
}
3160+
bool hasInoutResult() const { return getSubstCalleeConv().hasInoutResult(); }
3161+
bool hasAddressResult() const {
3162+
return getSubstCalleeConv().hasAddressResult();
3163+
}
31603164
};
31613165

31623166
/// PartialApplyInst - Represents the creation of a closure object by partial

lib/AST/ASTPrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7944,6 +7944,8 @@ static StringRef getStringForResultConvention(ResultConvention conv) {
79447944
return "@guaranteed_addr ";
79457945
case ResultConvention::Guaranteed:
79467946
return "@guaranteed ";
7947+
case ResultConvention::Inout:
7948+
return "@inout ";
79477949
}
79487950
llvm_unreachable("bad result convention");
79497951
}

lib/IRGen/CallEmission.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +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);
106+
void emitAddressResultToExplosion(Explosion &out);
107107
void setKeyPathAccessorArguments(Explosion &in, bool isOutlined,
108108
Explosion &out);
109109
virtual FunctionPointer getCalleeFunctionPointer() = 0;

lib/IRGen/GenCall.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -592,9 +592,8 @@ namespace {
592592
/// function type.
593593
void expandCoroutineContinuationType();
594594

595-
/// Initializes the result type for functions with @guaranteed_addr return
596-
/// convention.
597-
void expandGuaranteedAddressResult();
595+
/// Initializes the result type for borrow and mutate accessors.
596+
void expandAddressResult();
598597

599598
// Expand the components for the async continuation entrypoint of the
600599
// function type (the function to be called on returning).
@@ -699,8 +698,8 @@ void SignatureExpansion::expandResult(
699698

700699
auto fnConv = getSILFuncConventions();
701700

702-
if (fnConv.hasGuaranteedAddressResult()) {
703-
return expandGuaranteedAddressResult();
701+
if (fnConv.hasAddressResult()) {
702+
return expandAddressResult();
704703
}
705704

706705
// Disable the use of sret if we have multiple indirect results.
@@ -920,7 +919,7 @@ void SignatureExpansion::expandCoroutineContinuationParameters() {
920919
}
921920
}
922921

923-
void SignatureExpansion::expandGuaranteedAddressResult() {
922+
void SignatureExpansion::expandAddressResult() {
924923
CanUseSRet = false;
925924
ResultIRType = IGM.PtrTy;
926925
}
@@ -3959,7 +3958,7 @@ void CallEmission::emitYieldsToExplosion(Explosion &out) {
39593958
}
39603959
}
39613960

3962-
void CallEmission::emitGuaranteedAddressToExplosion(Explosion &out) {
3961+
void CallEmission::emitAddressResultToExplosion(Explosion &out) {
39633962
auto call = emitCallSite();
39643963
out.add(call);
39653964
}
@@ -3980,10 +3979,10 @@ void CallEmission::emitToExplosion(Explosion &out, bool isOutlined) {
39803979
SILFunctionConventions fnConv(getCallee().getSubstFunctionType(),
39813980
IGF.getSILModule());
39823981

3983-
if (fnConv.hasGuaranteedAddressResult()) {
3982+
if (fnConv.hasAddressResult()) {
39843983
assert(LastArgWritten == 0 &&
3985-
"@guaranteed_addr along with indirect result?");
3986-
emitGuaranteedAddressToExplosion(out);
3984+
"@guaranteed_addr/@inout along with indirect result?");
3985+
emitAddressResultToExplosion(out);
39873986
return;
39883987
}
39893988

@@ -6832,9 +6831,9 @@ void irgen::emitYieldOnceCoroutineResult(IRGenFunction &IGF, Explosion &result,
68326831
}
68336832
}
68346833

6835-
void irgen::emitGuaranteedAddressResult(IRGenFunction &IGF, Explosion &result,
6836-
SILType funcResultType,
6837-
SILType returnResultType) {
6834+
void irgen::emitAddressResult(IRGenFunction &IGF, Explosion &result,
6835+
SILType funcResultType,
6836+
SILType returnResultType) {
68386837
assert(funcResultType == returnResultType);
68396838
assert(funcResultType.isAddress());
68406839
auto &Builder = IGF.Builder;

lib/IRGen/GenCall.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,8 @@ namespace irgen {
278278
void emitYieldOnceCoroutineResult(IRGenFunction &IGF, Explosion &result,
279279
SILType funcResultType, SILType returnResultType);
280280

281-
void emitGuaranteedAddressResult(IRGenFunction &IGF, Explosion &result,
282-
SILType funcResultType,
283-
SILType returnResultType);
281+
void emitAddressResult(IRGenFunction &IGF, Explosion &result,
282+
SILType funcResultType, SILType returnResultType);
284283

285284
Address emitAutoDiffCreateLinearMapContextWithType(
286285
IRGenFunction &IGF, llvm::Value *topLevelSubcontextMetatype);

0 commit comments

Comments
 (0)