Skip to content

Commit 5d54a7f

Browse files
committed
Merge remote-tracking branch 'origin/main' into rebranch
2 parents 18a5500 + 49865f2 commit 5d54a7f

File tree

9 files changed

+497
-39
lines changed

9 files changed

+497
-39
lines changed

include/swift/SIL/SILFunctionConventions.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ class SILModuleConventions {
5050
friend SILResultInfo;
5151
friend SILFunctionConventions;
5252

53+
static inline bool
54+
isTypeIndirectForIndirectParamConvention(CanType paramTy,
55+
bool loweredAddresses);
56+
5357
static bool isIndirectSILParam(SILParameterInfo param,
5458
bool loweredAddresses);
5559

@@ -97,6 +101,10 @@ class SILModuleConventions {
97101

98102
bool useLoweredAddresses() const { return loweredAddresses; }
99103

104+
bool isTypeIndirectForIndirectParamConvention(CanType paramTy) {
105+
return isTypeIndirectForIndirectParamConvention(paramTy, loweredAddresses);
106+
}
107+
100108
bool isSILIndirect(SILParameterInfo param) const {
101109
return isIndirectSILParam(param, loweredAddresses);
102110
}
@@ -522,6 +530,12 @@ SILModuleConventions::getFunctionConventions(CanSILFunctionType funcTy) {
522530
return SILFunctionConventions(funcTy, *this);
523531
}
524532

533+
inline bool SILModuleConventions::isTypeIndirectForIndirectParamConvention(
534+
CanType paramTy, bool loweredAddresses) {
535+
return (loweredAddresses || paramTy->isOpenedExistentialWithError() ||
536+
paramTy->hasAnyPack());
537+
}
538+
525539
inline bool SILModuleConventions::isIndirectSILParam(SILParameterInfo param,
526540
bool loweredAddresses) {
527541
switch (param.getConvention()) {
@@ -537,8 +551,8 @@ inline bool SILModuleConventions::isIndirectSILParam(SILParameterInfo param,
537551

538552
case ParameterConvention::Indirect_In:
539553
case ParameterConvention::Indirect_In_Guaranteed:
540-
return (loweredAddresses ||
541-
param.getInterfaceType()->isOpenedExistentialWithError());
554+
return isTypeIndirectForIndirectParamConvention(param.getInterfaceType(),
555+
loweredAddresses);
542556
case ParameterConvention::Indirect_Inout:
543557
case ParameterConvention::Indirect_InoutAliasable:
544558
return true;

lib/SIL/IR/SILValue.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,13 +287,17 @@ ValueOwnershipKind::ValueOwnershipKind(const SILFunction &F, SILType Type,
287287
}
288288

289289
switch (Convention) {
290-
case SILArgumentConvention::Indirect_In:
291-
value = moduleConventions.useLoweredAddresses() ? OwnershipKind::None
292-
: OwnershipKind::Owned;
293-
break;
294290
case SILArgumentConvention::Indirect_In_Guaranteed:
295-
value = moduleConventions.useLoweredAddresses() ? OwnershipKind::None
296-
: OwnershipKind::Guaranteed;
291+
value = moduleConventions.isTypeIndirectForIndirectParamConvention(
292+
Type.getASTType())
293+
? OwnershipKind::None
294+
: OwnershipKind::Guaranteed;
295+
break;
296+
case SILArgumentConvention::Indirect_In:
297+
value = moduleConventions.isTypeIndirectForIndirectParamConvention(
298+
Type.getASTType())
299+
? OwnershipKind::None
300+
: OwnershipKind::Owned;
297301
break;
298302
case SILArgumentConvention::Indirect_Inout:
299303
case SILArgumentConvention::Indirect_InoutAliasable:

lib/SILGen/SILGenFunction.cpp

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -650,15 +650,46 @@ void SILGenFunction::emitCaptures(SILLocation loc,
650650

651651
// Get an address value for a SILValue if it is address only in an type
652652
// expansion context without opaque archetype substitution.
653-
auto getAddressValue = [&](SILValue entryValue, bool forceCopy) -> SILValue {
654-
if (SGM.M.useLoweredAddresses()
655-
&& SGM.Types
656-
.getTypeLowering(
657-
valueType,
658-
TypeExpansionContext::noOpaqueTypeArchetypesSubstitution(
659-
expansion.getResilienceExpansion()))
660-
.isAddressOnly()
661-
&& !entryValue->getType().isAddress()) {
653+
auto getAddressValue = [&](SILValue entryValue, bool forceCopy,
654+
bool forLValue) -> SILValue {
655+
if (!SGM.M.useLoweredAddresses() && !forLValue && !isPack) {
656+
// In opaque values mode, addresses aren't used except by lvalues.
657+
auto &lowering = getTypeLowering(entryValue->getType());
658+
if (entryValue->getType().isAddress()) {
659+
// If the value is currently an address, load it, copying if needed.
660+
if (lowering.isTrivial()) {
661+
SILValue result = lowering.emitLoad(
662+
B, loc, entryValue, LoadOwnershipQualifier::Trivial);
663+
return result;
664+
}
665+
if (forceCopy) {
666+
SILValue result =
667+
lowering.emitLoadOfCopy(B, loc, entryValue, IsNotTake);
668+
enterDestroyCleanup(result);
669+
return result;
670+
} else {
671+
auto load = B.createLoadBorrow(
672+
loc, ManagedValue::forBorrowedRValue(entryValue))
673+
.getValue();
674+
return load;
675+
}
676+
} else {
677+
// Otherwise, just return it, copying if needed.
678+
if (forceCopy && !lowering.isTrivial()) {
679+
auto result = B.emitCopyValueOperation(loc, entryValue);
680+
// enterDestroyCleanup(result);
681+
return result;
682+
}
683+
return entryValue;
684+
}
685+
} else if (SGM.M.useLoweredAddresses() &&
686+
SGM.Types
687+
.getTypeLowering(
688+
valueType, TypeExpansionContext::
689+
noOpaqueTypeArchetypesSubstitution(
690+
expansion.getResilienceExpansion()))
691+
.isAddressOnly() &&
692+
!entryValue->getType().isAddress()) {
662693

663694
assert(!isPack);
664695

@@ -684,7 +715,6 @@ void SILGenFunction::emitCaptures(SILLocation loc,
684715
if (!forceCopy)
685716
enterDestroyCleanup(addr);
686717
return addr;
687-
688718
} else if (forceCopy) {
689719
// We cannot pass a valid SILDebugVariable while creating the temp here
690720
// See rdar://60425582
@@ -755,26 +785,38 @@ void SILGenFunction::emitCaptures(SILLocation loc,
755785
if (canGuarantee) {
756786
// No-escaping stored declarations are captured as the
757787
// address of the value.
758-
auto addr = getAddressValue(val, /*forceCopy=*/false);
759-
capturedArgs.push_back(ManagedValue::forBorrowedRValue(addr));
760-
}
761-
else if (!silConv.useLoweredAddresses()) {
762-
capturedArgs.push_back(B.copyOwnedObjectRValue(
763-
loc, val, ManagedValue::ScopeKind::Lexical));
788+
auto addr =
789+
getAddressValue(val, /*forceCopy=*/false, /*forLValue=*/false);
790+
capturedArgs.push_back(
791+
addr->getOwnershipKind() == OwnershipKind::Owned
792+
? ManagedValue::forOwnedRValue(addr, CleanupHandle::invalid())
793+
: ManagedValue::forBorrowedRValue(addr));
764794
} else {
765-
auto addr = getAddressValue(val, /*forceCopy=*/true);
795+
auto addr =
796+
getAddressValue(val, /*forceCopy=*/true, /*forLValue=*/false);
797+
if (!useLoweredAddresses()) {
798+
auto &lowering = getTypeLowering(addr->getType());
799+
auto rvalue =
800+
lowering.isTrivial()
801+
? ManagedValue::forObjectRValueWithoutOwnership(addr)
802+
: ManagedValue::forOwnedRValue(addr,
803+
CleanupHandle::invalid());
804+
capturedArgs.push_back(rvalue);
805+
break;
806+
}
766807
// If our address is move only wrapped, unwrap it.
767808
if (addr->getType().isMoveOnlyWrapped()) {
768809
addr = B.createMoveOnlyWrapperToCopyableAddr(loc, addr);
769810
}
770-
capturedArgs.push_back(ManagedValue::forLValue(addr));
811+
capturedArgs.push_back(ManagedValue::forOwnedAddressRValue(
812+
addr, CleanupHandle::invalid()));
771813
}
772814
break;
773815
}
774816
case CaptureKind::StorageAddress: {
775817
assert(!isPack);
776818

777-
auto addr = getAddressValue(val, /*forceCopy=*/false);
819+
auto addr = getAddressValue(val, /*forceCopy=*/false, /*forLValue=*/true);
778820

779821
// No-escaping stored declarations are captured as the
780822
// address of the value.

lib/SILGen/SILGenProlog.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,12 +1130,13 @@ static void emitCaptureArguments(SILGenFunction &SGF,
11301130
LLVM_FALLTHROUGH;
11311131

11321132
case CaptureKind::Immutable: {
1133+
auto argIndex = SGF.F.begin()->getNumArguments();
11331134
// Non-escaping stored decls are captured as the address of the value.
1134-
auto argConv = SGF.F.getConventions().getSILArgumentConvention(
1135-
SGF.F.begin()->getNumArguments());
1135+
auto argConv = SGF.F.getConventions().getSILArgumentConvention(argIndex);
11361136
bool isInOut = (argConv == SILArgumentConvention::Indirect_Inout ||
11371137
argConv == SILArgumentConvention::Indirect_InoutAliasable);
1138-
if (isInOut || SGF.SGM.M.useLoweredAddresses()) {
1138+
auto param = SGF.F.getConventions().getParamInfoForSILArg(argIndex);
1139+
if (SGF.F.getConventions().isSILIndirect(param)) {
11391140
ty = ty.getAddressType();
11401141
}
11411142
auto *fArg = SGF.F.begin()->createFunctionArgument(ty, VD);

test/SIL/Parser/opaque_values_parse.sil

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,17 +118,20 @@ bb0(%instance : @guaranteed $WeakBox<T>):
118118
// Test tuple_pack_extract parsing.
119119

120120
// CHECK-LABEL: sil [ossa] @test_tuple_pack_extract : {{.*}} {
121-
// CHECK: bb0([[TUPLE:%[^,]+]] :
121+
// CHECK: bb0([[TUPLE_ADDR:%[^,]+]] :
122+
// CHECK: [[TUPLE:%[^,]+]] = load_borrow [[TUPLE_ADDR]]
122123
// CHECK: [[ZERO:%[^,]+]] = integer_literal
123124
// CHECK: [[INDEX:%[^,]+]] = dynamic_pack_index [[ZERO]]
124125
// CHECK: [[ELT:%[^,]+]] = tuple_pack_extract [[INDEX]] of [[TUPLE]]
125126
// CHECK-LABEL: } // end sil function 'test_tuple_pack_extract'
126127
sil [ossa] @test_tuple_pack_extract : $@convention(thin) <each T> (@in_guaranteed (repeat each T)) -> () {
127-
entry(%tuple : @guaranteed $(repeat each T)):
128+
entry(%tuple_addr : $*(repeat each T)):
129+
%tuple = load_borrow %tuple_addr : $*(repeat each T)
128130
%zero = integer_literal $Builtin.Word, 0
129131
%index = dynamic_pack_index %zero of $Pack{repeat each T}
130132
%opened = open_pack_element %index of <each U_1> at <Pack{repeat each T}>, shape $U_1, uuid "00000000-0000-0000-0000-000000000000"
131133
%elt = tuple_pack_extract %index of %tuple : $(repeat each T) as $@pack_element("00000000-0000-0000-0000-000000000000") U_1
134+
end_borrow %tuple : $(repeat each T)
132135
%retval = tuple ()
133136
return %retval : $()
134137
}

test/SIL/Serialization/opaque_values_serialize.sil

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,20 @@ bb0(%instance : @guaranteed $WeakBox<T>):
102102
// Test tuple_pack_extract parsing.
103103

104104
// CHECK-LABEL: sil [ossa] @test_tuple_pack_extract : {{.*}} {
105-
// CHECK: bb0([[TUPLE:%[^,]+]] :
105+
// CHECK: bb0([[TUPLE_ADDR:%[^,]+]] :
106+
// CHECK: [[TUPLE:%[^,]+]] = load_borrow [[TUPLE_ADDR]]
106107
// CHECK: [[ZERO:%[^,]+]] = integer_literal
107108
// CHECK: [[INDEX:%[^,]+]] = dynamic_pack_index [[ZERO]]
108109
// CHECK: [[ELT:%[^,]+]] = tuple_pack_extract [[INDEX]] of [[TUPLE]]
109110
// CHECK-LABEL: } // end sil function 'test_tuple_pack_extract'
110111
sil [ossa] @test_tuple_pack_extract : $@convention(thin) <each T> (@in_guaranteed (repeat each T)) -> () {
111-
entry(%tuple : @guaranteed $(repeat each T)):
112+
entry(%tuple_addr : $*(repeat each T)):
113+
%tuple = load_borrow %tuple_addr : $*(repeat each T)
112114
%zero = integer_literal $Builtin.Word, 0
113115
%index = dynamic_pack_index %zero of $Pack{repeat each T}
114116
%opened = open_pack_element %index of <each U_1> at <Pack{repeat each T}>, shape $U_1, uuid "00000000-0000-0000-0000-000000000000"
115117
%elt = tuple_pack_extract %index of %tuple : $(repeat each T) as $@pack_element("00000000-0000-0000-0000-000000000000") U_1
118+
end_borrow %tuple : $(repeat each T)
116119
%retval = tuple ()
117120
return %retval : $()
118121
}

test/SIL/cloning_opaque_values.sil

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,25 +30,28 @@ bb0(%instance : @guaranteed $WeakBox<T>):
3030
}
3131

3232
// CHECK-LABEL: sil [ossa] @tuple_pack_extract_caller : {{.*}} {
33-
// CHECK: bb0([[TUPLE:%[^,]+]] :
33+
// CHECK: bb0([[TUPLE_ADDR:%[^,]+]] :
34+
// CHECK: [[TUPLE:%[^,]+]] = load_borrow [[TUPLE_ADDR]]
3435
// CHECK: [[ZERO:%[^,]+]] = integer_literal
3536
// CHECK: [[INDEX:%[^,]+]] = dynamic_pack_index [[ZERO]]
3637
// CHECK: open_pack_element [[INDEX]] of <each U_1> at <Pack{repeat each T}>, shape $each U_1, uuid [[UUID:"[A-F0-9\-]+"]]
3738
// CHECK: tuple_pack_extract [[INDEX]] of [[TUPLE]] : $(repeat each T) as $@pack_element([[UUID]]) each U_1
3839
// CHECK-LABEL: } // end sil function 'tuple_pack_extract_caller'
3940
sil [ossa] @tuple_pack_extract_caller : $@convention(thin) <each T> (@in_guaranteed (repeat each T)) -> () {
40-
entry(%tuple : @guaranteed $(repeat each T)):
41+
entry(%tuple_addr : $*(repeat each T)):
4142
%callee = function_ref @tuple_pack_extract : $@convention(thin) <each T> (@in_guaranteed (repeat each T)) -> ()
42-
%retval = apply %callee<Pack{repeat each T}>(%tuple) : $@convention(thin) <each T> (@in_guaranteed (repeat each T)) -> ()
43+
%retval = apply %callee<Pack{repeat each T}>(%tuple_addr) : $@convention(thin) <each T> (@in_guaranteed (repeat each T)) -> ()
4344
return %retval : $()
4445
}
4546

4647
sil [always_inline] [ossa] @tuple_pack_extract : $@convention(thin) <each T> (@in_guaranteed (repeat each T)) -> () {
47-
entry(%tuple : @guaranteed $(repeat each T)):
48+
entry(%tuple_addr : $*(repeat each T)):
49+
%tuple = load_borrow %tuple_addr : $*(repeat each T)
4850
%zero = integer_literal $Builtin.Word, 0
4951
%index = dynamic_pack_index %zero of $Pack{repeat each T}
5052
%opened = open_pack_element %index of <each U_1> at <Pack{repeat each T}>, shape $U_1, uuid "00000000-0000-0000-0000-000000000000"
5153
%elt = tuple_pack_extract %index of %tuple : $(repeat each T) as $@pack_element("00000000-0000-0000-0000-000000000000") U_1
54+
end_borrow %tuple : $(repeat each T)
5255
%retval = tuple ()
5356
return %retval : $()
5457
}

0 commit comments

Comments
 (0)