@@ -421,7 +421,7 @@ private extension AnalyzedInstructions {
421
421
if ( loopSideEffects. contains { sideEffect in
422
422
switch sideEffect {
423
423
case let storeInst as StoreInst :
424
- if storeInst. isNonInitializingStoreTo ( accessPath) {
424
+ if storeInst. storesTo ( accessPath) {
425
425
return false
426
426
}
427
427
case let loadInst as LoadInst :
@@ -438,13 +438,13 @@ private extension AnalyzedInstructions {
438
438
}
439
439
440
440
if ( loads. contains { loadInst in
441
- loadInst. mayRead ( fromAddress: storeAddr, aliasAnalysis) && loadInst . loadOwnership != . take && !loadInst. overlaps ( accessPath: accessPath)
441
+ loadInst. mayRead ( fromAddress: storeAddr, aliasAnalysis) && !loadInst. overlaps ( accessPath: accessPath)
442
442
} ) {
443
443
return false
444
444
}
445
445
446
446
if ( stores. contains { storeInst in
447
- storeInst. mayWrite ( toAddress: storeAddr, aliasAnalysis) && !storeInst. isNonInitializingStoreTo ( accessPath)
447
+ storeInst. mayWrite ( toAddress: storeAddr, aliasAnalysis) && !storeInst. storesTo ( accessPath)
448
448
} ) {
449
449
return false
450
450
}
@@ -676,10 +676,10 @@ private extension MovableInstructions {
676
676
) -> Bool {
677
677
// Initially load the value in the loop pre header.
678
678
let builder = Builder ( before: loop. preheader!. terminator, context)
679
- var storeAddr : Value ?
679
+ var firstStore : StoreInst ?
680
680
681
681
// If there are multiple stores in a block, only the last one counts.
682
- for case let storeInst as StoreInst in loadsAndStores where storeInst. isNonInitializingStoreTo ( accessPath) {
682
+ for case let storeInst as StoreInst in loadsAndStores where storeInst. storesTo ( accessPath) {
683
683
// If a store just stores the loaded value, bail. The operand (= the load)
684
684
// will be removed later, so it cannot be used as available value.
685
685
// This corner case is surprisingly hard to handle, so we just give up.
@@ -688,9 +688,9 @@ private extension MovableInstructions {
688
688
return false
689
689
}
690
690
691
- if storeAddr == nil {
692
- storeAddr = storeInst. destination
693
- } else if storeInst. destination. type != storeAddr! . type {
691
+ if firstStore == nil {
692
+ firstStore = storeInst
693
+ } else if storeInst. destination. type != firstStore! . destination . type {
694
694
// This transformation assumes that the values of all stores in the loop
695
695
// must be interchangeable. It won't work if stores different types
696
696
// because of casting or payload extraction even though they have the
@@ -699,26 +699,26 @@ private extension MovableInstructions {
699
699
}
700
700
}
701
701
702
- guard let storeAddr else {
702
+ guard let firstStore else {
703
703
return false
704
704
}
705
705
706
706
var ssaUpdater = SSAUpdater (
707
- function: storeAddr . parentFunction,
708
- type: storeAddr . type. objectType,
709
- ownership: . none,
707
+ function: firstStore . parentFunction,
708
+ type: firstStore . destination . type. objectType,
709
+ ownership: firstStore . storeOwnership == . initialize ? . owned : . none,
710
710
context
711
711
)
712
712
713
713
// Set all stored values as available values in the ssaUpdater.
714
- for case let storeInst as StoreInst in loadsAndStores where storeInst. isNonInitializingStoreTo ( accessPath) {
714
+ for case let storeInst as StoreInst in loadsAndStores where storeInst. storesTo ( accessPath) {
715
715
ssaUpdater. addAvailableValue ( storeInst. source, in: storeInst. parentBlock)
716
716
}
717
717
718
718
var cloner = Cloner ( cloneBefore: loop. preheader!. terminator, context)
719
719
defer { cloner. deinitialize ( ) }
720
720
721
- guard let initialAddr = ( cloner. cloneRecursively ( value: storeAddr ) { srcAddr, cloner in
721
+ guard let initialAddr = ( cloner. cloneRecursively ( value: firstStore . destination ) { srcAddr, cloner in
722
722
switch srcAddr {
723
723
case is AllocStackInst , is BeginBorrowInst , is MarkDependenceInst :
724
724
return . stopCloning
@@ -737,7 +737,7 @@ private extension MovableInstructions {
737
737
return false
738
738
}
739
739
740
- let ownership : LoadInst . LoadOwnership = loop . preheader! . terminator . parentFunction. hasOwnership ? . trivial : . unqualified
740
+ let ownership : LoadInst . LoadOwnership = firstStore . parentFunction. hasOwnership ? ( firstStore . storeOwnership == . initialize ? . take : . trivial) : . unqualified
741
741
742
742
let initialLoad = builder. createLoad ( fromAddress: initialAddr, ownership: ownership)
743
743
ssaUpdater. addAvailableValue ( initialLoad, in: loop. preheader!)
@@ -757,7 +757,7 @@ private extension MovableInstructions {
757
757
currentVal = nil
758
758
}
759
759
760
- if let storeInst = inst as? StoreInst , storeInst. isNonInitializingStoreTo ( accessPath) {
760
+ if let storeInst = inst as? StoreInst , storeInst. storesTo ( accessPath) {
761
761
currentVal = storeInst. source
762
762
context. erase ( instruction: storeInst)
763
763
changed = true
@@ -797,11 +797,10 @@ private extension MovableInstructions {
797
797
798
798
let builder = Builder ( before: exitBlock. instructions. first!, context)
799
799
800
- let ownership : StoreInst . StoreOwnership = exitBlock. instructions. first!. parentFunction. hasOwnership ? . trivial : . unqualified
801
800
builder. createStore (
802
801
source: ssaUpdater. getValue ( inMiddleOf: exitBlock) ,
803
802
destination: initialAddr,
804
- ownership: ownership
803
+ ownership: firstStore . storeOwnership
805
804
)
806
805
changed = true
807
806
}
@@ -982,11 +981,7 @@ private extension Instruction {
982
981
983
982
private extension StoreInst {
984
983
/// Returns a `true` if this store is a store to `accessPath`.
985
- func isNonInitializingStoreTo( _ accessPath: AccessPath ) -> Bool {
986
- if self . storeOwnership == . initialize {
987
- return false
988
- }
989
-
984
+ func storesTo( _ accessPath: AccessPath ) -> Bool {
990
985
return accessPath == self . destination. accessPath
991
986
}
992
987
}
0 commit comments