@@ -67,15 +67,32 @@ static bool allUsesInSameBlock(AllocStackInst *ASI) {
67
67
return numDeallocStacks == 1 ;
68
68
}
69
69
70
- static bool shouldTrackLocation (SILType ty, SILFunction *function) {
71
- // Ignore empty tuples and empty structs.
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) {
72
75
if (auto tupleTy = ty.getAs <TupleType>()) {
73
- return tupleTy->getNumElements () != 0 ;
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 ;
74
83
}
75
- if (StructDecl *decl = ty.getStructOrBoundGenericStruct ()) {
76
- return decl->getStoredProperties ().size () != 0 ;
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 ;
77
94
}
78
- return true ;
95
+ return false ;
79
96
}
80
97
81
98
} // anonymous namespace
@@ -100,7 +117,7 @@ MemoryLocations::Location::Location(SILValue val, unsigned index, int parentIdx)
100
117
101
118
void MemoryLocations::Location::updateFieldCounters (SILType ty, int increment) {
102
119
SILFunction *function = representativeValue->getFunction ();
103
- if (shouldTrackLocation (ty, function)) {
120
+ if (! isEmptyType (ty, function)) {
104
121
numFieldsNotCoveredBySubfields += increment;
105
122
if (!ty.isTrivial (*function))
106
123
numNonTrivialFieldsNotCovered += increment;
@@ -198,7 +215,7 @@ void MemoryLocations::analyzeLocation(SILValue loc) {
198
215
if (loc->getType ().isTrivial (*function))
199
216
return ;
200
217
201
- if (! shouldTrackLocation (loc->getType (), function))
218
+ if (isEmptyType (loc->getType (), function))
202
219
return ;
203
220
204
221
unsigned currentLocIdx = locations.size ();
@@ -376,7 +393,7 @@ bool MemoryLocations::analyzeAddrProjection(
376
393
SingleValueInstruction *projection, unsigned parentLocIdx,unsigned fieldNr,
377
394
SmallVectorImpl<SILValue> &collectedVals, SubLocationMap &subLocationMap) {
378
395
379
- if (! shouldTrackLocation (projection->getType (), projection->getFunction ()))
396
+ if (isEmptyType (projection->getType (), projection->getFunction ()))
380
397
return false ;
381
398
382
399
unsigned &subLocIdx = subLocationMap[std::make_pair (parentLocIdx, fieldNr)];
0 commit comments