Skip to content

Commit b0f3338

Browse files
authored
Merge pull request #71826 from atrick/forwarding-utils
SwiftCompilerSources: support for ForwardingInstructions, ConversionInstructions, OwnershipTransitionInstruction
2 parents 98fc9fd + e3198ed commit b0f3338

File tree

13 files changed

+180
-109
lines changed

13 files changed

+180
-109
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LetPropertyLowering.swift

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,17 +156,17 @@ private func constructLetInitRegion(
156156
initRegion.insert(inst)
157157

158158
case let beginAccess as BeginAccessInst
159-
where beginAccess.accessKind == .Deinit &&
159+
where beginAccess.accessKind == .deinit &&
160160
beginAccess.address.isLetFieldAddress(of: markUninitialized):
161161
// Include let-field partial de-initializations in the region.
162162
initRegion.insert(inst)
163163

164164
case let beginBorrow as BeginBorrowInst
165-
where beginBorrow.borrowedValue.referenceRoot == markUninitialized:
165+
where beginBorrow.borrowedValue.isReferenceDerived(from: markUninitialized):
166166
borrows.append(beginBorrow)
167167

168168
case let storeBorrow as StoreBorrowInst
169-
where storeBorrow.source.referenceRoot == markUninitialized:
169+
where storeBorrow.source.isReferenceDerived(from: markUninitialized):
170170
borrows.append(storeBorrow)
171171

172172
default:
@@ -202,10 +202,28 @@ private extension RefElementAddrInst {
202202
}
203203

204204
private extension Value {
205+
func isReferenceDerived(from root: Value) -> Bool {
206+
var parent: Value = self
207+
while true {
208+
if parent == root {
209+
return true
210+
}
211+
if let operand = parent.forwardingInstruction?.singleForwardedOperand {
212+
parent = operand.value
213+
continue
214+
}
215+
if let transition = parent.definingInstruction as? OwnershipTransitionInstruction {
216+
parent = transition.operand.value
217+
continue
218+
}
219+
return false
220+
}
221+
}
222+
205223
func isLetFieldAddress(of markUninitialized: MarkUninitializedInst) -> Bool {
206224
if case .class(let rea) = self.accessBase,
207225
rea.fieldIsLet,
208-
rea.instance.referenceRoot == markUninitialized
226+
rea.instance.isReferenceDerived(from: markUninitialized)
209227
{
210228
return true
211229
}

SwiftCompilerSources/Sources/Optimizer/ModulePasses/StackProtection.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ private struct StackProtectionOptimization {
355355
/// Moves the value of a `beginAccess` to a temporary stack location, if possible.
356356
private func moveToTemporary(scope beginAccess: BeginAccessInst, mustFixStackNesting: inout Bool,
357357
_ context: FunctionPassContext) {
358-
if beginAccess.accessKind != .Modify {
358+
if beginAccess.accessKind != .modify {
359359
// We can only move from a `modify` access.
360360
// Also, read-only accesses shouldn't be subject to buffer overflows (because
361361
// no one should ever write to such a storage).

SwiftCompilerSources/Sources/Optimizer/Utilities/AddressUtils.swift

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,7 @@ extension AccessBase {
192192
/// with the initialized address. This does not guarantee that all
193193
/// uses of that address are dominated by the store or even that the
194194
/// store is a direct use of `address`.
195-
func findSingleInitializer(_ context: some Context)
196-
-> (initialAddress: Value, initializingStore: Instruction)? {
195+
func findSingleInitializer(_ context: some Context) -> (initialAddress: Value, initializingStore: Instruction)? {
197196
let baseAddr: Value
198197
switch self {
199198
case let .stack(allocStack):
@@ -206,15 +205,7 @@ extension AccessBase {
206205
default:
207206
return nil
208207
}
209-
var walker = AddressInitializationWalker(context: context)
210-
if walker.walkDownUses(ofAddress: baseAddr, path: SmallProjectionPath())
211-
== .abortWalk {
212-
return nil
213-
}
214-
guard let initializingStore = walker.initializingStore else {
215-
return nil
216-
}
217-
return (initialAddress: baseAddr, initializingStore: initializingStore)
208+
return AddressInitializationWalker.findSingleInitializer(ofAddress: baseAddr, context: context)
218209
}
219210
}
220211

@@ -223,6 +214,9 @@ extension AccessBase {
223214
// Implements AddressUseVisitor to guarantee that we can't miss any
224215
// stores. This separates escapingAddressUse from leafAddressUse.
225216
//
217+
// Main entry point:
218+
// static func findSingleInitializer(ofAddress: Value, context: some Context)
219+
//
226220
// TODO: Make AddressDefUseWalker always conform to AddressUseVisitor once we're
227221
// ready to debug changes to escape analysis etc...
228222
//
@@ -249,6 +243,19 @@ struct AddressInitializationWalker: AddressDefUseWalker, AddressUseVisitor {
249243
var isProjected = false
250244
var initializingStore: Instruction?
251245

246+
static func findSingleInitializer(ofAddress baseAddr: Value, context: some Context)
247+
-> (initialAddress: Value, initializingStore: Instruction)? {
248+
249+
var walker = AddressInitializationWalker(context: context)
250+
if walker.walkDownUses(ofAddress: baseAddr, path: SmallProjectionPath()) == .abortWalk {
251+
return nil
252+
}
253+
guard let initializingStore = walker.initializingStore else {
254+
return nil
255+
}
256+
return (initialAddress: baseAddr, initializingStore: initializingStore)
257+
}
258+
252259
private mutating func setInitializer(instruction: Instruction) -> WalkResult {
253260
// An initializer must be unique and store the full value.
254261
if initializingStore != nil || isProjected {

SwiftCompilerSources/Sources/Optimizer/Utilities/LifetimeDependenceUtils.swift

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -706,12 +706,8 @@ extension LifetimeDependenceUseDefWalker {
706706
mutating func walkUpDefault(dependent value: Value, owner: Value?)
707707
-> WalkResult {
708708
switch value.definingInstruction {
709-
case let copyInst as CopyValueInst:
710-
return walkUp(newLifetime: copyInst.fromValue)
711-
case let moveInst as MoveValueInst:
712-
return walkUp(value: moveInst.fromValue, owner)
713-
case let borrow as BeginBorrowInst:
714-
return walkUp(newLifetime: borrow.borrowedValue)
709+
case let transition as OwnershipTransitionInstruction:
710+
return walkUp(newLifetime: transition.operand.value)
715711
case let load as LoadInstruction:
716712
return walkUp(address: load.address)
717713
case let markDep as MarkDependenceInst:
@@ -862,11 +858,8 @@ extension LifetimeDependenceDefUseWalker {
862858
return leafUse(of: operand)
863859
}
864860
switch operand.instruction {
865-
case let copy as CopyingInstruction:
866-
return walkDownUses(of: copy, using: operand)
867-
868-
case let move as MoveValueInst:
869-
return walkDownUses(of: move, using: operand)
861+
case let transition as OwnershipTransitionInstruction:
862+
return walkDownUses(of: transition.ownershipResult, using: operand)
870863

871864
case let mdi as MarkDependenceInst where mdi.isUnresolved:
872865
// Override mark_dependence [unresolved] to handle them just

0 commit comments

Comments
 (0)