@@ -91,23 +91,28 @@ getFullyReferenceableStruct(SILType Ty) {
91
91
return SD;
92
92
}
93
93
94
- static unsigned getNumSubElements (SILType T, SILModule &M ,
94
+ static unsigned getNumSubElements (SILType T, SILFunction &F ,
95
95
TypeExpansionContext context) {
96
96
97
97
if (auto TT = T.getAs <TupleType>()) {
98
98
unsigned NumElements = 0 ;
99
99
for (auto index : indices (TT.getElementTypes ()))
100
100
NumElements +=
101
- getNumSubElements (T.getTupleElementType (index), M , context);
101
+ getNumSubElements (T.getTupleElementType (index), F , context);
102
102
return NumElements;
103
103
}
104
104
105
105
if (auto *SD = getFullyReferenceableStruct (T)) {
106
106
unsigned NumElements = 0 ;
107
107
for (auto *D : SD->getStoredProperties ())
108
108
NumElements +=
109
- getNumSubElements (T.getFieldType (D, M, context), M, context);
110
- return NumElements;
109
+ getNumSubElements (T.getFieldType (D, F.getModule (), context), F,
110
+ context);
111
+
112
+ // Returning NumElements == 0 implies that "empty" values can be
113
+ // materialized without ownership. This is only valid for trivial types.
114
+ if (NumElements > 0 || T.isTrivial (F))
115
+ return NumElements;
111
116
}
112
117
113
118
// If this isn't a tuple or struct, it is a single element.
@@ -152,7 +157,7 @@ static SILValue getAccessPathRoot(SILValue pointer) {
152
157
static unsigned computeSubelement (SILValue Pointer,
153
158
SingleValueInstruction *RootInst) {
154
159
unsigned SubElementNumber = 0 ;
155
- SILModule &M = RootInst->getModule ();
160
+ auto &F = * RootInst->getFunction ();
156
161
157
162
while (1 ) {
158
163
// If we got to the root, we're done.
@@ -175,7 +180,7 @@ static unsigned computeSubelement(SILValue Pointer,
175
180
// Keep track of what subelement is being referenced.
176
181
for (unsigned i = 0 , e = TEAI->getFieldIndex (); i != e; ++i) {
177
182
SubElementNumber +=
178
- getNumSubElements (TT.getTupleElementType (i), M ,
183
+ getNumSubElements (TT.getTupleElementType (i), F ,
179
184
TypeExpansionContext (*RootInst->getFunction ()));
180
185
}
181
186
Pointer = TEAI->getOperand ();
@@ -191,7 +196,8 @@ static unsigned computeSubelement(SILValue Pointer,
191
196
if (D == SEAI->getField ()) break ;
192
197
auto context = TypeExpansionContext (*RootInst->getFunction ());
193
198
SubElementNumber +=
194
- getNumSubElements (ST.getFieldType (D, M, context), M, context);
199
+ getNumSubElements (ST.getFieldType (D, F.getModule (), context), F,
200
+ context);
195
201
}
196
202
197
203
Pointer = SEAI->getOperand ();
@@ -370,10 +376,9 @@ static bool isFullyAvailable(SILType loadTy, unsigned firstElt,
370
376
if (!firstVal || firstVal.getType () != loadTy)
371
377
return false ;
372
378
373
- auto * function = firstVal.getValue ()->getFunction ();
379
+ auto & function = * firstVal.getValue ()->getFunction ();
374
380
return llvm::all_of (
375
- range (getNumSubElements (loadTy, function->getModule (),
376
- TypeExpansionContext (*function))),
381
+ range (getNumSubElements (loadTy, function, TypeExpansionContext (function))),
377
382
[&](unsigned index) -> bool {
378
383
auto &val = AvailableValues[firstElt + index];
379
384
return val.getValue () == firstVal.getValue () &&
@@ -395,7 +400,7 @@ static SILValue nonDestructivelyExtractSubElement(const AvailableValue &Val,
395
400
// Keep track of what subelement is being referenced.
396
401
SILType EltTy = ValTy.getTupleElementType (EltNo);
397
402
unsigned NumSubElt = getNumSubElements (
398
- EltTy, B.getModule (), TypeExpansionContext (B.getFunction ()));
403
+ EltTy, B.getFunction (), TypeExpansionContext (B.getFunction ()));
399
404
if (SubElementNumber < NumSubElt) {
400
405
auto BorrowedVal = Val.emitBeginBorrow (B, Loc);
401
406
auto NewVal =
@@ -420,7 +425,7 @@ static SILValue nonDestructivelyExtractSubElement(const AvailableValue &Val,
420
425
auto fieldType = ValTy.getFieldType (
421
426
D, B.getModule (), TypeExpansionContext (B.getFunction ()));
422
427
unsigned NumSubElt = getNumSubElements (
423
- fieldType, B.getModule (), TypeExpansionContext (B.getFunction ()));
428
+ fieldType, B.getFunction (), TypeExpansionContext (B.getFunction ()));
424
429
425
430
if (SubElementNumber < NumSubElt) {
426
431
auto BorrowedVal = Val.emitBeginBorrow (B, Loc);
@@ -1227,7 +1232,8 @@ bool AvailableValueAggregator::canTake(SILType loadTy,
1227
1232
return llvm::all_of (indices (tt->getElements ()), [&](unsigned eltNo) {
1228
1233
SILType eltTy = loadTy.getTupleElementType (eltNo);
1229
1234
unsigned numSubElt =
1230
- getNumSubElements (eltTy, M, TypeExpansionContext (B.getFunction ()));
1235
+ getNumSubElements (eltTy, B.getFunction (),
1236
+ TypeExpansionContext (B.getFunction ()));
1231
1237
bool success = canTake (eltTy, firstElt);
1232
1238
firstElt += numSubElt;
1233
1239
return success;
@@ -1238,7 +1244,7 @@ bool AvailableValueAggregator::canTake(SILType loadTy,
1238
1244
return llvm::all_of (sd->getStoredProperties (), [&](VarDecl *decl) -> bool {
1239
1245
auto context = TypeExpansionContext (B.getFunction ());
1240
1246
SILType eltTy = loadTy.getFieldType (decl, M, context);
1241
- unsigned numSubElt = getNumSubElements (eltTy, M , context);
1247
+ unsigned numSubElt = getNumSubElements (eltTy, B. getFunction () , context);
1242
1248
bool success = canTake (eltTy, firstElt);
1243
1249
firstElt += numSubElt;
1244
1250
return success;
@@ -1369,7 +1375,8 @@ SILValue AvailableValueAggregator::aggregateTupleSubElts(TupleType *TT,
1369
1375
for (unsigned EltNo : indices (TT->getElements ())) {
1370
1376
SILType EltTy = LoadTy.getTupleElementType (EltNo);
1371
1377
unsigned NumSubElt =
1372
- getNumSubElements (EltTy, M, TypeExpansionContext (B.getFunction ()));
1378
+ getNumSubElements (EltTy, B.getFunction (),
1379
+ TypeExpansionContext (B.getFunction ()));
1373
1380
1374
1381
// If we are missing any of the available values in this struct element,
1375
1382
// compute an address to load from.
@@ -1406,7 +1413,7 @@ SILValue AvailableValueAggregator::aggregateStructSubElts(StructDecl *sd,
1406
1413
for (auto *decl : sd->getStoredProperties ()) {
1407
1414
auto context = TypeExpansionContext (B.getFunction ());
1408
1415
SILType eltTy = loadTy.getFieldType (decl, M, context);
1409
- unsigned numSubElt = getNumSubElements (eltTy, M , context);
1416
+ unsigned numSubElt = getNumSubElements (eltTy, B. getFunction () , context);
1410
1417
1411
1418
// If we are missing any of the available values in this struct element,
1412
1419
// compute an address to load from.
@@ -1540,6 +1547,8 @@ class AvailableValueDataflowContext {
1540
1547
private:
1541
1548
SILModule &getModule () const { return TheMemory->getModule (); }
1542
1549
1550
+ SILFunction &getFunction () const { return *TheMemory->getFunction (); }
1551
+
1543
1552
void updateAvailableValues (
1544
1553
SILInstruction *Inst,
1545
1554
SmallBitVector &RequiredElts,
@@ -1673,7 +1682,7 @@ AvailableValueDataflowContext::computeAvailableValues(
1673
1682
return std::nullopt;
1674
1683
1675
1684
unsigned NumLoadSubElements = getNumSubElements (
1676
- LoadTy, getModule (), TypeExpansionContext (*TheMemory-> getFunction ()));
1685
+ LoadTy, getFunction (), TypeExpansionContext (getFunction ()));
1677
1686
1678
1687
LoadInfo loadInfo = {LoadTy, FirstElt, NumLoadSubElements};
1679
1688
@@ -1712,14 +1721,14 @@ static inline void updateAvailableValuesHelper(
1712
1721
SmallBitVector &conflictingValues,
1713
1722
function_ref<std::optional<AvailableValue>(unsigned )> defaultFunc,
1714
1723
function_ref<bool(AvailableValue &, unsigned )> isSafeFunc) {
1715
- auto &mod = theMemory->getModule ();
1716
1724
unsigned startSubElt = computeSubelement (address, theMemory);
1717
1725
1718
1726
// TODO: Is this needed now?
1719
1727
assert (startSubElt != ~0U && " Store within enum projection not handled" );
1728
+ auto &f = *theMemory->getFunction ();
1720
1729
for (unsigned i : range (getNumSubElements (
1721
- address->getType ().getObjectType (), mod ,
1722
- TypeExpansionContext (*theMemory-> getFunction () )))) {
1730
+ address->getType ().getObjectType (), f ,
1731
+ TypeExpansionContext (f )))) {
1723
1732
// If this element is not required, don't fill it in.
1724
1733
if (!requiredElts[startSubElt + i])
1725
1734
continue ;
@@ -1849,7 +1858,8 @@ void AvailableValueDataflowContext::updateAvailableValues(
1849
1858
1850
1859
bool AnyRequired = false ;
1851
1860
for (unsigned i : range (getNumSubElements (
1852
- ValTy, getModule (), TypeExpansionContext (*CAI->getFunction ())))) {
1861
+ ValTy, getFunction (),
1862
+ TypeExpansionContext (getFunction ())))) {
1853
1863
// If this element is not required, don't fill it in.
1854
1864
AnyRequired = RequiredElts[StartSubElt+i];
1855
1865
if (AnyRequired) break ;
@@ -1883,7 +1893,7 @@ void AvailableValueDataflowContext::updateAvailableValues(
1883
1893
// potentially bailing out (because it is address-only).
1884
1894
bool AnyRequired = false ;
1885
1895
for (unsigned i : range (getNumSubElements (
1886
- ValTy, getModule (), TypeExpansionContext (*MD-> getFunction ())))) {
1896
+ ValTy, getFunction (), TypeExpansionContext (getFunction ())))) {
1887
1897
// If this element is not required, don't fill it in.
1888
1898
AnyRequired = RequiredElts[StartSubElt+i];
1889
1899
if (AnyRequired) break ;
@@ -2171,7 +2181,7 @@ void AvailableValueDataflowContext::updateMarkDependenceValues(
2171
2181
}
2172
2182
SILType valueTy = md->getValue ()->getType ().getObjectType ();
2173
2183
unsigned numMDSubElements = getNumSubElements (
2174
- valueTy, getModule (), TypeExpansionContext (*TheMemory-> getFunction ()));
2184
+ valueTy, getFunction (), TypeExpansionContext (getFunction ()));
2175
2185
2176
2186
// Update each required subelement of the mark_dependence value.
2177
2187
for (unsigned subIdx = firstMDElt; subIdx < firstMDElt + numMDSubElements;
@@ -2299,7 +2309,8 @@ class OptimizeAllocLoads {
2299
2309
: Module(memory->getModule ()), TheMemory(memory),
2300
2310
MemoryType(getMemoryType(memory)),
2301
2311
NumMemorySubElements(getNumSubElements(
2302
- MemoryType, Module, TypeExpansionContext(*memory->getFunction ()))),
2312
+ MemoryType, *memory->getFunction (),
2313
+ TypeExpansionContext(*memory->getFunction ()))),
2303
2314
Uses(uses), deleter(deleter), deadEndBlocks(deadEndBlocks),
2304
2315
DataflowContext(TheMemory, NumMemorySubElements,
2305
2316
OptimizationMode::PreserveAlloc, uses,
@@ -2680,7 +2691,8 @@ class OptimizeDeadAlloc {
2680
2691
: Module(memory->getModule ()), TheMemory(memory),
2681
2692
MemoryType(getMemoryType(memory)),
2682
2693
NumMemorySubElements(getNumSubElements(
2683
- MemoryType, Module, TypeExpansionContext(*memory->getFunction ()))),
2694
+ MemoryType, *memory->getFunction (),
2695
+ TypeExpansionContext(*memory->getFunction ()))),
2684
2696
Uses(uses), Releases(releases), deadEndBlocks(deadEndBlocks),
2685
2697
deleter(deleter), domInfo(domInfo),
2686
2698
DataflowContext(TheMemory, NumMemorySubElements,
0 commit comments