Skip to content

Commit 33ed1e0

Browse files
committed
IRGen: Add ResilienceExpansion parameter to TypeInfo::isKnownEmpty(), NFC
In a few places, we have to be careful about the distinction between "empty in this resilience domain" versus "empty in all resilience domains". Make callers think about this by adding a parameter instead of relying on them to check isFixedSize() as necessary first. While making this change I noticed that the code for checking if types are empty when computing extra inhabitants of structs and enums might be slightly wrong in the face of resilience; I will revisit this later.
1 parent 627c906 commit 33ed1e0

12 files changed

+23
-22
lines changed

lib/IRGen/FixedTypeInfo.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ class FixedTypeInfo : public TypeInfo {
7272
static bool isFixed() { return true; }
7373

7474
/// Whether this type is known to be empty.
75-
bool isKnownEmpty() const { return StorageSize.isZero(); }
75+
bool isKnownEmpty(ResilienceExpansion expansion) const {
76+
return (isFixedSize(expansion) && StorageSize.isZero());
77+
}
7678

7779
ContainedAddress allocateStack(IRGenFunction &IGF, SILType T,
7880
const llvm::Twine &name) const override;

lib/IRGen/GenClass.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ OwnedAddress irgen::projectPhysicalClassMemberAddress(IRGenFunction &IGF,
402402
VarDecl *field) {
403403
// If the field is empty, its address doesn't matter.
404404
auto &fieldTI = IGF.getTypeInfo(fieldType);
405-
if (fieldTI.isKnownEmpty()) {
405+
if (fieldTI.isKnownEmpty(ResilienceExpansion::Maximal)) {
406406
return OwnedAddress(fieldTI.getUndefAddress(), base);
407407
}
408408

lib/IRGen/GenEnum.cpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -2625,7 +2625,7 @@ namespace {
26252625
auto &payloadTI = getFixedPayloadTypeInfo();
26262626
unsigned totalSize
26272627
= cast<FixedTypeInfo>(TI)->getFixedSize().getValueInBits();
2628-
if (payloadTI.isKnownEmpty())
2628+
if (payloadTI.isKnownEmpty(ResilienceExpansion::Maximal))
26292629
return APInt::getAllOnesValue(totalSize);
26302630
auto baseMask =
26312631
getFixedPayloadTypeInfo().getFixedExtraInhabitantMask(IGM);
@@ -2666,7 +2666,7 @@ namespace {
26662666
auto &payloadTI = getFixedPayloadTypeInfo();
26672667
ClusteredBitVector extraInhabitantsMask;
26682668

2669-
if (!payloadTI.isKnownEmpty())
2669+
if (!payloadTI.isKnownEmpty(ResilienceExpansion::Maximal))
26702670
extraInhabitantsMask =
26712671
getBitVectorFromAPInt(payloadTI.getFixedExtraInhabitantMask(IGM));
26722672
// Extend to include the extra tag bits, which are always significant.
@@ -4699,9 +4699,7 @@ EnumImplStrategy *EnumImplStrategy::get(TypeConverter &TC,
46994699
// If the payload is empty, turn the case into a no-payload case, but
47004700
// only if case numbering remains unchanged from all resilience domains
47014701
// that can see the enum.
4702-
if (origArgTI->isFixedSize(accessScope) &&
4703-
isa<LoadableTypeInfo>(origArgTI) &&
4704-
cast<LoadableTypeInfo>(origArgTI)->isKnownEmpty()) {
4702+
if (origArgTI->isKnownEmpty(accessScope)) {
47054703
elementsWithNoPayload.push_back({elt, nullptr, nullptr});
47064704
} else {
47074705
// *Now* apply the substitutions and get the type info for the instance's

lib/IRGen/GenFunc.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ static void addDereferenceableAttributeToBuilder(IRGenModule &IGM,
144144
const TypeInfo &ti) {
145145
// The addresses of empty values are undefined, so we can't safely mark them
146146
// dereferenceable.
147-
if (ti.isKnownEmpty())
147+
if (ti.isKnownEmpty(ResilienceExpansion::Maximal))
148148
return;
149149

150150
// If we know the type to have a fixed nonempty size, then the pointer is

lib/IRGen/GenHeap.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1482,7 +1482,7 @@ const TypeInfo *TypeConverter::convertBoxType(SILBoxType *T) {
14821482
auto &fixedTI = cast<FixedTypeInfo>(eltTI);
14831483

14841484
// For empty types, we don't really need to allocate anything.
1485-
if (fixedTI.isKnownEmpty()) {
1485+
if (fixedTI.isKnownEmpty(ResilienceExpansion::Maximal)) {
14861486
if (!EmptyBoxTI)
14871487
EmptyBoxTI = new EmptyBoxTypeInfo(IGM);
14881488
return EmptyBoxTI;

lib/IRGen/GenInit.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ using namespace irgen;
3535
Address IRGenModule::emitSILGlobalVariable(SILGlobalVariable *var) {
3636
auto &ti = getTypeInfo(var->getLoweredType());
3737

38-
// If the variable is empty, don't actually emit it; just return undef.
39-
if (ti.isFixedSize(ResilienceExpansion::Minimal) && ti.isKnownEmpty())
38+
// If the variable is empty in all resilience domains, don't actually emit it;
39+
// just return undef.
40+
if (ti.isKnownEmpty(ResilienceExpansion::Minimal))
4041
return ti.getUndefAddress();
4142

4243
/// Get the global variable.
@@ -55,7 +56,7 @@ Address IRGenModule::emitSILGlobalVariable(SILGlobalVariable *var) {
5556
ContainedAddress FixedTypeInfo::allocateStack(IRGenFunction &IGF, SILType T,
5657
const Twine &name) const {
5758
// If the type is known to be empty, don't actually allocate anything.
58-
if (isKnownEmpty()) {
59+
if (isKnownEmpty(ResilienceExpansion::Maximal)) {
5960
auto addr = getUndefAddress();
6061
return { addr, addr };
6162
}
@@ -69,7 +70,7 @@ ContainedAddress FixedTypeInfo::allocateStack(IRGenFunction &IGF, SILType T,
6970

7071
void FixedTypeInfo::deallocateStack(IRGenFunction &IGF, Address addr,
7172
SILType T) const {
72-
if (isKnownEmpty())
73+
if (isKnownEmpty(ResilienceExpansion::Maximal))
7374
return;
7475
IGF.Builder.CreateLifetimeEnd(addr, getFixedSize());
7576
}

lib/IRGen/GenStruct.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ namespace {
200200
= cast<FixedTypeInfo>(asImpl().getFields()[0].getTypeInfo());
201201
auto targetSize = asImpl().getFixedSize().getValueInBits();
202202

203-
if (fieldTI.isKnownEmpty())
203+
if (fieldTI.isKnownEmpty(ResilienceExpansion::Maximal))
204204
return APInt(targetSize, 0);
205205

206206
APInt fieldMask = fieldTI.getFixedExtraInhabitantMask(IGM);

lib/IRGen/GenTuple.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ namespace {
149149
= cast<FixedTypeInfo>(asImpl().getFields()[0].getTypeInfo());
150150
auto size = asImpl().getFixedSize().getValueInBits();
151151

152-
if (fieldTI.isKnownEmpty())
152+
if (fieldTI.isKnownEmpty(ResilienceExpansion::Maximal))
153153
return APInt(size, 0);
154154

155155
APInt firstMask = fieldTI.getFixedExtraInhabitantMask(IGM);

lib/IRGen/GenType.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,9 @@ Address TypeInfo::getUndefAddress() const {
354354
}
355355

356356
/// Whether this type is known to be empty.
357-
bool TypeInfo::isKnownEmpty() const {
357+
bool TypeInfo::isKnownEmpty(ResilienceExpansion expansion) const {
358358
if (auto fixed = dyn_cast<FixedTypeInfo>(this))
359-
return fixed->isKnownEmpty();
359+
return fixed->isKnownEmpty(expansion);
360360
return false;
361361
}
362362

lib/IRGen/IRGenSIL.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -1633,9 +1633,9 @@ void IRGenSILFunction::visitGlobalAddrInst(GlobalAddrInst *i) {
16331633
assert(loweredTy == i->getType().getObjectType());
16341634
auto &ti = getTypeInfo(loweredTy);
16351635

1636-
// If the variable is universally fixed-size and known to be empty, don't
1636+
// If the variable is empty in all resilience domains, don't
16371637
// actually emit a symbol for the global at all, just return undef.
1638-
if (ti.isFixedSize(ResilienceExpansion::Minimal) && ti.isKnownEmpty()) {
1638+
if (ti.isKnownEmpty(ResilienceExpansion::Minimal)) {
16391639
setLoweredAddress(SILValue(i, 0), ti.getUndefAddress());
16401640
return;
16411641
}
@@ -4287,7 +4287,7 @@ void IRGenSILFunction::visitInitExistentialAddrInst(swift::InitExistentialAddrIn
42874287
// Project down to the destination fixed-size buffer.
42884288
Address address = [&]{
42894289
// If the type is provably empty, we're done.
4290-
if (srcTI.isKnownEmpty()) {
4290+
if (srcTI.isKnownEmpty(ResilienceExpansion::Maximal)) {
42914291
assert(packing == FixedPacking::OffsetZero);
42924292
return buffer;
42934293
}

lib/IRGen/StructLayout.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ bool StructLayoutBuilder::addFields(llvm::MutableArrayRef<ElementLayout> elts,
213213
IsKnownAlwaysFixedSize &= eltTI.isFixedSize(ResilienceExpansion::Minimal);
214214

215215
// If the element type is empty, it adds nothing.
216-
if (eltTI.isKnownEmpty()) {
216+
if (eltTI.isKnownEmpty(ResilienceExpansion::Maximal)) {
217217
addEmptyElement(elt);
218218
} else {
219219
// Anything else we do at least potentially adds storage requirements.

lib/IRGen/TypeInfo.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class TypeInfo {
150150
bool isComplete() const { return !StorageAlignment.isZero(); }
151151

152152
/// Whether this type is known to be empty.
153-
bool isKnownEmpty() const;
153+
bool isKnownEmpty(ResilienceExpansion expansion) const;
154154

155155
/// Whether this type is known to be POD, i.e. to not require any
156156
/// particular action on copy or destroy.

0 commit comments

Comments
 (0)