Skip to content

Commit ea0e017

Browse files
authored
Merge pull request #84595 from meg-gupta/moreborrowaccessors
Extend borrow accessor support
2 parents be453cf + 3d74cf4 commit ea0e017

33 files changed

+2038
-136
lines changed

include/swift/AST/DeclAttr.def

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,12 @@ DECL_ATTR(specialized, Specialized,
902902
AllowMultipleAttributes | LongAttribute | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
903903
172)
904904

905-
LAST_DECL_ATTR(Specialized)
905+
SIMPLE_DECL_ATTR(_unsafeSelfDependentResult, UnsafeSelfDependentResult,
906+
OnAccessor,
907+
UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIBreakingToAdd | APIBreakingToRemove | EquivalentInABIAttr,
908+
173)
909+
910+
LAST_DECL_ATTR(UnsafeSelfDependentResult)
906911

907912
#undef DECL_ATTR_ALIAS
908913
#undef CONTEXTUAL_DECL_ATTR_ALIAS

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8946,5 +8946,8 @@ GROUPED_WARNING(perf_hint_closure_returns_array,ReturnTypeImplicitCopy,DefaultIg
89468946
"Performance: closure returns a%select{ dictionary|n array}0, leading to implicit copies. "
89478947
"Consider using an 'inout' parameter instead.", (bool))
89488948

8949+
ERROR(unsafe_self_dependent_result_attr_on_invalid_decl,none,
8950+
"invalid use of @_unsafeSelfDependentResult", ())
8951+
89498952
#define UNDEFINE_DIAGNOSTIC_MACROS
89508953
#include "DefineDiagnosticMacros.h"

include/swift/AST/Types.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5401,6 +5401,13 @@ class SILFunctionType final
54015401
return hasErrorResult() && getErrorResult().isFormalIndirect();
54025402
}
54035403

5404+
bool hasGuaranteedResult() const {
5405+
if (getNumResults() != 1) {
5406+
return false;
5407+
}
5408+
return getResults()[0].isGuaranteedResult();
5409+
}
5410+
54045411
bool hasGuaranteedAddressResult() const {
54055412
if (getNumResults() != 1) {
54065413
return false;

include/swift/SIL/InstructionUtils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ SILValue stripCastsWithoutMarkDependence(SILValue V);
4141
/// begin_borrow instructions.
4242
SILValue lookThroughOwnershipInsts(SILValue v);
4343

44+
SILValue lookThroughMoveOnlyCheckerPattern(SILValue value);
45+
4446
/// Reverse of lookThroughOwnershipInsts.
4547
///
4648
/// Return true if \p visitor returned true for all uses.

include/swift/SIL/MemAccessUtils.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,9 +1809,11 @@ Result AccessUseDefChainVisitor<Impl, Result>::visit(SILValue sourceAddr) {
18091809
return asImpl().visitUnidentified(sourceAddr);
18101810

18111811
if (isGuaranteedAddressReturn(sourceAddr)) {
1812-
return asImpl().visitAccessProjection(
1813-
cast<ApplyInst>(sourceAddr),
1814-
&cast<ApplyInst>(sourceAddr)->getSelfArgumentOperand());
1812+
auto *selfOp = &cast<ApplyInst>(sourceAddr)->getSelfArgumentOperand();
1813+
if (selfOp->get()->getType().isObject()) {
1814+
return asImpl().visitUnidentified(sourceAddr);
1815+
}
1816+
return asImpl().visitAccessProjection(cast<ApplyInst>(sourceAddr), selfOp);
18151817
}
18161818

18171819
// Don't currently allow any other calls to return an accessed address.

include/swift/SIL/SILValue.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,8 @@ class ValueBase : public SILNode, public SILAllocated<ValueBase> {
616616

617617
bool isBeginApplyToken() const;
618618

619+
bool isBorrowAccessorResult() const;
620+
619621
/// Unsafely eliminate moveonly from this value's type. Returns true if the
620622
/// value's underlying type was move only and thus was changed. Returns false
621623
/// otherwise.

lib/AST/ASTDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5062,6 +5062,7 @@ class PrintAttribute : public AttributeVisitor<PrintAttribute, void, Label>,
50625062
TRIVIAL_ATTR_PRINTER(WeakLinked, weak_linked)
50635063
TRIVIAL_ATTR_PRINTER(Nonexhaustive, nonexhaustive)
50645064
TRIVIAL_ATTR_PRINTER(Concurrent, concurrent)
5065+
TRIVIAL_ATTR_PRINTER(UnsafeSelfDependentResult, unsafe_self_dependent_result)
50655066

50665067
#undef TRIVIAL_ATTR_PRINTER
50675068

lib/ASTGen/Sources/ASTGen/DeclAttrs.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,8 @@ extension ASTGenVisitor {
309309
.UsableFromInline,
310310
.Used,
311311
.WarnUnqualifiedAccess,
312-
.WeakLinked:
312+
.WeakLinked,
313+
.UnsafeSelfDependentResult:
313314

314315
return handle(self.generateSimpleDeclAttr(attribute: node, kind: attrKind!))
315316

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)
@@ -3945,6 +3958,11 @@ void CallEmission::emitYieldsToExplosion(Explosion &out) {
39453958
}
39463959
}
39473960

3961+
void CallEmission::emitGuaranteedAddressToExplosion(Explosion &out) {
3962+
auto call = emitCallSite();
3963+
out.add(call);
3964+
}
3965+
39483966
/// Emit the result of this call to an explosion.
39493967
void CallEmission::emitToExplosion(Explosion &out, bool isOutlined) {
39503968
assert(state == State::Emitting);
@@ -3960,6 +3978,14 @@ void CallEmission::emitToExplosion(Explosion &out, bool isOutlined) {
39603978

39613979
SILFunctionConventions fnConv(getCallee().getSubstFunctionType(),
39623980
IGF.getSILModule());
3981+
3982+
if (fnConv.hasGuaranteedAddressResult()) {
3983+
assert(LastArgWritten == 0 &&
3984+
"@guaranteed_addr along with indirect result?");
3985+
emitGuaranteedAddressToExplosion(out);
3986+
return;
3987+
}
3988+
39633989
SILType substResultType =
39643990
fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext());
39653991

@@ -7019,6 +7045,16 @@ void irgen::emitYieldOnceCoroutineResult(IRGenFunction &IGF, Explosion &result,
70197045
}
70207046
}
70217047

7048+
void irgen::emitGuaranteedAddressResult(IRGenFunction &IGF, Explosion &result,
7049+
SILType funcResultType,
7050+
SILType returnResultType) {
7051+
assert(funcResultType == returnResultType);
7052+
assert(funcResultType.isAddress());
7053+
auto &Builder = IGF.Builder;
7054+
Builder.CreateRet(result.claimNext());
7055+
assert(result.empty());
7056+
}
7057+
70227058
FunctionPointer
70237059
IRGenFunction::getFunctionPointerForResumeIntrinsic(llvm::Value *resume) {
70247060
auto *fnTy = llvm::FunctionType::get(

0 commit comments

Comments
 (0)