Skip to content

Commit 0a59e02

Browse files
committed
Swift AccessUtils: make AccessPathWalker private
And simplify it. This struct is not really needed by clients. It's just needed internally in 'Value.accessPath` (and similar properties) to compute the access path.
1 parent 53363c7 commit 0a59e02

File tree

2 files changed

+74
-100
lines changed

2 files changed

+74
-100
lines changed

SwiftCompilerSources/Sources/Optimizer/TestPasses/AccessDumper.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,7 @@ private struct AccessStoragePathVisitor : AccessStoragePathWalker {
5959
private func printAccessInfo(address: Value) {
6060
print("Value: \(address)")
6161

62-
var apw = AccessPathWalker()
63-
let (ap, scope) = apw.getAccessPathWithScope(of: address)
62+
let (ap, scope) = address.accessPathWithScope
6463
if let beginAccess = scope {
6564
print(" Scope: \(beginAccess)")
6665
} else {
@@ -79,9 +78,8 @@ private func printAccessInfo(address: Value) {
7978
private func checkAliasInfo(forArgumentsOf apply: ApplyInst, expectDistinct: Bool) {
8079
let address1 = apply.arguments[0]
8180
let address2 = apply.arguments[1]
82-
var apw = AccessPathWalker()
83-
let path1 = apw.getAccessPath(of: address1)
84-
let path2 = apw.getAccessPath(of: address2)
81+
let path1 = address1.accessPath
82+
let path2 = address2.accessPath
8583

8684
if path1.isDistinct(from: path2) != expectDistinct {
8785
print("wrong isDistinct result of \(apply)")

SwiftCompilerSources/Sources/Optimizer/Utilities/AccessUtils.swift

Lines changed: 71 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -337,108 +337,75 @@ enum EnclosingScope {
337337
case base(AccessBase)
338338
}
339339

340-
/// A walker utility that, given an address value, computes the `AccessPath`
341-
/// of the access (the base address and the address projections to the accessed fields) and
342-
/// the innermost enclosing scope (`begin_access`).
343-
struct AccessPathWalker {
344-
mutating func getAccessPath(of address: Value) -> AccessPath {
345-
assert(address.type.isAddress, "Expected address")
346-
walker.start()
347-
if walker.walkUp(address: address, path: Walker.Path()) == .abortWalk {
348-
assert(walker.result.base == .unidentified,
340+
private struct AccessPathWalker : AddressUseDefWalker {
341+
var result = AccessPath.unidentified()
342+
var foundBeginAccess: BeginAccessInst?
343+
344+
mutating func walk(startAt address: Value, initialPath: SmallProjectionPath = SmallProjectionPath()) {
345+
if walkUp(address: address, path: Path(projectionPath: initialPath)) == .abortWalk {
346+
assert(result.base == .unidentified,
349347
"shouldn't have set an access base in an aborted walk")
350348
}
351-
return walker.result
352349
}
353350

354-
mutating func getAccessPathWithScope(of address: Value) -> (AccessPath, scope: BeginAccessInst?) {
355-
let ap = getAccessPath(of: address)
356-
return (ap, walker.foundBeginAccess)
357-
}
351+
struct Path : SmallProjectionWalkingPath {
352+
let projectionPath: SmallProjectionPath
358353

359-
mutating func getAccessBase(of address: Value) -> AccessBase {
360-
getAccessPath(of: address).base
361-
}
354+
// Tracks whether an `index_addr` instruction was crossed.
355+
// It should be (FIXME: check if it's enforced) that operands
356+
// of `index_addr` must be `tail_addr` or other `index_addr` results.
357+
let indexAddr: Bool
362358

363-
mutating func getEnclosingScope(of address: Value) -> EnclosingScope {
364-
let accessPath = getAccessPath(of: address)
365-
366-
if let ba = walker.foundBeginAccess {
367-
return .scope(ba)
359+
init(projectionPath: SmallProjectionPath = SmallProjectionPath(), indexAddr: Bool = false) {
360+
self.projectionPath = projectionPath
361+
self.indexAddr = indexAddr
368362
}
369-
return .base(accessPath.base)
370-
}
371-
372-
private var walker = Walker()
373-
374-
private struct Walker : AddressUseDefWalker {
375-
private(set) var result = AccessPath.unidentified()
376-
private(set) var foundBeginAccess: BeginAccessInst?
377363

378-
mutating func start() {
379-
result = .unidentified()
380-
foundBeginAccess = nil
364+
func with(projectionPath: SmallProjectionPath) -> Self {
365+
return Self(projectionPath: projectionPath, indexAddr: indexAddr)
381366
}
382367

383-
struct Path : SmallProjectionWalkingPath {
384-
let projectionPath: SmallProjectionPath
385-
386-
// Tracks whether an `index_addr` instruction was crossed.
387-
// It should be (FIXME: check if it's enforced) that operands
388-
// of `index_addr` must be `tail_addr` or other `index_addr` results.
389-
let indexAddr: Bool
390-
391-
init(projectionPath: SmallProjectionPath = SmallProjectionPath(), indexAddr: Bool = false) {
392-
self.projectionPath = projectionPath
393-
self.indexAddr = indexAddr
394-
}
395-
396-
func with(projectionPath: SmallProjectionPath) -> Self {
397-
return Self(projectionPath: projectionPath, indexAddr: indexAddr)
398-
}
399-
400-
func with(indexAddr: Bool) -> Self {
401-
return Self(projectionPath: projectionPath, indexAddr: indexAddr)
402-
}
368+
func with(indexAddr: Bool) -> Self {
369+
return Self(projectionPath: projectionPath, indexAddr: indexAddr)
370+
}
403371

404-
func merge(with other: Self) -> Self {
405-
return Self(
406-
projectionPath: projectionPath.merge(with: other.projectionPath),
407-
indexAddr: indexAddr || other.indexAddr
408-
)
409-
}
372+
func merge(with other: Self) -> Self {
373+
return Self(
374+
projectionPath: projectionPath.merge(with: other.projectionPath),
375+
indexAddr: indexAddr || other.indexAddr
376+
)
410377
}
378+
}
411379

412-
mutating func rootDef(address: Value, path: Path) -> WalkResult {
413-
assert(result.base == .unidentified, "rootDef should only called once")
414-
// Try identifying the address a pointer originates from
415-
if let p2ai = address as? PointerToAddressInst {
416-
if let originatingAddr = p2ai.originatingAddress {
417-
return walkUp(address: originatingAddr, path: path)
418-
} else {
419-
self.result = AccessPath(base: .pointer(p2ai), projectionPath: path.projectionPath)
420-
return .continueWalk
421-
}
380+
mutating func rootDef(address: Value, path: Path) -> WalkResult {
381+
assert(result.base == .unidentified, "rootDef should only called once")
382+
// Try identifying the address a pointer originates from
383+
if let p2ai = address as? PointerToAddressInst {
384+
if let originatingAddr = p2ai.originatingAddress {
385+
return walkUp(address: originatingAddr, path: path)
386+
} else {
387+
self.result = AccessPath(base: .pointer(p2ai), projectionPath: path.projectionPath)
388+
return .continueWalk
422389
}
423-
424-
let base = AccessBase(baseAddress: address)
425-
self.result = AccessPath(base: base, projectionPath: path.projectionPath)
426-
return .continueWalk
427390
}
428391

429-
mutating func walkUp(address: Value, path: Path) -> WalkResult {
430-
if address is IndexAddrInst {
431-
// Track that we crossed an `index_addr` during the walk-up
432-
return walkUpDefault(address: address, path: path.with(indexAddr: true))
433-
} else if path.indexAddr && !canBeOperandOfIndexAddr(address) {
434-
// An `index_addr` instruction cannot be derived from an address
435-
// projection. Bail out
436-
return .abortWalk
437-
} else if let ba = address as? BeginAccessInst, foundBeginAccess == nil {
438-
foundBeginAccess = ba
439-
}
440-
return walkUpDefault(address: address, path: path.with(indexAddr: false))
392+
let base = AccessBase(baseAddress: address)
393+
self.result = AccessPath(base: base, projectionPath: path.projectionPath)
394+
return .continueWalk
395+
}
396+
397+
mutating func walkUp(address: Value, path: Path) -> WalkResult {
398+
if address is IndexAddrInst {
399+
// Track that we crossed an `index_addr` during the walk-up
400+
return walkUpDefault(address: address, path: path.with(indexAddr: true))
401+
} else if path.indexAddr && !canBeOperandOfIndexAddr(address) {
402+
// An `index_addr` instruction cannot be derived from an address
403+
// projection. Bail out
404+
return .abortWalk
405+
} else if let ba = address as? BeginAccessInst, foundBeginAccess == nil {
406+
foundBeginAccess = ba
441407
}
408+
return walkUpDefault(address: address, path: path.with(indexAddr: false))
442409
}
443410
}
444411

@@ -451,27 +418,36 @@ extension Value {
451418
// go through phi-arguments, the AccessPathWalker will allocate memnory in its cache.
452419

453420
/// Computes the access base of this address value.
454-
var accessBase: AccessBase {
455-
var apWalker = AccessPathWalker()
456-
return apWalker.getAccessBase(of: self)
457-
}
421+
var accessBase: AccessBase { accessPath.base }
458422

459423
/// Computes the access path of this address value.
460424
var accessPath: AccessPath {
461-
var apWalker = AccessPathWalker()
462-
return apWalker.getAccessPath(of: self)
425+
var walker = AccessPathWalker()
426+
walker.walk(startAt: self)
427+
return walker.result
428+
}
429+
430+
func getAccessPath(fromInitialPath: SmallProjectionPath) -> AccessPath {
431+
var walker = AccessPathWalker()
432+
walker.walk(startAt: self, initialPath: fromInitialPath)
433+
return walker.result
463434
}
464435

465436
/// Computes the access path of this address value and also returns the scope.
466437
var accessPathWithScope: (AccessPath, scope: BeginAccessInst?) {
467-
var apWalker = AccessPathWalker()
468-
return apWalker.getAccessPathWithScope(of: self)
438+
var walker = AccessPathWalker()
439+
walker.walk(startAt: self)
440+
return (walker.result, walker.foundBeginAccess)
469441
}
470442

471443
/// Computes the enclosing access scope of this address value.
472444
var enclosingAccessScope: EnclosingScope {
473-
var apWalker = AccessPathWalker()
474-
return apWalker.getEnclosingScope(of: self)
445+
var walker = AccessPathWalker()
446+
walker.walk(startAt: self)
447+
if let ba = walker.foundBeginAccess {
448+
return .scope(ba)
449+
}
450+
return .base(walker.result.base)
475451
}
476452
}
477453

0 commit comments

Comments
 (0)