Skip to content

Commit ce153a8

Browse files
committed
[NFC] extend AddressInitializationWalker to report address reads
1 parent 432e316 commit ce153a8

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/AddressUtils.swift

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ extension AccessBase {
312312
struct AddressInitializationWalker: AddressDefUseWalker, AddressUseVisitor {
313313
let baseAddress: Value
314314
let requireFullyAssigned: IsFullyAssigned
315+
let onRead: WalkResult
315316
let context: any Context
316317

317318
var walkDownCache = WalkerCache<SmallProjectionPath>()
@@ -320,20 +321,21 @@ struct AddressInitializationWalker: AddressDefUseWalker, AddressUseVisitor {
320321
var initializer: AccessBase.Initializer?
321322

322323
static func findSingleInitializer(ofAddress baseAddr: Value, requireFullyAssigned: IsFullyAssigned,
323-
_ context: some Context)
324+
allowRead: Bool = true, _ context: some Context)
324325
-> AccessBase.Initializer? {
325326

326-
var walker = AddressInitializationWalker(baseAddress: baseAddr, requireFullyAssigned, context)
327+
var walker = AddressInitializationWalker(baseAddress: baseAddr, requireFullyAssigned, allowRead: allowRead, context)
327328
if walker.walkDownUses(ofAddress: baseAddr, path: SmallProjectionPath()) == .abortWalk {
328329
return nil
329330
}
330331
return walker.initializer
331332
}
332333

333-
private init(baseAddress: Value, _ requireFullyAssigned: IsFullyAssigned, _ context: some Context) {
334+
private init(baseAddress: Value, _ requireFullyAssigned: IsFullyAssigned, allowRead: Bool, _ context: some Context) {
334335
assert(requireFullyAssigned != .no)
335336
self.baseAddress = baseAddress
336337
self.requireFullyAssigned = requireFullyAssigned
338+
self.onRead = allowRead ? .continueWalk : .abortWalk
337339
self.context = context
338340
if let arg = baseAddress as? FunctionArgument {
339341
assert(!arg.convention.isIndirectIn, "@in arguments cannot be initialized")
@@ -391,15 +393,21 @@ extension AddressInitializationWalker {
391393
// FIXME: check mayWriteToMemory but ignore non-stores. Currently,
392394
// stores should all be checked my isAddressInitialization, but
393395
// this is not robust.
394-
return .continueWalk
396+
return onRead
395397
}
396398

397399
mutating func appliedAddressUse(of operand: Operand, by apply: FullApplySite)
398400
-> WalkResult {
399401
switch apply.fullyAssigns(operand: operand) {
400402
case .no:
403+
if onRead == .abortWalk {
404+
return .abortWalk
405+
}
401406
break
402407
case .lifetime:
408+
if onRead == .abortWalk {
409+
return .abortWalk
410+
}
403411
if requireFullyAssigned == .value {
404412
break
405413
}
@@ -415,26 +423,26 @@ extension AddressInitializationWalker {
415423

416424
mutating func loadedAddressUse(of operand: Operand, intoValue value: Value)
417425
-> WalkResult {
418-
return .continueWalk
426+
return onRead
419427
}
420428

421429
mutating func loadedAddressUse(of operand: Operand, intoAddress address: Operand)
422430
-> WalkResult {
423-
return .continueWalk
431+
return onRead
424432
}
425433

426434
mutating func yieldedAddressUse(of operand: Operand) -> WalkResult {
427435
// An inout yield is a partial write. Initialization via coroutine is not supported, so we assume a prior
428436
// initialization must dominate the yield.
429-
return .continueWalk
437+
return onRead
430438
}
431439

432440
mutating func dependentAddressUse(of operand: Operand, dependentValue value: Value) -> WalkResult {
433-
return .continueWalk
441+
return onRead
434442
}
435443

436444
mutating func dependentAddressUse(of operand: Operand, dependentAddress address: Value) -> WalkResult {
437-
return .continueWalk
445+
return onRead
438446
}
439447

440448
mutating func escapingAddressUse(of operand: Operand) -> WalkResult {

0 commit comments

Comments
 (0)