@@ -95,6 +95,7 @@ extension LifetimeDependentApply {
9595 struct LifetimeSource {
9696 let targetKind : TargetKind
9797 let convention : LifetimeDependenceConvention
98+ let isInout : Bool
9899 let value : Value
99100 }
100101
@@ -116,7 +117,8 @@ extension LifetimeDependentApply {
116117 guard let dep = applySite. resultDependence ( on: operand) else {
117118 continue
118119 }
119- info. sources. push ( LifetimeSource ( targetKind: . result, convention: dep, value: operand. value) )
120+ let isInout = applySite. convention ( of: operand) ? . isInout ?? false
121+ info. sources. push ( LifetimeSource ( targetKind: . result, convention: dep, isInout: isInout, value: operand. value) )
120122 }
121123 return info
122124 }
@@ -135,6 +137,7 @@ extension LifetimeDependentApply {
135137 ? TargetKind . yieldAddress : TargetKind . yield
136138 info. sources. push ( LifetimeSource ( targetKind: targetKind,
137139 convention: . scope( addressable: false , addressableForDeps: false ) ,
140+ isInout: false ,
138141 value: beginApply. token) )
139142 }
140143 for operand in applySite. parameterOperands {
@@ -151,7 +154,9 @@ extension LifetimeDependentApply {
151154 // However this is neccessary for safety when begin_apply gets inlined which will delete the dependence on the token.
152155 for yieldedValue in beginApply. yieldedValues {
153156 let targetKind = yieldedValue. type. isAddress ? TargetKind . yieldAddress : TargetKind . yield
154- info. sources. push ( LifetimeSource ( targetKind: targetKind, convention: dep, value: operand. value) )
157+ let isInout = applySite. convention ( of: operand) ? . isInout ?? false
158+ info. sources. push ( LifetimeSource ( targetKind: targetKind, convention: dep, isInout: isInout,
159+ value: operand. value) )
155160 }
156161 }
157162 }
@@ -180,7 +185,8 @@ extension LifetimeDependentApply {
180185 guard let dep = dep else {
181186 continue
182187 }
183- info. sources. push ( LifetimeSource ( targetKind: targetKind, convention: dep, value: operand. value) )
188+ let isInout = applySite. convention ( of: operand) ? . isInout ?? false
189+ info. sources. push ( LifetimeSource ( targetKind: targetKind, convention: dep, isInout: isInout, value: operand. value) )
184190 }
185191 return info
186192 }
@@ -223,7 +229,7 @@ private extension LifetimeDependentApply.LifetimeSourceInfo {
223229 return
224230 }
225231 // Create a new dependence on the apply's access to the argument.
226- for varIntroducer in gatherVariableIntroducers ( for: source. value, context) {
232+ for varIntroducer in gatherVariableIntroducers ( for: source. value, ignoreTrivialCopies : !source . isInout , context) {
227233 let scope = LifetimeDependence . Scope ( base: varIntroducer, context)
228234 log ( " Scoped lifetime from \( source. value) " )
229235 log ( " scope: \( scope) " )
@@ -316,11 +322,12 @@ private func insertMarkDependencies(value: Value, initializer: Instruction?,
316322/// - a variable declaration (begin_borrow [var_decl], move_value [var_decl])
317323/// - a begin_access for a mutable variable access
318324/// - the value or address "root" of the dependence chain
319- func gatherVariableIntroducers( for value: Value , _ context: Context )
325+ func gatherVariableIntroducers( for value: Value , ignoreTrivialCopies : Bool , _ context: Context )
320326 -> SingleInlineArray < Value >
321327{
322328 var introducers = SingleInlineArray < Value > ( )
323- var useDefVisitor = VariableIntroducerUseDefWalker ( context, scopedValue: value) {
329+ var useDefVisitor = VariableIntroducerUseDefWalker ( context, scopedValue: value,
330+ ignoreTrivialCopies: ignoreTrivialCopies) {
324331 introducers. push ( $0)
325332 return . continueWalk
326333 }
@@ -403,11 +410,15 @@ struct VariableIntroducerUseDefWalker : LifetimeDependenceUseDefValueWalker, Lif
403410 // Call \p visit rather than calling this directly.
404411 private let visitorClosure : ( Value ) -> WalkResult
405412
406- init ( _ context: Context , scopedValue: Value , _ visitor: @escaping ( Value ) -> WalkResult ) {
413+ init ( _ context: Context , scopedValue: Value , ignoreTrivialCopies : Bool , _ visitor: @escaping ( Value ) -> WalkResult ) {
407414 self . context = context
408- self . isTrivialScope = scopedValue. type. isAddress
409- ? scopedValue. type. objectType. isTrivial ( in: scopedValue. parentFunction)
410- : scopedValue. isTrivial ( context)
415+ if ignoreTrivialCopies {
416+ self . isTrivialScope = scopedValue. type. isAddress
417+ ? scopedValue. type. objectType. isTrivial ( in: scopedValue. parentFunction)
418+ : scopedValue. isTrivial ( context)
419+ } else {
420+ self . isTrivialScope = false
421+ }
411422 self . visitedValues = ValueSet ( context)
412423 self . visitorClosure = visitor
413424 }
@@ -472,5 +483,5 @@ let variableIntroducerTest = FunctionTest("variable_introducer") {
472483 function, arguments, context in
473484 let value = arguments. takeValue ( )
474485 print ( " Variable introducers of: \( value) " )
475- print ( gatherVariableIntroducers ( for: value, context) )
486+ print ( gatherVariableIntroducers ( for: value, ignoreTrivialCopies : false , context) )
476487}
0 commit comments