Skip to content

Commit 25d6340

Browse files
committed
SIL: extract the isEmptyType from MemoryLocations into a general utility in SILType
NFC
1 parent 8c43800 commit 25d6340

File tree

3 files changed

+35
-31
lines changed

3 files changed

+35
-31
lines changed

include/swift/SIL/SILType.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,10 @@ class SILType {
294294
/// even though they are technically trivial.
295295
bool isTrivial(const SILFunction &F) const;
296296

297+
/// True if the type is an empty tuple or an empty struct or a tuple or
298+
/// struct containing only empty types.
299+
bool isEmpty(const SILFunction &F) const;
300+
297301
/// True if the type, or the referenced type of an address type, is known to
298302
/// be a scalar reference-counted type such as a class, box, or thick function
299303
/// type. Returns false for non-trivial aggregates.

lib/SIL/IR/SILType.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,30 @@ bool SILType::isTrivial(const SILFunction &F) const {
104104
return F.getTypeLowering(contextType).isTrivial();
105105
}
106106

107+
bool SILType::isEmpty(const SILFunction &F) const {
108+
if (auto tupleTy = getAs<TupleType>()) {
109+
// A tuple is empty if it either has no elements or if all elements are
110+
// empty.
111+
for (unsigned idx = 0, num = tupleTy->getNumElements(); idx < num; ++idx) {
112+
if (!getTupleElementType(idx).isEmpty(F))
113+
return false;
114+
}
115+
return true;
116+
}
117+
if (StructDecl *structDecl = getStructOrBoundGenericStruct()) {
118+
// Also, a struct is empty if it either has no fields or if all fields are
119+
// empty.
120+
SILModule &module = F.getModule();
121+
TypeExpansionContext typeEx = F.getTypeExpansionContext();
122+
for (VarDecl *field : structDecl->getStoredProperties()) {
123+
if (!getFieldType(field, module, typeEx).isEmpty(F))
124+
return false;
125+
}
126+
return true;
127+
}
128+
return false;
129+
}
130+
107131
bool SILType::isReferenceCounted(SILModule &M) const {
108132
return M.Types.getTypeLowering(*this,
109133
TypeExpansionContext::minimal())

lib/SIL/Utils/MemoryLocations.cpp

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -67,34 +67,6 @@ static bool allUsesInSameBlock(AllocStackInst *ASI) {
6767
return numDeallocStacks == 1;
6868
}
6969

70-
/// We don't handle empty tuples and empty structs.
71-
///
72-
/// Locations with empty types don't even need a store to count as
73-
/// "initialized". We don't handle such cases.
74-
static bool isEmptyType(SILType ty, SILFunction *function) {
75-
if (auto tupleTy = ty.getAs<TupleType>()) {
76-
// A tuple is empty if it either has no elements or if all elements are
77-
// empty.
78-
for (unsigned idx = 0, num = tupleTy->getNumElements(); idx < num; ++idx) {
79-
if (!isEmptyType(ty.getTupleElementType(idx), function))
80-
return false;
81-
}
82-
return true;
83-
}
84-
if (StructDecl *structDecl = ty.getStructOrBoundGenericStruct()) {
85-
// Also, a struct is empty if it either has no fields or if all fields are
86-
// empty.
87-
SILModule &module = function->getModule();
88-
TypeExpansionContext typeEx = function->getTypeExpansionContext();
89-
for (VarDecl *field : structDecl->getStoredProperties()) {
90-
if (!isEmptyType(ty.getFieldType(field, module, typeEx), function))
91-
return false;
92-
}
93-
return true;
94-
}
95-
return false;
96-
}
97-
9870
} // anonymous namespace
9971
} // namespace swift
10072

@@ -117,7 +89,7 @@ MemoryLocations::Location::Location(SILValue val, unsigned index, int parentIdx)
11789

11890
void MemoryLocations::Location::updateFieldCounters(SILType ty, int increment) {
11991
SILFunction *function = representativeValue->getFunction();
120-
if (!isEmptyType(ty, function)) {
92+
if (!ty.isEmpty(*function)) {
12193
numFieldsNotCoveredBySubfields += increment;
12294
if (!ty.isTrivial(*function))
12395
numNonTrivialFieldsNotCovered += increment;
@@ -215,7 +187,11 @@ void MemoryLocations::analyzeLocation(SILValue loc) {
215187
if (!handleTrivialLocations && loc->getType().isTrivial(*function))
216188
return;
217189

218-
if (isEmptyType(loc->getType(), function))
190+
/// We don't handle empty tuples and empty structs.
191+
///
192+
/// Locations with empty types don't even need a store to count as
193+
/// "initialized". We don't handle such cases.
194+
if (loc->getType().isEmpty(*function))
219195
return;
220196

221197
unsigned currentLocIdx = locations.size();
@@ -400,7 +376,7 @@ bool MemoryLocations::analyzeAddrProjection(
400376
SingleValueInstruction *projection, unsigned parentLocIdx,unsigned fieldNr,
401377
SmallVectorImpl<SILValue> &collectedVals, SubLocationMap &subLocationMap) {
402378

403-
if (isEmptyType(projection->getType(), projection->getFunction()))
379+
if (projection->getType().isEmpty(*projection->getFunction()))
404380
return false;
405381

406382
auto key = std::make_pair(parentLocIdx, fieldNr);

0 commit comments

Comments
 (0)