@@ -66,6 +66,8 @@ struct LifetimeDependence : CustomStringConvertible {
66
66
/// A local variable scope without ownership. The scope must be introduced by either move_value or
67
67
/// begin_borrow. LinearLiveness computes the scope boundary.
68
68
case local( VariableScopeInstruction )
69
+ /// A directly accessed global variable without exclusivity. Presumably immutable and therefore immortal.
70
+ case global( GlobalAddrInst )
69
71
/// Singly-initialized addressable storage (likely for an immutable address-only value). The lifetime extends until
70
72
/// the memory is destroyed. e.g. A value produced by an @in FunctionArgument, an @out apply, or an @inout
71
73
/// FunctionArgument that is never modified inside the callee. Modified @inout FunctionArguments have caller scoped
@@ -82,6 +84,7 @@ struct LifetimeDependence : CustomStringConvertible {
82
84
case let . owned( value) : return value
83
85
case let . borrowed( beginBorrow) : return beginBorrow. value
84
86
case let . local( varScope) : return varScope. scopeBegin
87
+ case let . global( ga) : return ga
85
88
case let . initialized( initializer) : return initializer. initialAddress
86
89
case let . unknown( value) : return value
87
90
}
@@ -91,7 +94,7 @@ struct LifetimeDependence : CustomStringConvertible {
91
94
switch self {
92
95
case let . caller( argument) :
93
96
precondition ( argument. ownership != . owned, " only guaranteed or inout arguments have a caller scope " )
94
- case . access, . local, . unknown:
97
+ case . access, . local, . global , . unknown:
95
98
break
96
99
case let . yield( value) :
97
100
precondition ( value. definingInstruction is BeginApplyInst )
@@ -119,6 +122,7 @@ struct LifetimeDependence : CustomStringConvertible {
119
122
case . owned: return " Owned: "
120
123
case . borrowed: return " Borrowed: "
121
124
case . local: return " Local: "
125
+ case . global: return " Global: "
122
126
case . initialized: return " Initialized: "
123
127
case . unknown: return " Unknown: "
124
128
}
@@ -254,8 +258,15 @@ extension LifetimeDependence.Scope {
254
258
case let . box( projectBox) :
255
259
// Note: the box may be in a borrow scope.
256
260
self . init ( base: projectBox. operand. value, context)
257
- case . stack, . global, . class, . tail, . pointer, . index, . unidentified:
258
- self = . unknown( accessBase. address ?? address)
261
+ case . stack, . class, . tail, . pointer, . index, . unidentified:
262
+ self = . unknown( accessBase. address!)
263
+ case . global:
264
+ // TODO: When AccessBase stores global_addr, we don't need a check here and don't need to pass 'address' in.
265
+ if let ga = address as? GlobalAddrInst {
266
+ self = . global( ga)
267
+ } else {
268
+ self = . unknown( accessBase. address!)
269
+ }
259
270
case let . argument( arg) :
260
271
if arg. convention. isIndirectIn {
261
272
if arg. convention. isGuaranteed {
@@ -321,6 +332,8 @@ extension LifetimeDependence.Scope {
321
332
self = . caller( arg)
322
333
} else if let varScope = VariableScopeInstruction ( value. definingInstruction) {
323
334
self = . local( varScope)
335
+ } else if let ga = value as? GlobalAddrInst {
336
+ self = . global( ga)
324
337
} else {
325
338
self = . unknown( value)
326
339
}
@@ -365,7 +378,7 @@ extension LifetimeDependence.Scope {
365
378
/// Note: The caller must deinitialize the returned range.
366
379
func computeRange( _ context: Context ) -> InstructionRange ? {
367
380
switch self {
368
- case . caller:
381
+ case . caller, . global :
369
382
return nil
370
383
case let . access( beginAccess) :
371
384
var range = InstructionRange ( begin: beginAccess, context)
0 commit comments