@@ -339,56 +339,29 @@ bool SemanticARCOptVisitor::visitCopyValueInst(CopyValueInst *cvi) {
339
339
// load [copy] Optimizations
340
340
// ===----------------------------------------------------------------------===//
341
341
342
- // / A flow insensitive analysis that tells the load [copy] analysis if the
343
- // / storage has 0, 1, >1 writes to it.
344
- // /
345
- // / In the case of 0 writes, we return CanOptimizeLoadCopyResult::Always.
346
- // /
347
- // / In the case of 1 write, we return OnlyIfStorageIsLocal. We are taking
348
- // / advantage of definite initialization implying that an alloc_stack must be
349
- // / written to once before any loads from the memory location. Thus if we are
350
- // / local and see 1 write, we can still change to load_borrow if all other uses
351
- // / check out.
352
- // /
353
- // / If there is 2+ writes, we can not optimize = (.
354
- namespace {
355
-
356
- struct CanOptimizeLoadCopyFromAccessVisitor
357
- : AccessedStorageVisitor<CanOptimizeLoadCopyFromAccessVisitor, bool > {
358
- SILFunction &f;
359
-
360
- CanOptimizeLoadCopyFromAccessVisitor (SILFunction &f) : f(f) {}
361
-
362
- // Stubs
363
- bool visitBox (const AccessedStorage &boxStorage) { return false ; }
364
- bool visitStack (const AccessedStorage &stackStorage) { return false ; }
365
- bool visitGlobal (const AccessedStorage &globalStorage) { return false ; }
366
- bool visitClass (const AccessedStorage &classStorage) { return false ; }
367
- bool visitYield (const AccessedStorage &yieldStorage) { return false ; }
368
- bool visitUnidentified (const AccessedStorage &unidentifiedStorage) {
369
- return false ;
370
- }
371
- bool visitNested (const AccessedStorage &nested) {
372
- llvm_unreachable (" Visitor should never see nested since we lookup our "
373
- " address storage using lookup non nested" );
374
- }
375
-
376
- bool visitArgument (const AccessedStorage &argumentStorage);
377
- };
378
-
379
- } // namespace
342
+ // A flow insensitive analysis that tells the load [copy] analysis if the
343
+ // storage has 0, 1, >1 writes to it.
344
+ //
345
+ // In the case of 0 writes, we return CanOptimizeLoadCopyResult::Always.
346
+ //
347
+ // In the case of 1 write, we return OnlyIfStorageIsLocal. We are taking
348
+ // advantage of definite initialization implying that an alloc_stack must be
349
+ // written to once before any loads from the memory location. Thus if we are
350
+ // local and see 1 write, we can still change to load_borrow if all other uses
351
+ // check out.
352
+ //
353
+ // If there is 2+ writes, we can not optimize = (.
380
354
381
- bool CanOptimizeLoadCopyFromAccessVisitor::visitArgument (
382
- const AccessedStorage &storage) {
355
+ bool mayFunctionMutateArgument (const AccessedStorage &storage, SILFunction &f) {
383
356
auto *arg = cast<SILFunctionArgument>(storage.getArgument (&f));
384
357
385
358
// Then check if we have an in_guaranteed argument. In this case, we can
386
359
// always optimize load [copy] from this.
387
360
if (arg->hasConvention (SILArgumentConvention::Indirect_In_Guaranteed))
388
- return true ;
361
+ return false ;
389
362
390
363
// For now just return false.
391
- return false ;
364
+ return true ;
392
365
}
393
366
394
367
static bool isWrittenTo (SILFunction &f, SILValue value) {
@@ -402,7 +375,19 @@ static bool isWrittenTo(SILFunction &f, SILValue value) {
402
375
// way (ignoring stores that are obviously the only initializer to
403
376
// memory). We have to do this since load_borrow assumes that the
404
377
// underlying memory is never written to.
405
- return !CanOptimizeLoadCopyFromAccessVisitor (f).visit (storage);
378
+ switch (storage.getKind ()) {
379
+ case AccessedStorage::Box:
380
+ case AccessedStorage::Stack:
381
+ case AccessedStorage::Global:
382
+ case AccessedStorage::Class:
383
+ case AccessedStorage::Yield:
384
+ case AccessedStorage::Nested:
385
+ case AccessedStorage::Unidentified:
386
+ return true ;
387
+
388
+ case AccessedStorage::Argument:
389
+ return mayFunctionMutateArgument (storage, f);
390
+ }
406
391
}
407
392
408
393
// Convert a load [copy] from unique storage [read] that has all uses that can
0 commit comments