@@ -171,13 +171,19 @@ namespace {
171
171
// RetTy handleTrivial(CanType);
172
172
// RetTy handleTrivial(CanType, RecursiveProperties properties);
173
173
// // A reference type.
174
+ // RetTy handleReference(CanType);
174
175
// RetTy handleReference(CanType, RecursiveProperties properties);
175
- // RetTy handleReference(CanType, RecursiveProperties properties);
176
+ // // Non-trivial, move only, loadable
177
+ // RetTy handleMoveOnlyReference(CanType, RecursiveProperties properties);
178
+ // // Non-trivial, move only, address only
179
+ // RetTy handleMoveOnlyAddressOnly(CanType, RecursiveProperties
180
+ // properties);
176
181
// // Non-trivial and address-only.
177
182
// RetTy handleAddressOnly(CanType, RecursiveProperties properties);
178
183
// and, if it doesn't override handleTupleType,
179
184
// // An aggregate type that's non-trivial.
180
- // RetTy handleNonTrivialAggregate(CanType, RecursiveProperties properties);
185
+ // RetTy handleNonTrivialAggregate(CanType, RecursiveProperties
186
+ // properties);
181
187
//
182
188
// Alternatively, it can just implement:
183
189
// RetTy handle(CanType, RecursiveProperties properties);
@@ -208,6 +214,16 @@ namespace {
208
214
return asImpl ().handle (type, properties);
209
215
}
210
216
217
+ RetTy handleMoveOnlyReference (CanType type,
218
+ RecursiveProperties properties) {
219
+ return asImpl ().handle (type, properties);
220
+ }
221
+
222
+ RetTy handleMoveOnlyAddressOnly (CanType type,
223
+ RecursiveProperties properties) {
224
+ return asImpl ().handle (type, properties);
225
+ }
226
+
211
227
RecursiveProperties
212
228
mergeIsTypeExpansionSensitive (IsTypeExpansionSensitive_t isSensitive,
213
229
RecursiveProperties props) {
@@ -228,12 +244,24 @@ namespace {
228
244
RecursiveProperties::forReference ());
229
245
}
230
246
247
+ RecursiveProperties getMoveOnlyReferenceRecursiveProperties (
248
+ IsTypeExpansionSensitive_t isSensitive) {
249
+ return mergeIsTypeExpansionSensitive (isSensitive,
250
+ RecursiveProperties::forReference ());
251
+ }
252
+
231
253
RecursiveProperties
232
254
getOpaqueRecursiveProperties (IsTypeExpansionSensitive_t isSensitive) {
233
255
return mergeIsTypeExpansionSensitive (isSensitive,
234
256
RecursiveProperties::forOpaque ());
235
257
}
236
258
259
+ RecursiveProperties getMoveOnlyOpaqueRecursiveProperties (
260
+ IsTypeExpansionSensitive_t isSensitive) {
261
+ return mergeIsTypeExpansionSensitive (
262
+ isSensitive, RecursiveProperties::forMoveOnlyOpaque ());
263
+ }
264
+
237
265
#define IMPL (TYPE, LOWERING ) \
238
266
RetTy visit##TYPE##Type(Can##TYPE##Type type, AbstractionPattern orig, \
239
267
IsTypeExpansionSensitive_t isSensitive) { \
@@ -669,9 +697,19 @@ namespace {
669
697
RetTy visitSILMoveOnlyType (CanSILMoveOnlyType type,
670
698
AbstractionPattern origType,
671
699
IsTypeExpansionSensitive_t isSensitive) {
672
- return asImpl ().handleReference (
673
- type->getInnerType ()->getCanonicalType (),
674
- getReferenceRecursiveProperties (isSensitive));
700
+ AbstractionPattern innerAbstraction = origType.withoutMoveOnly ();
701
+ CanType innerType = type->getInnerType ();
702
+ auto &lowering =
703
+ TC.getTypeLowering (innerAbstraction, innerType, Expansion);
704
+ if (lowering.isAddressOnly ()) {
705
+ return asImpl ().handleMoveOnlyAddressOnly (
706
+ type->getCanonicalType (),
707
+ getMoveOnlyOpaqueRecursiveProperties (isSensitive));
708
+ }
709
+
710
+ return asImpl ().handleMoveOnlyReference (
711
+ type->getCanonicalType (),
712
+ getMoveOnlyReferenceRecursiveProperties (isSensitive));
675
713
}
676
714
677
715
RetTy handleAggregateByProperties (CanType type, RecursiveProperties props) {
@@ -1477,6 +1515,37 @@ namespace {
1477
1515
}
1478
1516
};
1479
1517
1518
+ // / A class for move only types which are non-trivial and loadable
1519
+ class MoveOnlyReferenceTypeLowering : public LeafLoadableTypeLowering {
1520
+ public:
1521
+ MoveOnlyReferenceTypeLowering (SILType type, RecursiveProperties properties,
1522
+ TypeExpansionContext forExpansion)
1523
+ : LeafLoadableTypeLowering(type, properties, IsReferenceCounted,
1524
+ forExpansion) {}
1525
+
1526
+ SILValue emitCopyValue (SILBuilder &B, SILLocation loc,
1527
+ SILValue value) const override {
1528
+ if (isa<FunctionRefInst>(value) || isa<DynamicFunctionRefInst>(value) ||
1529
+ isa<PreviousDynamicFunctionRefInst>(value))
1530
+ return value;
1531
+
1532
+ if (B.getFunction ().hasOwnership ())
1533
+ return B.createCopyValue (loc, value);
1534
+
1535
+ B.createStrongRetain (loc, value, B.getDefaultAtomicity ());
1536
+ return value;
1537
+ }
1538
+
1539
+ void emitDestroyValue (SILBuilder &B, SILLocation loc,
1540
+ SILValue value) const override {
1541
+ if (B.getFunction ().hasOwnership ()) {
1542
+ B.createDestroyValue (loc, value);
1543
+ return ;
1544
+ }
1545
+ B.createStrongRelease (loc, value, B.getDefaultAtomicity ());
1546
+ }
1547
+ };
1548
+
1480
1549
// / A type lowering for loadable @unowned types.
1481
1550
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE (Name, ...) \
1482
1551
class Loadable ##Name##TypeLowering final : public LeafLoadableTypeLowering { \
@@ -1590,6 +1659,93 @@ namespace {
1590
1659
}
1591
1660
};
1592
1661
1662
+ // / A class for non-trivial, address-only, move only types.
1663
+ class MoveOnlyAddressOnlyTypeLowering : public TypeLowering {
1664
+ public:
1665
+ MoveOnlyAddressOnlyTypeLowering (SILType type,
1666
+ RecursiveProperties properties,
1667
+ TypeExpansionContext forExpansion)
1668
+ : TypeLowering(type, properties, IsNotReferenceCounted, forExpansion) {
1669
+ assert (properties.isAddressOnly ());
1670
+ }
1671
+
1672
+ void emitCopyInto (SILBuilder &B, SILLocation loc, SILValue src,
1673
+ SILValue dest, IsTake_t isTake,
1674
+ IsInitialization_t isInit) const override {
1675
+ assert ((B.getModule ().getStage () == SILStage::Raw || isTake == true ) &&
1676
+ " Can only copy move only values in Raw SIL" );
1677
+ B.createCopyAddr (loc, src, dest, isTake, isInit);
1678
+ }
1679
+
1680
+ SILValue emitLoadOfCopy (SILBuilder &B, SILLocation loc, SILValue addr,
1681
+ IsTake_t isTake) const override {
1682
+ llvm_unreachable (" calling emitLoadOfCopy on non-loadable type" );
1683
+ }
1684
+
1685
+ void emitStoreOfCopy (SILBuilder &B, SILLocation loc, SILValue newValue,
1686
+ SILValue addr,
1687
+ IsInitialization_t isInit) const override {
1688
+ llvm_unreachable (" calling emitStoreOfCopy on non-loadable type" );
1689
+ }
1690
+
1691
+ void emitStore (SILBuilder &B, SILLocation loc, SILValue value,
1692
+ SILValue addr, StoreOwnershipQualifier qual) const override {
1693
+ llvm_unreachable (" calling emitStore on non-loadable type" );
1694
+ }
1695
+
1696
+ SILValue emitLoad (SILBuilder &B, SILLocation loc, SILValue addr,
1697
+ LoadOwnershipQualifier qual) const override {
1698
+ llvm_unreachable (" calling emitLoad on non-loadable type" );
1699
+ }
1700
+
1701
+ SILValue emitLoweredLoad (SILBuilder &B, SILLocation loc, SILValue addr,
1702
+ LoadOwnershipQualifier qual,
1703
+ Lowering::TypeLowering::TypeExpansionKind
1704
+ expansionKind) const override {
1705
+ llvm_unreachable (" calling emitLoweredLoad on non-loadable type?!" );
1706
+ }
1707
+
1708
+ void emitLoweredStore (SILBuilder &B, SILLocation loc, SILValue value,
1709
+ SILValue addr, StoreOwnershipQualifier qual,
1710
+ Lowering::TypeLowering::TypeExpansionKind
1711
+ expansionKind) const override {
1712
+ llvm_unreachable (" calling emitLoweredStore on non-loadable type?!" );
1713
+ }
1714
+
1715
+ void emitDestroyAddress (SILBuilder &B, SILLocation loc,
1716
+ SILValue addr) const override {
1717
+ if (!isTrivial ())
1718
+ B.createDestroyAddr (loc, addr);
1719
+ }
1720
+
1721
+ void emitDestroyRValue (SILBuilder &B, SILLocation loc,
1722
+ SILValue value) const override {
1723
+ if (!isTrivial ())
1724
+ B.createDestroyAddr (loc, value);
1725
+ }
1726
+
1727
+ SILValue emitCopyValue (SILBuilder &B, SILLocation loc,
1728
+ SILValue value) const override {
1729
+ llvm_unreachable (" type is not loadable!" );
1730
+ }
1731
+
1732
+ SILValue emitLoweredCopyValue (SILBuilder &B, SILLocation loc,
1733
+ SILValue value,
1734
+ TypeExpansionKind style) const override {
1735
+ llvm_unreachable (" type is not loadable!" );
1736
+ }
1737
+
1738
+ void emitDestroyValue (SILBuilder &B, SILLocation loc,
1739
+ SILValue value) const override {
1740
+ llvm_unreachable (" type is not loadable!" );
1741
+ }
1742
+
1743
+ void emitLoweredDestroyValue (SILBuilder &B, SILLocation loc, SILValue value,
1744
+ TypeExpansionKind style) const override {
1745
+ llvm_unreachable (" type is not loadable!" );
1746
+ }
1747
+ };
1748
+
1593
1749
// / A class for Builtin.UnsafeValueBuffer. The only purpose here is
1594
1750
// / to catch obviously broken attempts to copy or destroy the buffer.
1595
1751
class UnsafeValueBufferTypeLowering : public AddressOnlyTypeLowering {
@@ -1671,6 +1827,51 @@ namespace {
1671
1827
}
1672
1828
};
1673
1829
1830
+ // / Lower address only types as opaque values.
1831
+ // /
1832
+ // / Opaque values behave like loadable leaf types in SIL.
1833
+ // /
1834
+ // / FIXME: When you remove an unreachable, just delete the method.
1835
+ class MoveOnlyOpaqueValueTypeLowering : public LeafLoadableTypeLowering {
1836
+ public:
1837
+ MoveOnlyOpaqueValueTypeLowering (SILType type,
1838
+ RecursiveProperties properties,
1839
+ TypeExpansionContext forExpansion)
1840
+ : LeafLoadableTypeLowering(type, properties, IsNotReferenceCounted,
1841
+ forExpansion) {}
1842
+
1843
+ void emitCopyInto (SILBuilder &B, SILLocation loc, SILValue src,
1844
+ SILValue dest, IsTake_t isTake,
1845
+ IsInitialization_t isInit) const override {
1846
+ llvm_unreachable (" copy into" );
1847
+ }
1848
+
1849
+ // --- Same as LeafLoadableTypeLowering.
1850
+
1851
+ SILValue emitLoweredCopyValue (SILBuilder &B, SILLocation loc,
1852
+ SILValue value,
1853
+ TypeExpansionKind style) const override {
1854
+ llvm_unreachable (" lowered copy" );
1855
+ }
1856
+
1857
+ void emitLoweredDestroyValue (SILBuilder &B, SILLocation loc, SILValue value,
1858
+ TypeExpansionKind style) const override {
1859
+ llvm_unreachable (" destroy value" );
1860
+ }
1861
+
1862
+ SILValue emitCopyValue (SILBuilder &B, SILLocation loc,
1863
+ SILValue value) const override {
1864
+ assert (B.getModule ().getStage () == SILStage::Raw &&
1865
+ " Can not copy a move only value in non-Raw SIL" );
1866
+ return B.createCopyValue (loc, value);
1867
+ }
1868
+
1869
+ void emitDestroyValue (SILBuilder &B, SILLocation loc,
1870
+ SILValue value) const override {
1871
+ B.createDestroyValue (loc, value);
1872
+ }
1873
+ };
1874
+
1674
1875
// / Build the appropriate TypeLowering subclass for the given type,
1675
1876
// / which is assumed to already have been lowered.
1676
1877
class LowerType
@@ -1700,6 +1901,25 @@ namespace {
1700
1901
return new (TC) ReferenceTypeLowering (silType, properties, Expansion);
1701
1902
}
1702
1903
1904
+ TypeLowering *handleMoveOnlyReference (CanType type,
1905
+ RecursiveProperties properties) {
1906
+ auto silType = SILType::getPrimitiveObjectType (type);
1907
+ return new (TC)
1908
+ MoveOnlyReferenceTypeLowering (silType, properties, Expansion);
1909
+ }
1910
+
1911
+ TypeLowering *handleMoveOnlyAddressOnly (CanType type,
1912
+ RecursiveProperties properties) {
1913
+ if (!TC.Context .SILOpts .EnableSILOpaqueValues ) {
1914
+ auto silType = SILType::getPrimitiveAddressType (type);
1915
+ return new (TC)
1916
+ MoveOnlyAddressOnlyTypeLowering (silType, properties, Expansion);
1917
+ }
1918
+ auto silType = SILType::getPrimitiveObjectType (type);
1919
+ return new (TC)
1920
+ MoveOnlyOpaqueValueTypeLowering (silType, properties, Expansion);
1921
+ }
1922
+
1703
1923
TypeLowering *handleReference (CanType type) {
1704
1924
auto silType = SILType::getPrimitiveObjectType (type);
1705
1925
return new (TC) ReferenceTypeLowering (
0 commit comments