@@ -95,6 +95,7 @@ extension LifetimeDependentApply {
95
95
struct LifetimeSource {
96
96
let targetKind : TargetKind
97
97
let convention : LifetimeDependenceConvention
98
+ let isInout : Bool
98
99
let value : Value
99
100
}
100
101
@@ -116,7 +117,8 @@ extension LifetimeDependentApply {
116
117
guard let dep = applySite. resultDependence ( on: operand) else {
117
118
continue
118
119
}
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) )
120
122
}
121
123
return info
122
124
}
@@ -135,6 +137,7 @@ extension LifetimeDependentApply {
135
137
? TargetKind . yieldAddress : TargetKind . yield
136
138
info. sources. push ( LifetimeSource ( targetKind: targetKind,
137
139
convention: . scope( addressable: false , addressableForDeps: false ) ,
140
+ isInout: false ,
138
141
value: beginApply. token) )
139
142
}
140
143
for operand in applySite. parameterOperands {
@@ -151,7 +154,9 @@ extension LifetimeDependentApply {
151
154
// However this is neccessary for safety when begin_apply gets inlined which will delete the dependence on the token.
152
155
for yieldedValue in beginApply. yieldedValues {
153
156
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) )
155
160
}
156
161
}
157
162
}
@@ -180,7 +185,8 @@ extension LifetimeDependentApply {
180
185
guard let dep = dep else {
181
186
continue
182
187
}
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) )
184
190
}
185
191
return info
186
192
}
@@ -223,7 +229,7 @@ private extension LifetimeDependentApply.LifetimeSourceInfo {
223
229
return
224
230
}
225
231
// 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) {
227
233
let scope = LifetimeDependence . Scope ( base: varIntroducer, context)
228
234
log ( " Scoped lifetime from \( source. value) " )
229
235
log ( " scope: \( scope) " )
@@ -316,11 +322,12 @@ private func insertMarkDependencies(value: Value, initializer: Instruction?,
316
322
/// - a variable declaration (begin_borrow [var_decl], move_value [var_decl])
317
323
/// - a begin_access for a mutable variable access
318
324
/// - 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 )
320
326
-> SingleInlineArray < Value >
321
327
{
322
328
var introducers = SingleInlineArray < Value > ( )
323
- var useDefVisitor = VariableIntroducerUseDefWalker ( context, scopedValue: value) {
329
+ var useDefVisitor = VariableIntroducerUseDefWalker ( context, scopedValue: value,
330
+ ignoreTrivialCopies: ignoreTrivialCopies) {
324
331
introducers. push ( $0)
325
332
return . continueWalk
326
333
}
@@ -403,11 +410,15 @@ struct VariableIntroducerUseDefWalker : LifetimeDependenceUseDefValueWalker, Lif
403
410
// Call \p visit rather than calling this directly.
404
411
private let visitorClosure : ( Value ) -> WalkResult
405
412
406
- init ( _ context: Context , scopedValue: Value , _ visitor: @escaping ( Value ) -> WalkResult ) {
413
+ init ( _ context: Context , scopedValue: Value , ignoreTrivialCopies : Bool , _ visitor: @escaping ( Value ) -> WalkResult ) {
407
414
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
+ }
411
422
self . visitedValues = ValueSet ( context)
412
423
self . visitorClosure = visitor
413
424
}
@@ -472,5 +483,5 @@ let variableIntroducerTest = FunctionTest("variable_introducer") {
472
483
function, arguments, context in
473
484
let value = arguments. takeValue ( )
474
485
print ( " Variable introducers of: \( value) " )
475
- print ( gatherVariableIntroducers ( for: value, context) )
486
+ print ( gatherVariableIntroducers ( for: value, ignoreTrivialCopies : false , context) )
476
487
}
0 commit comments