@@ -171,13 +171,19 @@ namespace {
171171 // RetTy handleTrivial(CanType);
172172 // RetTy handleTrivial(CanType, RecursiveProperties properties);
173173 // // A reference type.
174+ // RetTy handleReference(CanType);
174175 // 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);
176181 // // Non-trivial and address-only.
177182 // RetTy handleAddressOnly(CanType, RecursiveProperties properties);
178183 // and, if it doesn't override handleTupleType,
179184 // // An aggregate type that's non-trivial.
180- // RetTy handleNonTrivialAggregate(CanType, RecursiveProperties properties);
185+ // RetTy handleNonTrivialAggregate(CanType, RecursiveProperties
186+ // properties);
181187 //
182188 // Alternatively, it can just implement:
183189 // RetTy handle(CanType, RecursiveProperties properties);
@@ -208,6 +214,16 @@ namespace {
208214 return asImpl ().handle (type, properties);
209215 }
210216
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+
211227 RecursiveProperties
212228 mergeIsTypeExpansionSensitive (IsTypeExpansionSensitive_t isSensitive,
213229 RecursiveProperties props) {
@@ -228,12 +244,24 @@ namespace {
228244 RecursiveProperties::forReference ());
229245 }
230246
247+ RecursiveProperties getMoveOnlyReferenceRecursiveProperties (
248+ IsTypeExpansionSensitive_t isSensitive) {
249+ return mergeIsTypeExpansionSensitive (isSensitive,
250+ RecursiveProperties::forReference ());
251+ }
252+
231253 RecursiveProperties
232254 getOpaqueRecursiveProperties (IsTypeExpansionSensitive_t isSensitive) {
233255 return mergeIsTypeExpansionSensitive (isSensitive,
234256 RecursiveProperties::forOpaque ());
235257 }
236258
259+ RecursiveProperties getMoveOnlyOpaqueRecursiveProperties (
260+ IsTypeExpansionSensitive_t isSensitive) {
261+ return mergeIsTypeExpansionSensitive (
262+ isSensitive, RecursiveProperties::forMoveOnlyOpaque ());
263+ }
264+
237265#define IMPL (TYPE, LOWERING ) \
238266 RetTy visit##TYPE##Type(Can##TYPE##Type type, AbstractionPattern orig, \
239267 IsTypeExpansionSensitive_t isSensitive) { \
@@ -669,9 +697,19 @@ namespace {
669697 RetTy visitSILMoveOnlyType (CanSILMoveOnlyType type,
670698 AbstractionPattern origType,
671699 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));
675713 }
676714
677715 RetTy handleAggregateByProperties (CanType type, RecursiveProperties props) {
@@ -1477,6 +1515,37 @@ namespace {
14771515 }
14781516 };
14791517
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+
14801549// / A type lowering for loadable @unowned types.
14811550#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE (Name, ...) \
14821551 class Loadable ##Name##TypeLowering final : public LeafLoadableTypeLowering { \
@@ -1590,6 +1659,93 @@ namespace {
15901659 }
15911660 };
15921661
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+
15931749 // / A class for Builtin.UnsafeValueBuffer. The only purpose here is
15941750 // / to catch obviously broken attempts to copy or destroy the buffer.
15951751 class UnsafeValueBufferTypeLowering : public AddressOnlyTypeLowering {
@@ -1671,6 +1827,51 @@ namespace {
16711827 }
16721828 };
16731829
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+
16741875 // / Build the appropriate TypeLowering subclass for the given type,
16751876 // / which is assumed to already have been lowered.
16761877 class LowerType
@@ -1700,6 +1901,25 @@ namespace {
17001901 return new (TC) ReferenceTypeLowering (silType, properties, Expansion);
17011902 }
17021903
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+
17031923 TypeLowering *handleReference (CanType type) {
17041924 auto silType = SILType::getPrimitiveObjectType (type);
17051925 return new (TC) ReferenceTypeLowering (
0 commit comments