Skip to content

Commit fa3ebb5

Browse files
committed
LifetimeDependence.Scope add global variable support.
This fixes functions that return @Lifetime(immortal).
1 parent 39bae0b commit fa3ebb5

File tree

4 files changed

+44
-15
lines changed

4 files changed

+44
-15
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/LifetimeDependenceUtils.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ struct LifetimeDependence : CustomStringConvertible {
6767
/// begin_borrow. LinearLiveness computes the scope boundary.
6868
case local(VariableScopeInstruction)
6969
/// A directly accessed global variable without exclusivity. Presumably immutable and therefore immortal.
70-
case global(GlobalAddrInst)
70+
case global(GlobalAccessBase)
7171
/// Singly-initialized addressable storage (likely for an immutable address-only value). The lifetime extends until
7272
/// the memory is destroyed. e.g. A value produced by an @in FunctionArgument, an @out apply, or an @inout
7373
/// FunctionArgument that is never modified inside the callee. Modified @inout FunctionArguments have caller scoped
@@ -84,7 +84,7 @@ struct LifetimeDependence : CustomStringConvertible {
8484
case let .owned(value): return value
8585
case let .borrowed(beginBorrow): return beginBorrow.value
8686
case let .local(varScope): return varScope.scopeBegin
87-
case let .global(ga): return ga
87+
case let .global(ga): return ga.address
8888
case let .initialized(initializer): return initializer.initialAddress
8989
case let .unknown(value): return value
9090
}
@@ -261,11 +261,12 @@ extension LifetimeDependence.Scope {
261261
case .stack, .class, .tail, .pointer, .index, .unidentified:
262262
self = .unknown(accessBase.address!)
263263
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 {
264+
// TODO: When AccessBase directly stores GlobalAccessBase, we don't need a check here and don't need to pass
265+
// 'address' in to this function.
266+
if let ga = GlobalAccessBase(address: address) {
266267
self = .global(ga)
267268
} else {
268-
self = .unknown(accessBase.address!)
269+
self = .unknown(accessBase.address ?? address)
269270
}
270271
case let .argument(arg):
271272
if arg.convention.isIndirectIn {
@@ -332,7 +333,7 @@ extension LifetimeDependence.Scope {
332333
self = .caller(arg)
333334
} else if let varScope = VariableScopeInstruction(value.definingInstruction) {
334335
self = .local(varScope)
335-
} else if let ga = value as? GlobalAddrInst {
336+
} else if let ga = GlobalAccessBase(address: value) {
336337
self = .global(ga)
337338
} else {
338339
self = .unknown(value)

SwiftCompilerSources/Sources/SIL/Utilities/AccessUtils.swift

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ private func canBeOperandOfIndexAddr(_ value: Value) -> Bool {
428428
/// %ptr = address_to_pointer %orig_addr
429429
/// %addr = pointer_to_address %ptr
430430
/// ```
431-
private extension PointerToAddressInst {
431+
public extension PointerToAddressInst {
432432
var originatingAddress: Value? {
433433

434434
struct Walker : ValueUseDefWalker {
@@ -481,6 +481,33 @@ private extension PointerToAddressInst {
481481
}
482482
}
483483

484+
/// TODO: migrate AccessBase to use this instead of GlobalVariable because many utilities need to get back to a
485+
/// representative SIL Value.
486+
public enum GlobalAccessBase {
487+
case global(GlobalAddrInst)
488+
case initializer(PointerToAddressInst)
489+
490+
public init?(address: Value) {
491+
switch address {
492+
case let ga as GlobalAddrInst:
493+
self = .global(ga)
494+
case let p2a as PointerToAddressInst where p2a.resultOfGlobalAddressorCall != nil:
495+
self = .initializer(p2a)
496+
default:
497+
return nil
498+
}
499+
}
500+
501+
public var address: Value {
502+
switch self {
503+
case let .global(ga):
504+
return ga
505+
case let .initializer(p2a):
506+
return p2a
507+
}
508+
}
509+
}
510+
484511
/// The `EnclosingAccessScope` of an access is the innermost `begin_access`
485512
/// instruction that checks for exclusivity of the access.
486513
/// If there is no `begin_access` instruction found, then the scope is

test/SILOptimizer/lifetime_dependence/lifetime_dependence_borrow_fail.swift

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,6 @@ func bv_incorrect_annotation2(_ w1: borrowing Wrapper, _ w2: borrowing Wrapper)
8080
return w1.bv // expected-note @-1{{it depends on the lifetime of argument 'w1'}}
8181
} // expected-note @-1{{this use causes the lifetime-dependent value to escape}}
8282

83-
let ptr = UnsafeRawPointer(bitPattern: 1)!
84-
let nc = NC(ptr, 0)
85-
86-
func bv_global(dummy: BV) -> BV {
87-
nc.getBV() // expected-error {{lifetime-dependent value escapes its scope}}
88-
// expected-note @-4{{it depends on the lifetime of variable 'nc'}}
89-
} // expected-note {{this use causes the lifetime-dependent value to escape}}
90-
9183
func testEmpty(nc: consuming NC) {
9284
var e: Empty // expected-error {{lifetime-dependent variable 'e' escapes its scope}}
9385
do {

test/SILOptimizer/lifetime_dependence/semantics.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,15 @@ func testImmortalString() -> Span<String> {
338338
return _overrideLifetime(span, borrowing: immortalString)
339339
}
340340

341+
let ptr = UnsafePointer<Int>(bitPattern: 1)!
342+
let globalTrivial = InnerTrivial(p: ptr)
343+
344+
// An immortal span can depend on a caller's local borrow scope even though the callee sees no such dependency.
345+
@lifetime(borrow local)
346+
func testGlobal(local: InnerTrivial) -> Span<Int> {
347+
globalTrivial.span()
348+
}
349+
341350
// =============================================================================
342351
// Scoped dependence on mutable values
343352
// =============================================================================

0 commit comments

Comments
 (0)