Skip to content

Commit 971d581

Browse files
authored
Merge pull request #61711 from gottesmm/pr-8e7407db044609579456f02173cda0dbd572217d
[move-only] Change type lowering to ensure we use {retain,release}_value instead of strong_{retain,release}
2 parents 25eb9ef + e77714b commit 971d581

File tree

9 files changed

+931
-10
lines changed

9 files changed

+931
-10
lines changed

include/swift/SIL/SILType.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,10 @@ class SILType {
622622
/// wrapped type.
623623
bool isMoveOnly() const;
624624

625+
/// Is this a type that is a first class move only type. This returns false
626+
/// for a move only wrapped type.
627+
bool isPureMoveOnly() const;
628+
625629
/// Returns true if and only if this type is a first class move only
626630
/// type. NOTE: Returns false if the type is a move only wrapped type.
627631
bool isMoveOnlyType() const;

lib/SIL/IR/SILType.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,3 +948,10 @@ bool SILType::isMoveOnlyType() const {
948948
return true;
949949
return false;
950950
}
951+
952+
bool SILType::isPureMoveOnly() const {
953+
if (auto *nom = getNominalOrBoundGenericNominal())
954+
if (nom->isMoveOnly())
955+
return true;
956+
return false;
957+
}

lib/SIL/IR/TypeLowering.cpp

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,110 @@ namespace {
14591459
}
14601460
};
14611461

1462+
/// A lowering for loadable but non-trivial struct types.
1463+
class MoveOnlyLoadableStructTypeLowering final
1464+
: public LoadableAggTypeLowering<MoveOnlyLoadableStructTypeLowering,
1465+
VarDecl *> {
1466+
using Super =
1467+
LoadableAggTypeLowering<MoveOnlyLoadableStructTypeLowering, VarDecl *>;
1468+
1469+
public:
1470+
MoveOnlyLoadableStructTypeLowering(CanType type,
1471+
RecursiveProperties properties,
1472+
TypeExpansionContext forExpansion)
1473+
: LoadableAggTypeLowering(type, properties, forExpansion) {}
1474+
1475+
SILValue emitRValueProject(SILBuilder &B, SILLocation loc,
1476+
SILValue structValue, VarDecl *field,
1477+
const TypeLowering &fieldLowering) const {
1478+
return B.createStructExtract(loc, structValue, field,
1479+
fieldLowering.getLoweredType());
1480+
}
1481+
1482+
void destructureAggregate(
1483+
SILBuilder &B, SILLocation loc, SILValue aggValue, bool skipTrivial,
1484+
function_ref<void(unsigned childIndex, SILValue childValue,
1485+
const TypeLowering &childLowering)>
1486+
visitor) const {
1487+
if (!B.hasOwnership())
1488+
return Super::destructureAggregate(B, loc, aggValue, skipTrivial,
1489+
visitor);
1490+
1491+
auto *dsi = B.createDestructureStruct(loc, aggValue);
1492+
for (auto pair : llvm::enumerate(dsi->getResults())) {
1493+
SILValue childValue = pair.value();
1494+
auto &childLowering =
1495+
B.getFunction().getTypeLowering(childValue->getType());
1496+
if (skipTrivial && childLowering.isTrivial())
1497+
continue;
1498+
visitor(pair.index(), childValue, childLowering);
1499+
}
1500+
}
1501+
1502+
SILValue rebuildAggregate(SILBuilder &B, SILLocation loc,
1503+
ArrayRef<SILValue> values) const override {
1504+
return B.createStruct(loc, getLoweredType(), values);
1505+
}
1506+
1507+
private:
1508+
void lowerChildren(TypeConverter &TC,
1509+
SmallVectorImpl<Child> &children) const override {
1510+
auto silTy = getLoweredType();
1511+
auto structDecl = silTy.getStructOrBoundGenericStruct();
1512+
assert(structDecl);
1513+
1514+
for (auto prop : structDecl->getStoredProperties()) {
1515+
SILType propTy = silTy.getFieldType(prop, TC, getExpansionContext());
1516+
auto &propTL = TC.getTypeLowering(propTy, getExpansionContext());
1517+
children.push_back(Child{prop, propTL});
1518+
}
1519+
}
1520+
};
1521+
1522+
/// A lowering for loadable but non-trivial enum types.
1523+
class MoveOnlyLoadableEnumTypeLowering final
1524+
: public NonTrivialLoadableTypeLowering {
1525+
public:
1526+
MoveOnlyLoadableEnumTypeLowering(CanType type,
1527+
RecursiveProperties properties,
1528+
TypeExpansionContext forExpansion)
1529+
: NonTrivialLoadableTypeLowering(SILType::getPrimitiveObjectType(type),
1530+
properties, IsNotReferenceCounted,
1531+
forExpansion) {}
1532+
1533+
SILValue emitCopyValue(SILBuilder &B, SILLocation loc,
1534+
SILValue value) const override {
1535+
if (B.getFunction().hasOwnership())
1536+
return B.createCopyValue(loc, value);
1537+
B.createRetainValue(loc, value, B.getDefaultAtomicity());
1538+
return value;
1539+
}
1540+
1541+
SILValue emitLoweredCopyValue(SILBuilder &B, SILLocation loc,
1542+
SILValue value,
1543+
TypeExpansionKind style) const override {
1544+
if (B.getFunction().hasOwnership())
1545+
return B.createCopyValue(loc, value);
1546+
B.createRetainValue(loc, value, B.getDefaultAtomicity());
1547+
return value;
1548+
}
1549+
1550+
void emitDestroyValue(SILBuilder &B, SILLocation loc,
1551+
SILValue value) const override {
1552+
if (B.getFunction().hasOwnership()) {
1553+
B.createDestroyValue(loc, value);
1554+
return;
1555+
}
1556+
B.createReleaseValue(loc, value, B.getDefaultAtomicity());
1557+
}
1558+
1559+
void emitLoweredDestroyValue(SILBuilder &B, SILLocation loc, SILValue value,
1560+
TypeExpansionKind style) const override {
1561+
// Enums, we never want to expand.
1562+
return emitDestroyValue(B, loc, value);
1563+
}
1564+
};
1565+
14621566
/// A type lowering for `@differentiable(_linear)` function types.
14631567
class LinearDifferentiableSILFunctionTypeLowering final
14641568
: public LoadableAggTypeLowering<
@@ -2146,7 +2250,8 @@ namespace {
21462250
properties.setNonTrivial();
21472251
if (properties.isAddressOnly())
21482252
return handleMoveOnlyAddressOnly(structType, properties);
2149-
return handleMoveOnlyReference(structType, properties);
2253+
return new (TC) MoveOnlyLoadableStructTypeLowering(
2254+
structType, properties, Expansion);
21502255
}
21512256

21522257
return handleAggregateByProperties<LoadableStructTypeLowering>(structType,
@@ -2223,7 +2328,8 @@ namespace {
22232328
properties.setNonTrivial();
22242329
if (properties.isAddressOnly())
22252330
return handleMoveOnlyAddressOnly(enumType, properties);
2226-
return handleMoveOnlyReference(enumType, properties);
2331+
return new (TC)
2332+
MoveOnlyLoadableEnumTypeLowering(enumType, properties, Expansion);
22272333
}
22282334

22292335
return handleAggregateByProperties<LoadableEnumTypeLowering>(enumType,

lib/SILGen/SILGenApply.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4248,6 +4248,7 @@ RValue CallEmission::applyEnumElementConstructor(SGFContext C) {
42484248
uncurriedLoc, std::move(payload),
42494249
SGF.getLoweredType(formalResultType),
42504250
element, uncurriedContext);
4251+
42514252
return RValue(SGF, uncurriedLoc, formalResultType, resultMV);
42524253
}
42534254

lib/SILGen/SILGenDecl.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -570,10 +570,21 @@ class LetValueInitialization : public Initialization {
570570
SILValue value, bool wasPlusOne) {
571571
// If we have none...
572572
if (value->getOwnershipKind() == OwnershipKind::None) {
573-
// ... and we don't have a no implicit copy trivial type, just return
574-
// value.
575-
if (!SGF.getASTContext().LangOpts.Features.count(Feature::MoveOnly) ||
576-
!vd->isNoImplicitCopy() || !value->getType().isTrivial(SGF.F))
573+
// If we don't have move only features enabled, just return, we are done.
574+
if (!SGF.getASTContext().LangOpts.Features.count(Feature::MoveOnly))
575+
return value;
576+
577+
// Then check if we have a pure move only type. In that case, we need to
578+
// insert a no implicit copy
579+
if (value->getType().isPureMoveOnly()) {
580+
value = SGF.B.createMoveValue(PrologueLoc, value, /*isLexical*/ true);
581+
return SGF.B.createMarkMustCheckInst(
582+
PrologueLoc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
583+
}
584+
585+
// Otherwise, if we don't have a no implicit copy trivial type, just
586+
// return value.
587+
if (!vd->isNoImplicitCopy() || !value->getType().isTrivial(SGF.F))
577588
return value;
578589

579590
// Otherwise, we have a no implicit copy trivial type, so wrap it in the

0 commit comments

Comments
 (0)