Skip to content

Commit 4986105

Browse files
authored
Merge pull request #22803 from slavapestov/sil-type-lowering-resilience
SIL: Plumb ResilienceExpansion through TypeLowering more carefully
2 parents 3c9d620 + f6cb10b commit 4986105

File tree

4 files changed

+91
-70
lines changed

4 files changed

+91
-70
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2148,12 +2148,18 @@ class SILBuilder {
21482148
}
21492149

21502150
bool isLoadableOrOpaque(SILType Ty) {
2151-
if (!F) {
2152-
// We are inserting into the static initializer of a SILGlobalVariable.
2153-
// All types used there are loadable by definition.
2151+
auto &M = C.Module;
2152+
2153+
if (!SILModuleConventions(M).useLoweredAddresses())
21542154
return true;
2155-
}
2156-
return Ty.isLoadableOrOpaque(F);
2155+
2156+
auto expansion = ResilienceExpansion::Maximal;
2157+
// If there's no current SILFunction, we're inserting into a global
2158+
// variable initializer.
2159+
if (F)
2160+
expansion = F->getResilienceExpansion();
2161+
2162+
return M.getTypeLowering(Ty, expansion).isLoadable();
21572163
}
21582164

21592165
void appendOperandTypeName(SILType OpdTy, llvm::SmallString<16> &Name) {

include/swift/SIL/TypeLowering.h

Lines changed: 24 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -306,23 +306,6 @@ class TypeLowering {
306306
return Properties.isResilient();
307307
}
308308

309-
/// Return the semantic type.
310-
///
311-
/// The semantic type is what a type pretends to be during
312-
/// type-checking: that is, the type that getTypeOfRValue would
313-
/// return on a variable of this type.
314-
SILType getSemanticType() const {
315-
// If you change this, change getSemanticTypeLowering() too.
316-
auto storageType = getLoweredType().getASTType();
317-
if (auto refType = dyn_cast<ReferenceStorageType>(storageType))
318-
return SILType::getPrimitiveType(refType.getReferentType(),
319-
SILValueCategory::Object);
320-
return getLoweredType();
321-
}
322-
323-
/// Return the lowering for the semantic type.
324-
inline const TypeLowering &getSemanticTypeLowering(TypeConverter &TC) const;
325-
326309
/// Produce an exact copy of the value in the given address as a
327310
/// scalar. The caller is responsible for destroying this value,
328311
/// e.g. by releasing it.
@@ -582,13 +565,6 @@ class TypeConverter {
582565

583566
llvm::BumpPtrAllocator IndependentBPA;
584567

585-
enum : unsigned {
586-
/// There is a unique entry with this uncurry level in the
587-
/// type-lowering map for every TLI we create. The map has the
588-
/// responsibility to call the destructor for these entries.
589-
UniqueLoweringEntry = ~0U
590-
};
591-
592568
struct CachingTypeKey {
593569
GenericSignature *Sig;
594570
AbstractionPattern::CachingKey OrigType;
@@ -700,8 +676,16 @@ class TypeConverter {
700676
#include "swift/SIL/BridgedTypes.def"
701677

702678
const TypeLowering &
703-
getTypeLoweringForLoweredType(TypeKey key, ResilienceExpansion forExpansion);
704-
const TypeLowering &getTypeLoweringForUncachedLoweredType(TypeKey key);
679+
getTypeLoweringForLoweredType(TypeKey key,
680+
ResilienceExpansion forExpansion);
681+
const TypeLowering &
682+
getTypeLoweringForUncachedLoweredType(TypeKey key,
683+
ResilienceExpansion forExpansion);
684+
685+
const TypeLowering &
686+
getTypeLoweringForExpansion(TypeKey key,
687+
ResilienceExpansion forExpansion,
688+
const TypeLowering *lowering);
705689

706690
public:
707691
SILModule &M;
@@ -763,15 +747,19 @@ class TypeConverter {
763747

764748
/// Lowers a Swift type to a SILType, and returns the SIL TypeLowering
765749
/// for that type.
766-
const TypeLowering &getTypeLowering(Type t) {
750+
const TypeLowering &
751+
getTypeLowering(Type t, ResilienceExpansion forExpansion =
752+
ResilienceExpansion::Minimal) {
767753
AbstractionPattern pattern(getCurGenericContext(), t->getCanonicalType());
768-
return getTypeLowering(pattern, t);
754+
return getTypeLowering(pattern, t, forExpansion);
769755
}
770756

771757
/// Lowers a Swift type to a SILType according to the abstraction
772758
/// patterns of the given original type.
773759
const TypeLowering &getTypeLowering(AbstractionPattern origType,
774-
Type substType);
760+
Type substType,
761+
ResilienceExpansion forExpansion =
762+
ResilienceExpansion::Minimal);
775763

776764
/// Returns the SIL TypeLowering for an already lowered SILType. If the
777765
/// SILType is an address, returns the TypeLowering for the pointed-to
@@ -782,16 +770,19 @@ class TypeConverter {
782770

783771
// Returns the lowered SIL type for a Swift type.
784772
SILType getLoweredType(Type t) {
785-
return getTypeLowering(t).getLoweredType();
773+
return getTypeLowering(t, ResilienceExpansion::Minimal).getLoweredType();
786774
}
787775

788776
// Returns the lowered SIL type for a Swift type.
789777
SILType getLoweredType(AbstractionPattern origType, Type substType) {
790-
return getTypeLowering(origType, substType).getLoweredType();
778+
return getTypeLowering(origType, substType, ResilienceExpansion::Minimal)
779+
.getLoweredType();
791780
}
792781

793-
SILType getLoweredLoadableType(Type t) {
794-
const TypeLowering &ti = getTypeLowering(t);
782+
SILType getLoweredLoadableType(Type t,
783+
ResilienceExpansion forExpansion =
784+
ResilienceExpansion::Minimal) {
785+
const TypeLowering &ti = getTypeLowering(t, forExpansion);
795786
assert(
796787
(ti.isLoadable() || !SILModuleConventions(M).useLoweredAddresses()) &&
797788
"unexpected address-only type");
@@ -1033,15 +1024,6 @@ class TypeConverter {
10331024
bool suppressOptional);
10341025
};
10351026

1036-
inline const TypeLowering &
1037-
TypeLowering::getSemanticTypeLowering(TypeConverter &TC) const {
1038-
// If you change this, change getSemanticType() too.
1039-
auto storageType = getLoweredType().getASTType();
1040-
if (auto refType = dyn_cast<ReferenceStorageType>(storageType))
1041-
return TC.getTypeLowering(refType.getReferentType());
1042-
return *this;
1043-
}
1044-
10451027
/// RAII interface to push a generic context.
10461028
class GenericContextScope {
10471029
TypeConverter &TC;

lib/SIL/TypeLowering.cpp

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ CaptureKind TypeConverter::getDeclCaptureKind(CapturedValue capture) {
9797
// by its address (like a var) instead.
9898
if (var->isImmutable() &&
9999
(!SILModuleConventions(M).useLoweredAddresses() ||
100+
// FIXME: Expansion
100101
!getTypeLowering(var->getType()).isAddressOnly()))
101102
return CaptureKind::Constant;
102103

@@ -323,7 +324,7 @@ namespace {
323324
auto concreteType = getConcreteReferenceStorageReferent(referentType); \
324325
auto &ctx = M.getASTContext(); \
325326
if (Name##StorageType::get(concreteType, ctx) \
326-
->isLoadable(ResilienceExpansion::Maximal)) { \
327+
->isLoadable(Expansion)) { \
327328
return asImpl().visitLoadable##Name##StorageType(type); \
328329
} else { \
329330
return asImpl().visitAddressOnly##Name##StorageType(type); \
@@ -458,14 +459,14 @@ namespace {
458459

459460
// Consult the type lowering.
460461
type = getSubstitutedTypeForTypeLowering(type);
461-
auto &lowering = M.Types.getTypeLowering(type);
462+
auto &lowering = M.Types.getTypeLowering(type, Expansion);
462463
return handleClassificationFromLowering(type, lowering);
463464
}
464465

465466
RecursiveProperties visitAnyStructType(CanType type, StructDecl *D) {
466467
// Consult the type lowering.
467468
type = getSubstitutedTypeForTypeLowering(type);
468-
auto &lowering = M.Types.getTypeLowering(type);
469+
auto &lowering = M.Types.getTypeLowering(type, Expansion);
469470
return handleClassificationFromLowering(type, lowering);
470471
}
471472

@@ -850,6 +851,7 @@ namespace {
850851
unsigned index = 0;
851852
for (auto elt : tupleTy.getElementTypes()) {
852853
auto silElt = SILType::getPrimitiveType(elt, silTy.getCategory());
854+
// FIXME: Expansion
853855
children.push_back(Child{index, M.Types.getTypeLowering(silElt)});
854856
++index;
855857
}
@@ -884,6 +886,7 @@ namespace {
884886

885887
for (auto prop : structDecl->getStoredProperties()) {
886888
SILType propTy = silTy.getFieldType(prop, M);
889+
// FIXME: Expansion
887890
children.push_back(Child{prop, M.Types.getTypeLowering(propTy)});
888891
}
889892
}
@@ -1161,7 +1164,7 @@ namespace {
11611164
}
11621165

11631166
TypeLowering *handleAddressOnly(CanType type,
1164-
RecursiveProperties properties) {
1167+
RecursiveProperties properties) {
11651168
if (SILModuleConventions(M).useLoweredAddresses()) {
11661169
auto silType = SILType::getPrimitiveAddressType(type);
11671170
return new (TC, Dependent) AddressOnlyTypeLowering(silType, properties);
@@ -1187,7 +1190,7 @@ namespace {
11871190
TypeLowering *visitTupleType(CanTupleType tupleType) {
11881191
RecursiveProperties properties;
11891192
for (auto eltType : tupleType.getElementTypes()) {
1190-
auto &lowering = TC.getTypeLowering(eltType);
1193+
auto &lowering = TC.getTypeLowering(eltType, Expansion);
11911194
properties.addSubobject(lowering.getRecursiveProperties());
11921195
}
11931196

@@ -1258,7 +1261,7 @@ namespace {
12581261

12591262
template <class LoadableLoweringClass>
12601263
TypeLowering *handleAggregateByProperties(CanType type,
1261-
RecursiveProperties props) {
1264+
RecursiveProperties props) {
12621265
if (props.isAddressOnly()) {
12631266
return handleAddressOnly(type, props);
12641267
}
@@ -1422,7 +1425,8 @@ TypeConverter::getSILFunctionType(AbstractionPattern origType,
14221425

14231426
const TypeLowering &
14241427
TypeConverter::getTypeLowering(AbstractionPattern origType,
1425-
Type origSubstType) {
1428+
Type origSubstType,
1429+
ResilienceExpansion forExpansion) {
14261430
CanType substType = origSubstType->getCanonicalType();
14271431
auto key = getTypeKey(origType, substType);
14281432

@@ -1431,7 +1435,7 @@ TypeConverter::getTypeLowering(AbstractionPattern origType,
14311435
assert(!substType->is<InOutType>());
14321436

14331437
if (auto existing = find(key))
1434-
return *existing;
1438+
return getTypeLoweringForExpansion(key, forExpansion, existing);
14351439

14361440
// Lower the type.
14371441
CanType loweredSubstType =
@@ -1441,7 +1445,7 @@ TypeConverter::getTypeLowering(AbstractionPattern origType,
14411445
// point in re-checking the table, so just construct a type lowering
14421446
// and cache it.
14431447
if (loweredSubstType == substType && key.isCacheable()) {
1444-
return getTypeLoweringForUncachedLoweredType(key);
1448+
return getTypeLoweringForUncachedLoweredType(key, forExpansion);
14451449
}
14461450

14471451
// Otherwise, check the table at a key that would be used by the
@@ -1452,7 +1456,7 @@ TypeConverter::getTypeLowering(AbstractionPattern origType,
14521456
auto loweredKey = getTypeKey(origTypeForCaching, loweredSubstType);
14531457

14541458
auto &lowering = getTypeLoweringForLoweredType(loweredKey,
1455-
ResilienceExpansion::Minimal);
1459+
forExpansion);
14561460
insert(key, &lowering);
14571461
return lowering;
14581462
}
@@ -1582,17 +1586,22 @@ TypeConverter::getTypeLoweringForLoweredType(TypeKey key,
15821586
assert(type->isLegalSILType() && "type is not lowered!");
15831587
(void)type;
15841588

1585-
// Re-using uncurry level 0 is reasonable because our uncurrying
1586-
// transforms are idempotent at this level. This means we don't
1587-
// need a ton of redundant entries in the map.
15881589
const TypeLowering *lowering = find(key);
1589-
if (!lowering) {
1590-
lowering = &getTypeLoweringForUncachedLoweredType(key);
1591-
}
1592-
assert(lowering->forExpansion == ResilienceExpansion::Minimal &&
1593-
"the first lowering in the list must be for minimal expansion");
1590+
if (!lowering)
1591+
lowering = &getTypeLoweringForUncachedLoweredType(key, forExpansion);
1592+
1593+
return getTypeLoweringForExpansion(key, forExpansion, lowering);
1594+
}
15941595

1595-
if (key.isDependent() || !lowering->isResilient()) {
1596+
/// When we've found a type lowering for one resilience expansion,
1597+
/// check if its the one we want; if not, walk the list until we
1598+
/// find the right one, or create a new lowering and add it to
1599+
/// the end of the list.
1600+
const TypeLowering & TypeConverter::
1601+
getTypeLoweringForExpansion(TypeKey key,
1602+
ResilienceExpansion forExpansion,
1603+
const TypeLowering *lowering) {
1604+
if (!lowering->isResilient()) {
15961605
// Don't try to refine the lowering for other resilience expansions if
15971606
// we don't expect to get a different lowering anyway.
15981607
return *lowering;
@@ -1622,8 +1631,9 @@ TypeConverter::getTypeLoweringForLoweredType(TypeKey key,
16221631

16231632
/// Do type-lowering for a lowered type which is not already in the cache,
16241633
/// then insert it into the cache.
1625-
const TypeLowering &
1626-
TypeConverter::getTypeLoweringForUncachedLoweredType(TypeKey key) {
1634+
const TypeLowering & TypeConverter::
1635+
getTypeLoweringForUncachedLoweredType(TypeKey key,
1636+
ResilienceExpansion forExpansion) {
16271637
assert(!find(key) && "re-entrant or already cached");
16281638
assert(key.SubstType->isLegalSILType() && "type is not already lowered");
16291639

@@ -1632,12 +1642,13 @@ TypeConverter::getTypeLoweringForUncachedLoweredType(TypeKey key) {
16321642
insert(key, nullptr);
16331643
#endif
16341644

1635-
// FIXME: Get expansion from SILFunction
16361645
auto *theInfo = LowerType(*this,
16371646
CanGenericSignature(),
1638-
ResilienceExpansion::Minimal,
1647+
forExpansion,
16391648
key.isDependent()).visit(key.SubstType);
16401649

1650+
theInfo->forExpansion = forExpansion;
1651+
16411652
if (key.OrigType.isForeign()) {
16421653
assert(theInfo->isLoadable() && "Cannot lower address-only type with "
16431654
"foreign abstraction pattern");
@@ -2492,6 +2503,7 @@ CanSILBoxType TypeConverter::getBoxTypeForEnumElement(SILType enumType,
24922503
static void countNumberOfInnerFields(unsigned &fieldsCount, SILModule &Module,
24932504
SILType Ty) {
24942505
if (auto *structDecl = Ty.getStructOrBoundGenericStruct()) {
2506+
// FIXME: Expansion
24952507
assert(!structDecl->isResilient(Module.getSwiftModule(),
24962508
ResilienceExpansion::Minimal) &&
24972509
" FSO should not be trying to explode resilient (ie address-only) "
@@ -2519,6 +2531,7 @@ static void countNumberOfInnerFields(unsigned &fieldsCount, SILModule &Module,
25192531
if (enumDecl->isIndirect()) {
25202532
return;
25212533
}
2534+
// FIXME: Expansion
25222535
assert(!enumDecl->isResilient(Module.getSwiftModule(),
25232536
ResilienceExpansion::Minimal) &&
25242537
" FSO should not be trying to explode resilient (ie address-only) "

test/SILOptimizer/globalopt_resilience.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,23 @@ public func cannotConvertToValueUse() {
3232
// CHECK: apply [[METHOD]]([[ADDR]]) : $@convention(method) (@in_guaranteed ResilientStruct) -> ()
3333
// CHECK: [[RESULT:%.*]] = tuple ()
3434
// CHECK: return [[RESULT]] : $()
35+
36+
internal struct WrapperStruct {
37+
var inner: ResilientStruct = .staticVal
38+
39+
init() {}
40+
}
41+
42+
func returnWrapperStruct() -> WrapperStruct {
43+
return WrapperStruct()
44+
}
45+
46+
// CHECK-LABEL: sil hidden @$s4test19returnWrapperStructAA0cD0VyF : $@convention(thin) () -> @out WrapperStruct
47+
// CHECK: bb0(%0 : $*WrapperStruct):
48+
// CHECK: [[INT:%.*]] = integer_literal $Builtin.Int{{32|64}}, 27
49+
// CHECK: [[S1:%.*]] = struct $Int ([[INT]] : $Builtin.Int{{32|64}})
50+
// CHECK: [[S2:%.*]] = struct $ResilientStruct ([[S1]] : $Int)
51+
// CHECK: [[S3:%.*]] = struct $WrapperStruct ([[S2]] : $ResilientStruct)
52+
// CHECK: store [[S3]] to %0 : $*WrapperStruct
53+
// CHECK: [[RESULT:%.*]] = tuple ()
54+
// CHECK: return [[RESULT]] : $()

0 commit comments

Comments
 (0)