@@ -93,6 +93,7 @@ static SILValue scalarizeLoad(LoadInst *LI,
93
93
// ===----------------------------------------------------------------------===//
94
94
95
95
namespace {
96
+
96
97
class ElementUseCollector {
97
98
SILModule &Module;
98
99
const PMOMemoryObjectInfo &TheMemory;
@@ -118,9 +119,6 @@ class ElementUseCollector {
118
119
private:
119
120
LLVM_NODISCARD bool collectUses (SILValue Pointer);
120
121
LLVM_NODISCARD bool collectContainerUses (AllocBoxInst *ABI);
121
- void addElementUses (SILInstruction *User, PMOUseKind Kind);
122
- LLVM_NODISCARD bool collectTupleElementUses (TupleElementAddrInst *TEAI);
123
- LLVM_NODISCARD bool collectStructElementUses (StructElementAddrInst *SEAI);
124
122
};
125
123
} // end anonymous namespace
126
124
@@ -149,34 +147,6 @@ bool ElementUseCollector::collectFrom() {
149
147
return true ;
150
148
}
151
149
152
- // / addElementUses - An operation (e.g. load, store, inout use, etc) on a value
153
- // / acts on all of the aggregate elements in that value. For example, a load
154
- // / of $*(Int,Int) is a use of both Int elements of the tuple. This is a helper
155
- // / to keep the Uses data structure up to date for aggregate uses.
156
- void ElementUseCollector::addElementUses (SILInstruction *User,
157
- PMOUseKind Kind) {
158
- Uses.emplace_back (User, Kind);
159
- }
160
-
161
- // / Given a tuple_element_addr or struct_element_addr, compute the new
162
- // / BaseEltNo implicit in the selected member, and recursively add uses of
163
- // / the instruction.
164
- bool ElementUseCollector::collectTupleElementUses (TupleElementAddrInst *TEAI) {
165
- // If we're walking into a tuple within a struct or enum, don't adjust the
166
- // BaseElt. The uses hanging off the tuple_element_addr are going to be
167
- // counted as uses of the struct or enum itself.
168
- return collectUses (TEAI);
169
- }
170
-
171
- bool ElementUseCollector::collectStructElementUses (
172
- StructElementAddrInst *SEAI) {
173
- // Generally, we set the "InStructSubElement" flag and recursively process
174
- // the uses so that we know that we're looking at something within the
175
- // current element.
176
- llvm::SaveAndRestore<bool > X (InStructSubElement, true );
177
- return collectUses (SEAI);
178
- }
179
-
180
150
bool ElementUseCollector::collectContainerUses (AllocBoxInst *ABI) {
181
151
for (Operand *UI : ABI->getUses ()) {
182
152
auto *User = UI->getUser ();
@@ -200,7 +170,7 @@ bool ElementUseCollector::collectContainerUses(AllocBoxInst *ABI) {
200
170
//
201
171
// This will cause the dataflow to stop propagating any information at the
202
172
// use block.
203
- addElementUses (User, PMOUseKind::Escape);
173
+ Uses. emplace_back (User, PMOUseKind::Escape);
204
174
}
205
175
206
176
return true ;
@@ -221,22 +191,26 @@ bool ElementUseCollector::collectUses(SILValue Pointer) {
221
191
auto *User = UI->getUser ();
222
192
223
193
// struct_element_addr P, #field indexes into the current element.
224
- if (auto *SEAI = dyn_cast<StructElementAddrInst>(User)) {
225
- if (!collectStructElementUses (SEAI))
194
+ if (auto *seai = dyn_cast<StructElementAddrInst>(User)) {
195
+ // Generally, we set the "InStructSubElement" flag and recursively process
196
+ // the uses so that we know that we're looking at something within the
197
+ // current element.
198
+ llvm::SaveAndRestore<bool > X (InStructSubElement, true );
199
+ if (!collectUses (seai))
226
200
return false ;
227
201
continue ;
228
202
}
229
203
230
204
// Instructions that compute a subelement are handled by a helper.
231
- if (auto *TEAI = dyn_cast<TupleElementAddrInst>(User)) {
232
- if (!collectTupleElementUses (TEAI ))
205
+ if (auto *teai = dyn_cast<TupleElementAddrInst>(User)) {
206
+ if (!collectUses (teai ))
233
207
return false ;
234
208
continue ;
235
209
}
236
210
237
211
// Look through begin_access.
238
- if (auto I = dyn_cast<BeginAccessInst>(User)) {
239
- if (!collectUses (I ))
212
+ if (auto *bai = dyn_cast<BeginAccessInst>(User)) {
213
+ if (!collectUses (bai ))
240
214
return false ;
241
215
continue ;
242
216
}
@@ -251,7 +225,7 @@ bool ElementUseCollector::collectUses(SILValue Pointer) {
251
225
if (PointeeType.is <TupleType>())
252
226
UsesToScalarize.push_back (User);
253
227
else
254
- addElementUses (User, PMOUseKind::Load);
228
+ Uses. emplace_back (User, PMOUseKind::Load);
255
229
continue ;
256
230
}
257
231
@@ -279,7 +253,7 @@ bool ElementUseCollector::collectUses(SILValue Pointer) {
279
253
else
280
254
Kind = PMOUseKind::Initialization;
281
255
282
- addElementUses (User, Kind);
256
+ Uses. emplace_back (User, Kind);
283
257
continue ;
284
258
}
285
259
@@ -321,7 +295,7 @@ bool ElementUseCollector::collectUses(SILValue Pointer) {
321
295
else
322
296
Kind = PMOUseKind::Assign;
323
297
324
- addElementUses (User, Kind);
298
+ Uses. emplace_back (User, Kind);
325
299
continue ;
326
300
}
327
301
@@ -346,7 +320,7 @@ bool ElementUseCollector::collectUses(SILValue Pointer) {
346
320
if (InStructSubElement) {
347
321
return false ;
348
322
}
349
- addElementUses (User, PMOUseKind::Initialization);
323
+ Uses. emplace_back (User, PMOUseKind::Initialization);
350
324
continue ;
351
325
352
326
// Otherwise, adjust the argument index.
@@ -367,7 +341,7 @@ bool ElementUseCollector::collectUses(SILValue Pointer) {
367
341
case ParameterConvention::Indirect_In:
368
342
case ParameterConvention::Indirect_In_Constant:
369
343
case ParameterConvention::Indirect_In_Guaranteed:
370
- addElementUses (User, PMOUseKind::IndirectIn);
344
+ Uses. emplace_back (User, PMOUseKind::IndirectIn);
371
345
continue ;
372
346
373
347
// If this is an @inout parameter, it is like both a load and store.
@@ -377,7 +351,7 @@ bool ElementUseCollector::collectUses(SILValue Pointer) {
377
351
// mutating method, we model that as an escape of self. If an
378
352
// individual sub-member is passed as inout, then we model that as an
379
353
// inout use.
380
- addElementUses (User, PMOUseKind::InOutUse);
354
+ Uses. emplace_back (User, PMOUseKind::InOutUse);
381
355
continue ;
382
356
}
383
357
}
@@ -390,14 +364,14 @@ bool ElementUseCollector::collectUses(SILValue Pointer) {
390
364
if (InStructSubElement) {
391
365
return false ;
392
366
}
393
- Uses.push_back ( PMOMemoryUse ( User, PMOUseKind::Initialization) );
367
+ Uses.emplace_back ( User, PMOUseKind::Initialization);
394
368
continue ;
395
369
}
396
370
397
371
// open_existential_addr is a use of the protocol value,
398
372
// so it is modeled as a load.
399
373
if (isa<OpenExistentialAddrInst>(User)) {
400
- Uses.push_back ( PMOMemoryUse ( User, PMOUseKind::Load) );
374
+ Uses.emplace_back ( User, PMOUseKind::Load);
401
375
// TODO: Is it safe to ignore all uses of the open_existential_addr?
402
376
continue ;
403
377
}
@@ -418,7 +392,7 @@ bool ElementUseCollector::collectUses(SILValue Pointer) {
418
392
continue ;
419
393
420
394
// Otherwise, the use is something complicated, it escapes.
421
- addElementUses (User, PMOUseKind::Escape);
395
+ Uses. emplace_back (User, PMOUseKind::Escape);
422
396
}
423
397
424
398
// Now that we've walked all of the immediate uses, scalarize any operations
@@ -483,8 +457,8 @@ bool ElementUseCollector::collectUses(SILValue Pointer) {
483
457
// Now that we've scalarized some stuff, recurse down into the newly created
484
458
// element address computations to recursively process it. This can cause
485
459
// further scalarization.
486
- if (llvm::any_of (ElementAddrs, [&](SILValue V ) {
487
- return !collectTupleElementUses (cast<TupleElementAddrInst>(V ));
460
+ if (llvm::any_of (ElementAddrs, [&](SILValue v ) {
461
+ return !collectUses (cast<TupleElementAddrInst>(v ));
488
462
})) {
489
463
return false ;
490
464
}
0 commit comments