Skip to content

Commit a4c168e

Browse files
authored
Merge pull request #11038 from atrick/silval
2 parents 133bd85 + 2df98a6 commit a4c168e

File tree

5 files changed

+97
-14
lines changed

5 files changed

+97
-14
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,8 @@ class SILBuilder {
517517
}
518518

519519
LoadBorrowInst *createLoadBorrow(SILLocation Loc, SILValue LV) {
520-
assert(LV->getType().isLoadable(F.getModule()));
520+
assert(!SILModuleConventions(F.getModule()).useLoweredAddresses()
521+
|| LV->getType().isLoadable(F.getModule()));
521522
return insert(new (F.getModule())
522523
LoadBorrowInst(getSILDebugLocation(Loc), LV));
523524
}

lib/SIL/SILVerifier.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
12361236
F.hasQualifiedOwnership(),
12371237
"Inst with qualified ownership in a function that is not qualified");
12381238
require(LBI->getType().isObject(), "Result of load must be an object");
1239-
require(LBI->getType().isLoadable(LBI->getModule()),
1239+
require(!fnConv.useLoweredAddresses()
1240+
|| LBI->getType().isLoadable(LBI->getModule()),
12401241
"Load must have a loadable type");
12411242
require(LBI->getOperand()->getType().isAddress(),
12421243
"Load operand must be an address");

lib/SILGen/SILGenConvert.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -907,12 +907,20 @@ SILGenFunction::emitOpenExistential(
907907

908908
existentialType = existentialValue.getType();
909909
assert(existentialType.isObject());
910+
if (loweredOpenedType.isAddress()) {
911+
archetypeMV = ManagedValue::forUnmanaged(
912+
B.createOpenExistentialBox(loc, existentialValue.getValue(),
913+
loweredOpenedType));
914+
} else {
915+
assert(!silConv.useLoweredAddresses());
916+
archetypeMV = ManagedValue::forUnmanaged(
917+
B.createOpenExistentialBoxValue(loc, existentialValue.getValue(),
918+
loweredOpenedType));
919+
}
910920
// NB: Don't forward the cleanup, because consuming a boxed value won't
911921
// consume the box reference.
912-
archetypeMV = ManagedValue::forUnmanaged(B.createOpenExistentialBox(
913-
loc, existentialValue.getValue(), loweredOpenedType.getAddressType()));
914-
// The boxed value can't be assumed to be uniquely referenced. We can never
915-
// consume it.
922+
// The boxed value can't be assumed to be uniquely referenced.
923+
// We can never consume it.
916924
// TODO: We could use isUniquelyReferenced to shorten the duration of
917925
// the box to the point that the opaque value is copied out.
918926
isUnique = false;

lib/SILGen/SILGenExpr.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ ManagedValue SILGenFunction::emitManagedLoadCopy(SILLocation loc, SILValue v,
8686
return ManagedValue::forUnmanaged(v);
8787
if (v.getOwnershipKind() == ValueOwnershipKind::Trivial)
8888
return ManagedValue::forUnmanaged(v);
89-
assert(!lowering.isAddressOnly() && "cannot retain an unloadable type");
89+
assert((!lowering.isAddressOnly() || !silConv.useLoweredAddresses()) &&
90+
"cannot retain an unloadable type");
9091
return emitManagedRValueWithCleanup(v, lowering);
9192
}
9293

@@ -105,7 +106,8 @@ SILGenFunction::emitManagedLoadBorrow(SILLocation loc, SILValue v,
105106
return ManagedValue::forUnmanaged(v);
106107
}
107108

108-
assert(!lowering.isAddressOnly() && "cannot retain an unloadable type");
109+
assert((!lowering.isAddressOnly() || !silConv.useLoweredAddresses()) &&
110+
"cannot retain an unloadable type");
109111
auto *lbi = B.createLoadBorrow(loc, v);
110112
return emitManagedBorrowedRValueWithCleanup(v, lbi, lowering);
111113
}
@@ -124,7 +126,8 @@ ManagedValue SILGenFunction::emitManagedStoreBorrow(
124126
lowering.emitStore(B, loc, v, addr, StoreOwnershipQualifier::Trivial);
125127
return ManagedValue::forUnmanaged(v);
126128
}
127-
assert(!lowering.isAddressOnly() && "cannot retain an unloadable type");
129+
assert((!lowering.isAddressOnly() || !silConv.useLoweredAddresses()) &&
130+
"cannot retain an unloadable type");
128131
auto *sbi = B.createStoreBorrow(loc, v, addr);
129132
return emitManagedBorrowedRValueWithCleanup(sbi->getSrc(), sbi, lowering);
130133
}
@@ -3989,7 +3992,7 @@ RValue RValueEmitter::visitBindOptionalExpr(BindOptionalExpr *E, SGFContext C) {
39893992
auto &optTL = SGF.getTypeLowering(E->getSubExpr()->getType());
39903993

39913994
ManagedValue optValue;
3992-
if (optTL.isLoadable()) {
3995+
if (!SGF.silConv.useLoweredAddresses() || optTL.isLoadable()) {
39933996
optValue = SGF.emitRValueAsSingleValue(E->getSubExpr());
39943997
} else {
39953998
auto temp = SGF.emitTemporary(E, optTL);

test/SILGen/opaque_values_silgen.swift

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -489,10 +489,9 @@ func s210______compErasure(_ x: Foo & Error) -> Error {
489489
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s220_____openExistBoxSSs5Error_pF : $@convention(thin) (@owned Error) -> @owned String {
490490
// CHECK: bb0([[ARG:%.*]] : $Error):
491491
// CHECK: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
492-
// CHECK: [[OPAQUE_ARG:%.*]] = open_existential_box [[BORROWED_ARG]] : $Error to $*@opened({{.*}}) Error
493-
// CHECK: [[LOAD_ALLOC:%.*]] = load [copy] [[OPAQUE_ARG]]
492+
// CHECK: [[OPAQUE_ARG:%.*]] = open_existential_box_value [[BORROWED_ARG]] : $Error to $@opened({{.*}}) Error
494493
// CHECK: [[ALLOC_OPEN:%.*]] = alloc_stack $@opened({{.*}}) Error
495-
// CHECK: store [[LOAD_ALLOC]] to [init] [[ALLOC_OPEN]]
494+
// CHECK: store_borrow [[OPAQUE_ARG]] to [[ALLOC_OPEN]]
496495
// CHECK: dealloc_stack [[ALLOC_OPEN]]
497496
// CHECK: end_borrow [[BORROWED_ARG]] from [[ARG]]
498497
// CHECK: destroy_value [[ARG]] : $Error
@@ -983,7 +982,7 @@ func s460______________foo<Element>(p: UnsafePointer<Element>) -> UnsafeBufferPo
983982
return UnsafeBufferPointer(start: p, count: 1)
984983
}
985984

986-
// Test emitNativeToCBridgedNonoptionalValue
985+
// Test emitNativeToCBridgedNonoptionalValue.
987986
// ---
988987
// CHECK-objc-LABEL: sil hidden @_T020opaque_values_silgen21s470________nativeToCyXlyp7fromAny_tF : $@convention(thin) (@in Any) -> @owned AnyObject {
989988
// CHECK-objc bb0(%0 : $Any):
@@ -1003,6 +1002,77 @@ func s470________nativeToC(fromAny any: Any) -> AnyObject {
10031002
}
10041003
#endif
10051004

1005+
// Test emitOpenExistential.
1006+
// ---
1007+
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s480_________getErroryps0F0_p04someF0_tF : $@convention(thin) (@owned Error) -> @out Any {
1008+
// CHECK: bb0(%0 : $Error):
1009+
// CHECK: [[BORROW:%.*]] = begin_borrow %0 : $Error
1010+
// CHECK: [[VAL:%.*]] = open_existential_box_value [[BORROW]] : $Error to $@opened("{{.*}}") Error
1011+
// CHECK: [[COPY:%.*]] = copy_value [[VAL]] : $@opened("{{.*}}") Error
1012+
// CHECK: [[ANY:%.*]] = init_existential_value [[COPY]] : $@opened("{{.*}}") Error, $@opened("{{.*}}") Error, $Any
1013+
// CHECK: destroy_value %0 : $Error
1014+
// CHECK: return [[ANY]] : $Any
1015+
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s480_________getErroryps0F0_p04someF0_tF'
1016+
func s480_________getError(someError: Error) -> Any {
1017+
return someError
1018+
}
1019+
1020+
// Test SILBuilder.createLoadBorrow.
1021+
// ---
1022+
// CHECK-LABEL: sil private @_T020opaque_values_silgen21s490_______loadBorrowyyF3FooL_V3foo7ElementQzSg5IndexQz3pos_tF : $@convention(method) <Elements where Elements : Collection> (@in Elements.Index, @inout Foo<Elements>) -> @out Optional<Elements.Element> {
1023+
// CHECK: bb0(%0 : $Elements.Index, %1 : $*Foo<Elements>):
1024+
// CHECK: [[READ:%.*]] = begin_access [read] [unknown] %1 : $*Foo<Elements>
1025+
// CHECK: [[LOAD:%.*]] = load_borrow [[READ]] : $*Foo<Elements>
1026+
// CHECK: end_access [[READ]] : $*Foo<Elements>
1027+
// CHECK: [[EXTRACT:%.*]] = struct_extract [[LOAD]] : $Foo<Elements>, #<abstract function>Foo._elements
1028+
// CHECK: [[COPYELT:%.*]] = copy_value [[EXTRACT]] : $Elements
1029+
// CHECK: [[BORROW:%.*]] = begin_borrow %0 : $Elements.Index
1030+
// CHECK: [[COPYIDX:%.*]] = copy_value [[BORROW]] : $Elements.Index
1031+
// CHECK: [[WT:%.*]] = witness_method $Elements, #Collection.subscript!getter.1 : <Self where Self : Collection> (Self) -> (Self.Index) -> Self.Element : $@convention(witness_method) <τ_0_0 where τ_0_0 : Collection> (@in τ_0_0.Index, @in_guaranteed τ_0_0) -> @out τ_0_0.Element
1032+
// CHECK: %{{.*}} = apply [[WT]]<Elements>([[COPYIDX]], [[COPYELT]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Collection> (@in τ_0_0.Index, @in_guaranteed τ_0_0) -> @out τ_0_0.Element
1033+
// CHECK: destroy_value [[COPYELT]] : $Elements
1034+
// CHECK: [[ENUM:%.*]] = enum $Optional<Elements.Element>, #Optional.some!enumelt.1, %12 : $Elements.Element
1035+
// CHECK: end_borrow [[BORROW]] from %0 : $Elements.Index, $Elements.Index
1036+
// CHECK: end_borrow [[LOAD]] from [[READ]] : $Foo<Elements>, $*Foo<Elements>
1037+
// CHECK: destroy_value %0 : $Elements.Index
1038+
// CHECK: return %14 : $Optional<Elements.Element>
1039+
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s490_______loadBorrowyyF3FooL_V3foo7ElementQzSg5IndexQz3pos_tF'
1040+
1041+
func s490_______loadBorrow() {
1042+
struct Foo<Elements : Collection> {
1043+
internal let _elements: Elements
1044+
1045+
public mutating func foo(pos: Elements.Index) -> Elements.Element? {
1046+
return _elements[pos]
1047+
}
1048+
}
1049+
var foo = Foo(_elements: [])
1050+
_ = foo.foo(pos: 1)
1051+
}
1052+
1053+
protocol ConvertibleToP {
1054+
func asP() -> P
1055+
}
1056+
1057+
// Test visitBindOptionalExpr
1058+
// ---
1059+
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s500_______getAnyHashAA1P_pSgAA14ConvertibleToP_pSgF : $@convention(thin) (@in Optional<ConvertibleToP>) -> @out Optional<P> {
1060+
// CHECK: bb0(%0 : $Optional<ConvertibleToP>):
1061+
// CHECK: [[BORROW:%.*]] = begin_borrow %0 : $Optional<ConvertibleToP>
1062+
// CHECK: [[COPY:%.*]] = copy_value [[BORROW]] : $Optional<ConvertibleToP>
1063+
// CHECK: [[DATA:%.*]] = unchecked_enum_data [[COPY]] : $Optional<ConvertibleToP>, #Optional.some!enumelt.1
1064+
// CHECK: [[VAL:%.*]] = open_existential_value [[DATA]] : $ConvertibleToP to $@opened("{{.*}}") ConvertibleToP
1065+
// CHECK: [[WT:%.*]] = witness_method $@opened("{{.*}}") ConvertibleToP, #ConvertibleToP.asP!1 : <Self where Self : ConvertibleToP> (Self) -> () -> P, %12 : $@opened("{{.*}}") ConvertibleToP : $@convention(witness_method) <τ_0_0 where τ_0_0 : ConvertibleToP> (@in_guaranteed τ_0_0) -> @out P
1066+
// CHECK: [[AS_P:%.*]] = apply [[WT]]<@opened("{{.*}}") ConvertibleToP>(%12) : $@convention(witness_method) <τ_0_0 where τ_0_0 : ConvertibleToP> (@in_guaranteed τ_0_0) -> @out P
1067+
// CHECK: [[ENUM:%.*]] = enum $Optional<P>, #Optional.some!enumelt.1, [[AS_P]] : $P
1068+
// CHECK: destroy_value [[DATA]] : $ConvertibleToP
1069+
// CHECK: end_borrow [[BORROW]] from %0 : $Optional<ConvertibleToP>, $Optional<ConvertibleToP>
1070+
// CHECK: br bb{{.*}}([[ENUM]] : $Optional<P>)
1071+
// CHECK: // end sil function '_T020opaque_values_silgen21s500_______getAnyHashAA1P_pSgAA14ConvertibleToP_pSgF'
1072+
func s500_______getAnyHash(_ value: ConvertibleToP?) -> P? {
1073+
return value?.asP()
1074+
}
1075+
10061076
// Tests conditional value casts and correspondingly generated reabstraction thunk, with <T> types
10071077
// ---
10081078
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s999_____condTFromAnyyyp_xtlF : $@convention(thin) <T> (@in Any, @in T) -> () {

0 commit comments

Comments
 (0)