Skip to content

Commit 5fc103b

Browse files
committed
[NFC] AccessUtils: add accessBaseWithScopes
And simplify enclosingAccessScope. These two APIs now directly compute what is being asked for. Previously, each invocation of enclosingAccessScope would recompute the base and all nested scopes, but throw away that information. Sometimes we do not want to compute that information, and other times we need all of it. Instead, provide separate APIs that do exactly what is needed. These are common APIs used by other utilities. This avoids quadratic traversals in those cases. It is also easier to understand and debug. These utilities will be used in LifetimeDependenceScopeFixup.
1 parent 0fb3cb9 commit 5fc103b

File tree

1 file changed

+42
-8
lines changed

1 file changed

+42
-8
lines changed

SwiftCompilerSources/Sources/SIL/Utilities/AccessUtils.swift

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -502,9 +502,40 @@ public enum EnclosingScope {
502502
case base(AccessBase)
503503
}
504504

505+
private struct EnclosingAccessWalker : AddressUseDefWalker {
506+
var enclosingScope: EnclosingScope?
507+
508+
mutating func walk(startAt address: Value, initialPath: UnusedWalkingPath = UnusedWalkingPath()) {
509+
if walkUp(address: address, path: UnusedWalkingPath()) == .abortWalk {
510+
assert(enclosingScope == nil, "shouldn't have set an enclosing scope in an aborted walk")
511+
}
512+
}
513+
514+
mutating func rootDef(address: Value, path: UnusedWalkingPath) -> WalkResult {
515+
assert(enclosingScope == nil, "rootDef should only called once")
516+
// Try identifying the address a pointer originates from
517+
if let p2ai = address as? PointerToAddressInst, let originatingAddr = p2ai.originatingAddress {
518+
return walkUp(address: originatingAddr, path: path)
519+
}
520+
enclosingScope = .base(AccessBase(baseAddress: address))
521+
return .continueWalk
522+
}
523+
524+
mutating func walkUp(address: Value, path: UnusedWalkingPath) -> WalkResult {
525+
if let ba = address as? BeginAccessInst {
526+
enclosingScope = .scope(ba)
527+
return .continueWalk
528+
}
529+
return walkUpDefault(address: address, path: path)
530+
}
531+
}
532+
505533
private struct AccessPathWalker : AddressUseDefWalker {
506534
var result = AccessPath.unidentified()
507-
var foundBeginAccess: BeginAccessInst?
535+
536+
// List of nested BeginAccessInst: inside-out order.
537+
var foundBeginAccesses = SingleInlineArray<BeginAccessInst>()
538+
508539
let enforceConstantProjectionPath: Bool
509540

510541
init(enforceConstantProjectionPath: Bool = false) {
@@ -570,8 +601,8 @@ private struct AccessPathWalker : AddressUseDefWalker {
570601
// An `index_addr` instruction cannot be derived from an address
571602
// projection. Bail out
572603
return .abortWalk
573-
} else if let ba = address as? BeginAccessInst, foundBeginAccess == nil {
574-
foundBeginAccess = ba
604+
} else if let ba = address as? BeginAccessInst {
605+
foundBeginAccesses.push(ba)
575606
}
576607
return walkUpDefault(address: address, path: path.with(indexAddr: false))
577608
}
@@ -624,17 +655,20 @@ extension Value {
624655
public var accessPathWithScope: (AccessPath, scope: BeginAccessInst?) {
625656
var walker = AccessPathWalker()
626657
walker.walk(startAt: self)
627-
return (walker.result, walker.foundBeginAccess)
658+
return (walker.result, walker.foundBeginAccesses.first)
628659
}
629660

630661
/// Computes the enclosing access scope of this address value.
631662
public var enclosingAccessScope: EnclosingScope {
663+
var walker = EnclosingAccessWalker()
664+
walker.walk(startAt: self)
665+
return walker.enclosingScope ?? .base(.unidentified)
666+
}
667+
668+
public var accessBaseWithScopes: (AccessBase, SingleInlineArray<BeginAccessInst>) {
632669
var walker = AccessPathWalker()
633670
walker.walk(startAt: self)
634-
if let ba = walker.foundBeginAccess {
635-
return .scope(ba)
636-
}
637-
return .base(walker.result.base)
671+
return (walker.result.base, walker.foundBeginAccesses)
638672
}
639673

640674
/// The root definition of a reference, obtained by skipping ownership forwarding and ownership transition.

0 commit comments

Comments
 (0)