Skip to content

Commit 17319fa

Browse files
committed
Improve the AddressUtils and OwnershipLiveness APIs
1 parent 800fa16 commit 17319fa

File tree

3 files changed

+35
-9
lines changed

3 files changed

+35
-9
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/AddressUtils.swift

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,19 @@ protocol AddressUseVisitor {
3434
/// An access scope: begin_access, begin_apply, load_borrow.
3535
mutating func scopedAddressUse(of operand: Operand) -> WalkResult
3636

37+
/// end_access, end_apply, abort_apply, end_borrow.
38+
mutating func scopeEndingAddressUse(of operand: Operand) -> WalkResult
39+
3740
/// A address leaf use cannot propagate the address bits beyond the
3841
/// instruction.
3942
///
40-
/// An apply or builtin propagates an address into the callee, but
41-
/// it is considered a leaf use as long as the argument does not escape.
43+
/// StoringInstructions are leaf uses.
4244
mutating func leafAddressUse(of operand: Operand) -> WalkResult
4345

46+
/// An address used by an apply.
47+
mutating func appliedAddressUse(of operand: Operand, by apply: FullApplySite)
48+
-> WalkResult
49+
4450
/// A loaded address use propagates the value at the address.
4551
mutating func loadedAddressUse(of operand: Operand, into value: Value)
4652
-> WalkResult
@@ -67,10 +73,12 @@ extension AddressUseVisitor {
6773
/// protocol methods above.
6874
mutating func classifyAddress(operand: Operand) -> WalkResult {
6975
switch operand.instruction {
70-
case is BeginAccessInst, is BeginApplyInst, is LoadBorrowInst,
71-
is StoreBorrowInst:
76+
case is BeginAccessInst, is LoadBorrowInst, is StoreBorrowInst:
7277
return scopedAddressUse(of: operand)
7378

79+
case is EndAccessInst, is EndApplyInst, is AbortApplyInst, is EndBorrowInst:
80+
return scopeEndingAddressUse(of: operand)
81+
7482
case let markDep as MarkDependenceInst:
7583
if markDep.valueOperand == operand {
7684
return projectedAddressUse(of: operand, into: markDep)
@@ -81,7 +89,7 @@ extension AddressUseVisitor {
8189
if markDep.type.isAddress {
8290
return projectedAddressUse(of: operand, into: markDep)
8391
}
84-
if LifetimeDependence(markDependence: markDep, context) != nil {
92+
if LifetimeDependence(markDep, context) != nil {
8593
// This is unreachable from InteriorUseVisitor because the
8694
// base address of a `mark_dependence [nonescaping]` must be a
8795
// `begin_access`, and interior liveness does not check uses of
@@ -97,7 +105,7 @@ extension AddressUseVisitor {
97105
case let pai as PartialApplyInst where !pai.isOnStack:
98106
return escapingAddressUse(of: operand)
99107

100-
case is AddressToPointerInst:
108+
case is ReturnInst, is ThrowInst, is YieldInst, is AddressToPointerInst:
101109
return escapingAddressUse(of: operand)
102110

103111
case is StructElementAddrInst, is TupleElementAddrInst,
@@ -113,16 +121,18 @@ extension AddressUseVisitor {
113121
let svi = operand.instruction as! SingleValueInstruction
114122
return projectedAddressUse(of: operand, into: svi)
115123

116-
case is ReturnInst, is ThrowInst, is YieldInst, is TryApplyInst,
117-
is SwitchEnumAddrInst, is CheckedCastAddrBranchInst,
124+
case let apply as FullApplySite:
125+
return appliedAddressUse(of: operand, by: apply)
126+
127+
case is SwitchEnumAddrInst, is CheckedCastAddrBranchInst,
118128
is SelectEnumAddrInst, is InjectEnumAddrInst,
119129
is StoreInst, is StoreUnownedInst, is StoreWeakInst,
120130
is AssignInst, is AssignByWrapperInst, is AssignOrInitInst,
121131
is TupleAddrConstructorInst, is InitBlockStorageHeaderInst,
122132
is RetainValueAddrInst, is ReleaseValueAddrInst,
123133
is DestroyAddrInst, is DeallocStackInst,
124134
is DeinitExistentialAddrInst,
125-
is EndApplyInst, is IsUniqueInst, is MarkFunctionEscapeInst,
135+
is IsUniqueInst, is MarkFunctionEscapeInst,
126136
is PackElementSetInst:
127137
return leafAddressUse(of: operand)
128138

SwiftCompilerSources/Sources/Optimizer/Utilities/OwnershipLiveness.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,14 @@ extension InteriorUseWalker: AddressUseVisitor {
631631
return walkDownAddressUses(of: value)
632632
}
633633

634+
mutating func appliedAddressUse(of operand: Operand, by apply: FullApplySite)
635+
-> WalkResult {
636+
if apply is BeginApplyInst {
637+
return scopedAddressUse(of: operand)
638+
}
639+
return leafAddressUse(of: operand)
640+
}
641+
634642
mutating func scopedAddressUse(of operand: Operand) -> WalkResult {
635643
switch operand.instruction {
636644
case let ba as BeginAccessInst:
@@ -664,6 +672,10 @@ extension InteriorUseWalker: AddressUseVisitor {
664672
}
665673
}
666674

675+
mutating func scopeEndingAddressUse(of operand: Operand) -> WalkResult {
676+
return .continueWalk
677+
}
678+
667679
mutating func leafAddressUse(of operand: Operand) -> WalkResult {
668680
return .continueWalk
669681
}

SwiftCompilerSources/Sources/SIL/Utilities/AccessUtils.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,10 @@ extension Value {
575575
/// %addr = struct_element_addr %base : $X, #X.e
576576
/// store %v to [trivial] %addr : $*Int
577577
/// ```
578+
///
579+
/// Warning: This does not find the correct storage root of the
580+
/// lifetime of an object projection, such as .box or .class because
581+
/// ValueUseDefWalker ignores ownership and, for example, walks past copies.
578582
extension ValueUseDefWalker where Path == SmallProjectionPath {
579583
/// The main entry point.
580584
/// Given an `accessPath` where the access base is a reference (class, tail, box), call

0 commit comments

Comments
 (0)