@@ -862,7 +862,7 @@ extension LifetimeDependenceDefUseWalker {
862862 return walkDownUses ( of: value, using: operand)
863863 }
864864
865- // copy_addr
865+ // copy_addr %operand to %address; %_newAddr = mark_dependence %address on %operand
866866 mutating func loadedAddressUse( of operand: Operand , intoAddress address: Operand ) -> WalkResult {
867867 if leafUse ( of: operand) == . abortWalk {
868868 return . abortWalk
@@ -971,7 +971,29 @@ extension LifetimeDependenceDefUseWalker {
971971 break
972972 case . yield:
973973 return storeToYieldDependence ( address: address, of: operand)
974- case . global, . class, . tail, . storeBorrow, . pointer, . index, . unidentified:
974+ case let . pointer( p2a) :
975+ if !address. isEscapable, let base = p2a. isResultOfUnsafeAddressor ( ) {
976+ let selfValue = base. value
977+ if selfValue. type. isAddress {
978+ // Normally an unsafeMutableAddressor is mutating, so this is the common case (address-type
979+ // 'selfValue'). Treat the store to this pointer-to-address projection just like any store to the local
980+ // variable holding 'selfValue'.
981+ return visitStoredUses ( of: operand, into: selfValue)
982+ }
983+ // selfValue.type might not an be address:
984+ // (1) mark_dependence on unsafeAddress is handled like a storedUse
985+ // (2) nonmutating unsafeMutableAddress (e.g. UnsafeMutable[Buffer]Pointer).
986+ // A nonmutating unsafeMutableAddress is only expected to happen for UnsafeMutable[Buffer]Pointer, in which case
987+
988+ // If selfValue is trivial (UnsafeMutable[Buffer]Pointer), its uses can be ignored.
989+ if selfValue. type. isTrivial ( in: selfValue. parentFunction) {
990+ return . continueWalk
991+ }
992+ // Otherwise a store to indirect memory is conservatively escaping.
993+ return escapingDependence ( on: operand)
994+ }
995+ break
996+ case . global, . class, . tail, . storeBorrow, . index, . unidentified:
975997 // An address produced by .storeBorrow should never be stored into.
976998 //
977999 // TODO: allow storing an immortal value into a global.
@@ -1045,7 +1067,7 @@ extension LifetimeDependenceDefUseWalker {
10451067 }
10461068 case . dependenceDest:
10471069 // Simply a marker that indicates the start of an in-memory dependent value. If this was a mark_dependence, uses
1048- // of its forwarded address has were visited by LocalVariableAccessWalker and recorded as separate local accesses.
1070+ // of its forwarded address were visited by LocalVariableAccessWalker and recorded as separate local accesses.
10491071 return . continueWalk
10501072 case . store, . storeBorrow:
10511073 // A store does not use the previous in-memory value.
0 commit comments