Skip to content

Commit 809045f

Browse files
authored
Merge pull request #11012 from atrick/silval-silgen
2 parents bafcb2b + 80f8d3e commit 809045f

File tree

7 files changed

+111
-21
lines changed

7 files changed

+111
-21
lines changed

lib/SILGen/SILGenBridging.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,11 @@ static ManagedValue emitNativeToCBridgedNonoptionalValue(SILGenFunction &SGF,
675675

676676
// Put the value into memory if necessary.
677677
assert(v.getType().isTrivial(SGF.SGM.M) || v.hasCleanup());
678-
if (v.getType().isObject()) {
678+
SILModuleConventions silConv(SGF.SGM.M);
679+
// bridgeAnything always takes an indirect argument as @in.
680+
// Since we don't have the SIL type here, check the current SIL stage/mode
681+
// to determine the convention.
682+
if (v.getType().isObject() && silConv.useLoweredAddresses()) {
679683
auto tmp = SGF.emitTemporaryAllocation(loc, v.getType());
680684
v.forwardInto(SGF, loc, tmp);
681685
v = SGF.emitManagedBufferWithCleanup(tmp);

lib/SILGen/SILGenBuilder.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,9 @@ ManagedValue SILGenBuilder::createLoadCopy(SILLocation loc, ManagedValue v,
494494
lowering.emitLoadOfCopy(*this, loc, v.getValue(), IsNotTake);
495495
if (lowering.isTrivial())
496496
return ManagedValue::forUnmanaged(result);
497-
assert(!lowering.isAddressOnly() && "cannot retain an unloadable type");
497+
assert((!lowering.isAddressOnly()
498+
|| !SGF.silConv.useLoweredAddresses()) &&
499+
"cannot retain an unloadable type");
498500
return SGF.emitManagedRValueWithCleanup(result, lowering);
499501
}
500502

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ emitBuiltinCastReference(SILGenFunction &gen,
572572
auto &toTL = gen.getTypeLowering(toTy);
573573
assert(!fromTL.isTrivial() && !toTL.isTrivial() && "expected ref type");
574574

575-
if (fromTL.isLoadable() || toTL.isLoadable()) {
575+
if (!fromTL.isAddress() || !toTL.isAddress()) {
576576
if (auto refCast = gen.B.tryCreateUncheckedRefCast(loc, args[0].getValue(),
577577
toTL.getLoweredType())) {
578578
// Create a reference cast, forwarding the cleanup.
@@ -593,7 +593,7 @@ emitBuiltinCastReference(SILGenFunction &gen,
593593
// more information to the optimizer.
594594
SILValue srcVal = args[0].forward(gen);
595595
SILValue fromAddr;
596-
if (fromTL.isLoadable()) {
596+
if (!fromTL.isAddress()) {
597597
// Move the loadable value into a "source temp". Since the source and
598598
// dest are RC identical, store the reference into the source temp without
599599
// a retain. The cast will load the reference from the source temp and
@@ -610,7 +610,7 @@ emitBuiltinCastReference(SILGenFunction &gen,
610610
gen.B.createUncheckedRefCastAddr(loc, fromAddr, fromTy->getCanonicalType(),
611611
toAddr, toTy->getCanonicalType());
612612
// Forward it along and register a cleanup.
613-
if (toTL.isAddressOnly())
613+
if (toTL.isAddress())
614614
return gen.emitManagedBufferWithCleanup(toAddr);
615615

616616
// Load the destination value.
@@ -630,12 +630,12 @@ static ManagedValue emitBuiltinReinterpretCast(SILGenFunction &gen,
630630
auto &fromTL = gen.getTypeLowering(substitutions[0].getReplacement());
631631
auto &toTL = gen.getTypeLowering(substitutions[1].getReplacement());
632632

633-
// If casting between address-only types, cast the address.
634-
if (!fromTL.isLoadable() || !toTL.isLoadable()) {
633+
// If casting between address types, cast the address.
634+
if (fromTL.isAddress() || toTL.isAddress()) {
635635
SILValue fromAddr;
636636

637-
// If the from value is loadable, move it to a buffer.
638-
if (fromTL.isLoadable()) {
637+
// If the from value is not an address, move it to a buffer.
638+
if (!fromTL.isAddress()) {
639639
fromAddr = gen.emitTemporaryAllocation(loc, args[0].getValue()->getType());
640640
fromTL.emitStore(gen.B, loc, args[0].getValue(), fromAddr,
641641
StoreOwnershipQualifier::Init);
@@ -647,7 +647,7 @@ static ManagedValue emitBuiltinReinterpretCast(SILGenFunction &gen,
647647

648648
// Load and retain the destination value if it's loadable. Leave the cleanup
649649
// on the original value since we don't know anything about it's type.
650-
if (toTL.isLoadable()) {
650+
if (!toTL.isAddress()) {
651651
return gen.emitManagedLoadCopy(loc, toAddr, toTL);
652652
}
653653
// Leave the cleanup on the original value.

lib/SILGen/SILGenConvert.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -462,13 +462,15 @@ SILGenFunction::emitPointerToPointer(SILLocation loc,
462462
SGFContext C) {
463463
auto converter = getASTContext().getConvertPointerToPointerArgument(nullptr);
464464

465-
// The generic function currently always requires indirection, but pointers
466-
// are always loadable.
467-
auto origBuf = emitTemporaryAllocation(loc, input.getType());
468-
B.emitStoreValueOperation(loc, input.forward(*this), origBuf,
469-
StoreOwnershipQualifier::Init);
470-
auto origValue = emitManagedBufferWithCleanup(origBuf);
471-
465+
auto origValue = input;
466+
if (silConv.useLoweredAddresses()) {
467+
// The generic function currently always requires indirection, but pointers
468+
// are always loadable.
469+
auto origBuf = emitTemporaryAllocation(loc, input.getType());
470+
B.emitStoreValueOperation(loc, input.forward(*this), origBuf,
471+
StoreOwnershipQualifier::Init);
472+
origValue = emitManagedBufferWithCleanup(origBuf);
473+
}
472474
// Invoke the conversion intrinsic to convert to the destination type.
473475
auto *M = SGM.M.getSwiftModule();
474476
auto *proto = getPointerProtocol();

lib/SILGen/SILGenExpr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ ManagedValue SILGenFunction::emitManagedRetain(SILLocation loc,
6666
if (v->getType().isObject() &&
6767
v.getOwnershipKind() == ValueOwnershipKind::Trivial)
6868
return ManagedValue::forUnmanaged(v);
69-
assert(!lowering.isAddressOnly() && "cannot retain an unloadable type");
69+
assert((!lowering.isAddressOnly() || !silConv.useLoweredAddresses()) &&
70+
"cannot retain an unloadable type");
7071

7172
v = lowering.emitCopyValue(B, loc, v);
7273
return emitManagedRValueWithCleanup(v, lowering);

test/SILGen/opaque_values_silgen.swift

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -enable-sil-opaque-values -emit-sorted-sil -Xllvm -sil-full-demangle -emit-silgen %s | %FileCheck %s
1+
// RUN: %target-swift-frontend -enable-sil-opaque-values -emit-sorted-sil -Xllvm -sil-full-demangle -emit-silgen %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime
22

33
// UNSUPPORTED: resilient_stdlib
44

@@ -721,7 +721,7 @@ func s340_______captureBox() {
721721
var mutableAddressOnly: EmptyP = AddressOnlyStruct()
722722

723723
func captureEverything() {
724-
s100_________identity((mutableAddressOnly))
724+
_ = s100_________identity((mutableAddressOnly))
725725
}
726726

727727
captureEverything()
@@ -790,6 +790,7 @@ func s350_______addrOnlyIf(x: Bool) -> EmptyP {
790790
func s360________guardEnum<T>(_ e: IndirectEnum<T>) {
791791
do {
792792
guard case .Node(let x) = e else { return }
793+
_ = x
793794
}
794795
}
795796

@@ -819,6 +820,7 @@ func s370_____optToOptCast<T>(_ x : T!) -> T? {
819820
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s380___contextualInitySiSgF'
820821
func s380___contextualInit(_ a : Int?) {
821822
var x: Int! = a
823+
_ = x
822824
}
823825

824826
// Tests opaque call result types
@@ -842,6 +844,7 @@ func s380___contextualInit(_ a : Int?) {
842844
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s390___addrCallResultyxycSglF'
843845
func s390___addrCallResult<T>(_ f: (() -> T)?) {
844846
var x = f?()
847+
_ = x
845848
}
846849

847850
// Tests reabstraction / partial apply of protocols under opaque value mode
@@ -956,6 +959,50 @@ func s440__cleanupEmission<T>(_ x: T) {
956959
_ = x2
957960
}
958961

962+
// Test SILGenBuilder.loadCopy().
963+
// ---
964+
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s450__________lastValxSayxGd_tlF : $@convention(thin) <T> (@owned Array<T>) -> @out T
965+
// CHECK: [[LOAD:%.*]] = load [copy] %34 : $*T
966+
// CHECK: return [[LOAD]] : $T
967+
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s450__________lastValxSayxGd_tlF'
968+
func s450__________lastVal<T>(_ rest: T...) -> T {
969+
var minValue: T
970+
for value in rest {
971+
minValue = value
972+
}
973+
return minValue
974+
}
975+
976+
// Test SILGenFunction::emitPointerToPointer.
977+
// ---
978+
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s460______________fooSRyxGSPyxG1p_tlF : $@convention(thin) <Element> (UnsafePointer<Element>) -> UnsafeBufferPointer<Element> {
979+
// CHECK: [[F:%.*]] = function_ref @_T0s017_convertPointerToB8Argumentq_xs01_B0RzsABR_r0_lF : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : _Pointer, τ_0_1 : _Pointer> (@in τ_0_0) -> @out τ_0_1
980+
// CHECK: apply [[F]]<UnsafePointer<Element>, UnsafePointer<Element>>(%0) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : _Pointer, τ_0_1 : _Pointer> (@in τ_0_0) -> @out τ_0_1
981+
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s460______________fooSRyxGSPyxG1p_tlF'
982+
func s460______________foo<Element>(p: UnsafePointer<Element>) -> UnsafeBufferPointer<Element> {
983+
return UnsafeBufferPointer(start: p, count: 1)
984+
}
985+
986+
// Test emitNativeToCBridgedNonoptionalValue
987+
// ---
988+
// CHECK-objc-LABEL: sil hidden @_T020opaque_values_silgen21s470________nativeToCyXlyp7fromAny_tF : $@convention(thin) (@in Any) -> @owned AnyObject {
989+
// CHECK-objc bb0(%0 : $Any):
990+
// CHECK-objc [[BORROW:%.*]] = begin_borrow %0 : $Any
991+
// CHECK-objc [[SRC:%.*]] = copy_value [[BORROW]] : $Any
992+
// CHECK-objc [[OPEN:%.*]] = open_existential_opaque [[SRC]] : $Any to $@opened
993+
// CHECK-objc [[COPY:%.*]] = copy_value [[OPEN]] : $@opened
994+
// CHECK-objc [[F:%.*]] = function_ref @_T0s27_bridgeAnythingToObjectiveCyXlxlF : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @owned AnyObject
995+
// CHECK-objc [[RET:%.*]] = apply [[F]]<@opened("{{.*}}") Any>([[COPY]]) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @owned AnyObject
996+
// CHECK-objc destroy_value [[SRC]] : $Any
997+
// CHECK-objc destroy_value %0 : $Any
998+
// CHECK-objc return [[RET]] : $AnyObject
999+
// CHECK-objc-LABEL: } // end sil function '_T020opaque_values_silgen21s470________nativeToCyXlyp7fromAny_tF'
1000+
#if _runtime(_ObjC)
1001+
func s470________nativeToC(fromAny any: Any) -> AnyObject {
1002+
return any as AnyObject
1003+
}
1004+
#endif
1005+
9591006
// Tests conditional value casts and correspondingly generated reabstraction thunk, with <T> types
9601007
// ---
9611008
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s999_____condTFromAnyyyp_xtlF : $@convention(thin) <T> (@in Any, @in T) -> () {
@@ -971,7 +1018,7 @@ func s440__cleanupEmission<T>(_ x: T) {
9711018
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s999_____condTFromAnyyyp_xtlF'
9721019
func s999_____condTFromAny<T>(_ x: Any, _ y: T) {
9731020
if let f = x as? (Int, T) -> (Int, T) {
974-
f(42, y)
1021+
_ = f(42, y)
9751022
}
9761023
}
9771024

test/SILGen/opaque_values_silgen_lib.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,40 @@ func s010______PAndS_cases() {
2525
_ = PAndSEnum.A
2626
}
2727

28+
// Test emitBuiltinReinterpretCast.
29+
// ---
30+
// CHECK-LABEL: sil hidden @_T0s21s020__________bitCastq_x_q_m2totr0_lF : $@convention(thin) <T, U> (@in T, @thick U.Type) -> @out U {
31+
// CHECK: [[BORROW:%.*]] = begin_borrow %0 : $T
32+
// CHECK: [[COPY:%.*]] = copy_value [[BORROW]] : $T
33+
// CHECK: [[CAST:%.*]] = unchecked_bitwise_cast [[COPY]] : $T to $U
34+
// CHECK: [[RET:%.*]] = copy_value [[CAST]] : $U
35+
// CHECK: destroy_value [[COPY]] : $T
36+
// CHECK: return [[RET]] : $U
37+
// CHECK-LABEL: } // end sil function '_T0s21s020__________bitCastq_x_q_m2totr0_lF'
38+
func s020__________bitCast<T, U>(_ x: T, to type: U.Type) -> U {
39+
return Builtin.reinterpretCast(x)
40+
}
41+
42+
// Test emitBuiltinCastReference
43+
// ---
44+
// CHECK-LABEL: sil hidden @_T0s21s030__________refCastq_x_q_m2totr0_lF : $@convention(thin) <T, U> (@in T, @thick U.Type) -> @out U {
45+
// CHECK: bb0(%0 : $T, %1 : $@thick U.Type):
46+
// CHECK: [[BORROW:%.*]] = begin_borrow %0 : $T
47+
// CHECK: [[COPY:%.*]] = copy_value [[BORROW]] : $T
48+
// CHECK: [[SRC:%.*]] = alloc_stack $T
49+
// CHECK: store [[COPY]] to [init] [[SRC]] : $*T
50+
// CHECK: [[DEST:%.*]] = alloc_stack $U
51+
// CHECK: unchecked_ref_cast_addr T in [[SRC]] : $*T to U in [[DEST]] : $*U
52+
// CHECK: [[LOAD:%.*]] = load [take] [[DEST]] : $*U
53+
// CHECK: dealloc_stack [[DEST]] : $*U
54+
// CHECK: dealloc_stack [[SRC]] : $*T
55+
// CHECK: destroy_value %0 : $T
56+
// CHECK: return [[LOAD]] : $U
57+
// CHECK-LABEL: } // end sil function '_T0s21s030__________refCastq_x_q_m2totr0_lF'
58+
func s030__________refCast<T, U>(_ x: T, to: U.Type) -> U {
59+
return Builtin.castReference(x)
60+
}
61+
2862
// Init of Empty protocol + Builtin.NativeObject enum (including opaque tuples as a return value)
2963
// ---
3064
// CHECK-LABEL: sil shared [transparent] @_T0s9PAndSEnumO1AABs6EmptyP_p_SStcABmF : $@convention(method) (@in EmptyP, @owned String, @thin PAndSEnum.Type) -> @out PAndSEnum {

0 commit comments

Comments
 (0)