Skip to content

Commit 1eb49ec

Browse files
committed
SwiftCompilerSources: move ForwardingUtils and BorrowUtils to the SIL module
1 parent a767261 commit 1eb49ec

File tree

7 files changed

+97
-101
lines changed

7 files changed

+97
-101
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88

99
swift_compiler_sources(Optimizer
1010
AddressUtils.swift
11-
BorrowUtils.swift
1211
SpecializationCloner.swift
1312
Devirtualization.swift
1413
EscapeUtils.swift
15-
ForwardingUtils.swift
1614
FunctionSignatureTransforms.swift
1715
FunctionTest.swift
1816
GenericSpecialization.swift

SwiftCompilerSources/Sources/Optimizer/Utilities/FunctionTest.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ public func registerOptimizerTests() {
4343
registerFunctionTests(
4444
addressOwnershipLiveRangeTest,
4545
argumentConventionsTest,
46-
borrowIntroducersTest,
47-
enclosingValuesTest,
48-
forwardingDefUseTest,
49-
forwardingUseDefTest,
5046
getPullbackClosureInfoTest,
5147
interiorLivenessTest,
5248
lifetimeDependenceRootTest,

SwiftCompilerSources/Sources/Optimizer/Utilities/OwnershipLiveness.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,26 @@ func computeKnownLiveness(for definingValue: Value, visitInnerUses: Bool = false
8484
visitInnerUses: visitInnerUses, context).acquireRange
8585
}
8686

87+
/// Compute the live range for the borrow scopes of a guaranteed value. This returns a separate instruction range for
88+
/// each of the value's borrow introducers.
89+
///
90+
/// TODO: This should return a single multiply-defined instruction range.
91+
func computeBorrowLiveRange(for value: Value, _ context: FunctionPassContext)
92+
-> SingleInlineArray<(BeginBorrowValue, InstructionRange)> {
93+
assert(value.ownership == .guaranteed)
94+
95+
var ranges = SingleInlineArray<(BeginBorrowValue, InstructionRange)>()
96+
// If introducers is empty, then the dependence is on a trivial value, so
97+
// there is no ownership range.
98+
for beginBorrow in value.getBorrowIntroducers(context) {
99+
/// FIXME: Remove calls to computeKnownLiveness() as soon as lifetime completion runs immediately after
100+
/// SILGen. Instead, this should compute linear liveness for borrowed value by switching over BeginBorrowValue, just
101+
/// like LifetimeDependence.Scope.computeRange().
102+
ranges.push((beginBorrow, computeKnownLiveness(for: beginBorrow.value, context)))
103+
}
104+
return ranges
105+
}
106+
87107
/// If any interior pointer may escape, then record the first instance here. If 'ignoreEscape' is true, this
88108
/// immediately aborts the walk, so further instances are unavailable.
89109
///

SwiftCompilerSources/Sources/Optimizer/Utilities/BorrowUtils.swift renamed to SwiftCompilerSources/Sources/SIL/Utilities/BorrowUtils.swift

Lines changed: 41 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,6 @@
130130
// patterns).
131131
// ===----------------------------------------------------------------------===//
132132

133-
import SIL
134-
135133
/// A scoped instruction that borrows one or more operands.
136134
///
137135
/// If this instruction produces a borrowed value, then BeginBorrowValue(resultOf: self) != nil.
@@ -151,7 +149,7 @@ import SIL
151149
/// operand.
152150
///
153151
/// TODO: replace BorrowIntroducingInstruction with this.
154-
enum BorrowingInstruction : CustomStringConvertible, Hashable {
152+
public enum BorrowingInstruction : CustomStringConvertible, Hashable {
155153
case beginBorrow(BeginBorrowInst)
156154
case borrowedFrom(BorrowedFromInst)
157155
case storeBorrow(StoreBorrowInst)
@@ -160,7 +158,7 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
160158
case markDependence(MarkDependenceInst)
161159
case startAsyncLet(BuiltinInst)
162160

163-
init?(_ inst: Instruction) {
161+
public init?(_ inst: Instruction) {
164162
switch inst {
165163
case let bbi as BeginBorrowInst:
166164
self = .beginBorrow(bbi)
@@ -185,7 +183,7 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
185183
}
186184
}
187185

188-
var instruction: Instruction {
186+
public var instruction: Instruction {
189187
switch self {
190188
case .beginBorrow(let bbi):
191189
return bbi
@@ -204,7 +202,7 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
204202
}
205203
}
206204

207-
var innerValue: Value? {
205+
public var innerValue: Value? {
208206
if let dependent = dependentValue {
209207
return dependent
210208
}
@@ -214,7 +212,7 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
214212
/// Returns non-nil if this borrowing instruction produces an guaranteed dependent value and does not have immediate
215213
/// scope-ending uses. Finding the borrow scope in such cases requires recursively following uses of the guaranteed
216214
/// value.
217-
var dependentValue: Value? {
215+
public var dependentValue: Value? {
218216
switch self {
219217
case .borrowedFrom(let bfi):
220218
let phi = bfi.borrowedPhi
@@ -233,7 +231,7 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
233231
}
234232

235233
/// If this is valid, then visitScopeEndingOperands succeeds.
236-
var scopedValue: Value? {
234+
public var scopedValue: Value? {
237235
switch self {
238236
case .beginBorrow, .storeBorrow:
239237
return instruction as! SingleValueInstruction
@@ -271,7 +269,7 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
271269
///
272270
/// TODO: For instructions that are not a BeginBorrowValue, verify that scope ending instructions exist on all
273271
/// paths. These instructions should be complete after SILGen and never cloned to produce phis.
274-
func visitScopeEndingOperands(_ context: Context, visitor: @escaping (Operand) -> WalkResult) -> WalkResult {
272+
public func visitScopeEndingOperands(_ context: Context, visitor: @escaping (Operand) -> WalkResult) -> WalkResult {
275273
guard let val = scopedValue else {
276274
return .abortWalk
277275
}
@@ -326,7 +324,7 @@ extension BorrowingInstruction {
326324
}
327325
}
328326

329-
var description: String { instruction.description }
327+
public var description: String { instruction.description }
330328
}
331329

332330
/// A value that introduces a borrow scope:
@@ -340,15 +338,15 @@ extension BorrowingInstruction {
340338
/// one of the yielded values. In any case, the scope ending operands
341339
/// are on the end_apply or abort_apply instructions that use the
342340
/// token.
343-
enum BeginBorrowValue {
341+
public enum BeginBorrowValue {
344342
case beginBorrow(BeginBorrowInst)
345343
case loadBorrow(LoadBorrowInst)
346344
case beginApply(Value)
347345
case uncheckOwnershipConversion(UncheckedOwnershipConversionInst)
348346
case functionArgument(FunctionArgument)
349347
case reborrow(Phi)
350348

351-
init?(_ value: Value) {
349+
public init?(_ value: Value) {
352350
switch value {
353351
case let bbi as BeginBorrowInst:
354352
self = .beginBorrow(bbi)
@@ -369,7 +367,7 @@ enum BeginBorrowValue {
369367
}
370368
}
371369

372-
var value: Value {
370+
public var value: Value {
373371
switch self {
374372
case .beginBorrow(let bbi): return bbi
375373
case .loadBorrow(let lbi): return lbi
@@ -380,7 +378,7 @@ enum BeginBorrowValue {
380378
}
381379
}
382380

383-
init?(using operand: Operand) {
381+
public init?(using operand: Operand) {
384382
switch operand.instruction {
385383
case is BeginBorrowInst, is LoadBorrowInst:
386384
let inst = operand.instruction as! SingleValueInstruction
@@ -398,7 +396,7 @@ enum BeginBorrowValue {
398396
}
399397
}
400398

401-
init?(resultOf borrowInstruction: BorrowingInstruction) {
399+
public init?(resultOf borrowInstruction: BorrowingInstruction) {
402400
switch borrowInstruction {
403401
case let .beginBorrow(beginBorrow):
404402
self.init(beginBorrow)
@@ -412,7 +410,7 @@ enum BeginBorrowValue {
412410
}
413411
}
414412

415-
var hasLocalScope: Bool {
413+
public var hasLocalScope: Bool {
416414
switch self {
417415
case .beginBorrow, .loadBorrow, .beginApply, .reborrow, .uncheckOwnershipConversion:
418416
return true
@@ -425,7 +423,7 @@ enum BeginBorrowValue {
425423
// load_borrow.
426424
//
427425
// Return nil for begin_apply and reborrow, which need special handling.
428-
var baseOperand: Operand? {
426+
public var baseOperand: Operand? {
429427
switch self {
430428
case let .beginBorrow(beginBorrow):
431429
return beginBorrow.operand
@@ -438,7 +436,7 @@ enum BeginBorrowValue {
438436

439437
/// The EndBorrows, reborrows (phis), and consumes (of closures)
440438
/// that end the local borrow scope. Empty if hasLocalScope is false.
441-
var scopeEndingOperands: LazyFilterSequence<UseList> {
439+
public var scopeEndingOperands: LazyFilterSequence<UseList> {
442440
switch self {
443441
case let .beginApply(value):
444442
return (value.definingInstruction
@@ -451,57 +449,37 @@ enum BeginBorrowValue {
451449
}
452450
}
453451

454-
/// Compute the live range for the borrow scopes of a guaranteed value. This returns a separate instruction range for
455-
/// each of the value's borrow introducers.
456-
///
457-
/// TODO: This should return a single multiply-defined instruction range.
458-
func computeBorrowLiveRange(for value: Value, _ context: FunctionPassContext)
459-
-> SingleInlineArray<(BeginBorrowValue, InstructionRange)> {
460-
assert(value.ownership == .guaranteed)
461-
462-
var ranges = SingleInlineArray<(BeginBorrowValue, InstructionRange)>()
463-
// If introducers is empty, then the dependence is on a trivial value, so
464-
// there is no ownership range.
465-
for beginBorrow in value.getBorrowIntroducers(context) {
466-
/// FIXME: Remove calls to computeKnownLiveness() as soon as lifetime completion runs immediately after
467-
/// SILGen. Instead, this should compute linear liveness for borrowed value by switching over BeginBorrowValue, just
468-
/// like LifetimeDependence.Scope.computeRange().
469-
ranges.push((beginBorrow, computeKnownLiveness(for: beginBorrow.value, context)))
470-
}
471-
return ranges
472-
}
473-
474452
extension Value {
475-
var lookThroughBorrowedFrom: Value {
453+
public var lookThroughBorrowedFrom: Value {
476454
if let bfi = self as? BorrowedFromInst {
477455
return bfi.borrowedValue.lookThroughBorrowedFrom
478456
}
479457
return self
480458
}
481459
}
482460

483-
struct BorrowIntroducers<Ctxt: Context> : CollectionLikeSequence {
461+
public struct BorrowIntroducers<Ctxt: Context> : CollectionLikeSequence {
484462
let initialValue: Value
485463
let context: Ctxt
486464

487-
func makeIterator() -> EnclosingValueIterator {
465+
public func makeIterator() -> EnclosingValueIterator {
488466
EnclosingValueIterator(forBorrowIntroducers: initialValue, context)
489467
}
490468
}
491469

492-
struct EnclosingValues<Ctxt: Context> : CollectionLikeSequence {
470+
public struct EnclosingValues<Ctxt: Context> : CollectionLikeSequence {
493471
let initialValue: Value
494472
let context: Ctxt
495473

496-
func makeIterator() -> EnclosingValueIterator {
474+
public func makeIterator() -> EnclosingValueIterator {
497475
EnclosingValueIterator(forEnclosingValues: initialValue, context)
498476
}
499477
}
500478

501479
// This iterator must be a class because we need a deinit.
502480
// It shouldn't be a performance problem because the optimizer should always be able to stack promote the iterator.
503481
// TODO: Make it a struct once this is possible with non-copyable types.
504-
final class EnclosingValueIterator : IteratorProtocol {
482+
public final class EnclosingValueIterator : IteratorProtocol {
505483
var worklist: ValueWorklist
506484

507485
init(forBorrowIntroducers value: Value, _ context: some Context) {
@@ -535,7 +513,7 @@ final class EnclosingValueIterator : IteratorProtocol {
535513
worklist.deinitialize()
536514
}
537515

538-
func next() -> Value? {
516+
public func next() -> Value? {
539517
while let value = worklist.pop() {
540518
switch value.ownership {
541519
case .none, .unowned:
@@ -584,7 +562,9 @@ extension Value {
584562
/// %field = ref_element_addr %first // (none)
585563
/// %load = load_borrow %field : $*C // %load
586564
///
587-
func getBorrowIntroducers<Ctxt: Context>(_ context: Ctxt) -> LazyMapSequence<BorrowIntroducers<Ctxt>, BeginBorrowValue> {
565+
public func getBorrowIntroducers<Ctxt: Context>(
566+
_ context: Ctxt
567+
) -> LazyMapSequence<BorrowIntroducers<Ctxt>, BeginBorrowValue> {
588568
BorrowIntroducers(initialValue: self, context: context).lazy.map { BeginBorrowValue($0)! }
589569
}
590570

@@ -625,15 +605,24 @@ extension Value {
625605
/// bb1(%outerReborrow : @reborrow, // %0
626606
/// %innerReborrow : @reborrow) // %outerReborrow
627607
///
628-
func getEnclosingValues<Ctxt: Context>(_ context: Ctxt) -> EnclosingValues<Ctxt> {
608+
public func getEnclosingValues<Ctxt: Context>(_ context: Ctxt) -> EnclosingValues<Ctxt> {
629609
EnclosingValues(initialValue: self, context: context)
630610
}
611+
612+
public var lookThroughBorrowedFromUser: Value {
613+
for use in uses {
614+
if let bfi = use.forwardingBorrowedFromUser {
615+
return bfi
616+
}
617+
}
618+
return self
619+
}
631620
}
632621

633622
extension Phi {
634623
/// The inner adjacent phis of this outer "enclosing" phi.
635624
/// These keep the enclosing (outer adjacent) phi alive.
636-
var innerAdjacentPhis: LazyMapSequence<LazyFilterSequence<LazyMapSequence<UseList, Phi?>>, Phi> {
625+
public var innerAdjacentPhis: LazyMapSequence<LazyFilterSequence<LazyMapSequence<UseList, Phi?>>, Phi> {
637626
value.uses.lazy.compactMap { use in
638627
if let bfi = use.instruction as? BorrowedFromInst,
639628
use.index != 0
@@ -647,7 +636,7 @@ extension Phi {
647636

648637
/// Gathers enclosing values by visiting predecessor blocks.
649638
/// Only used for updating borrowed-from instructions and for verification.
650-
func gatherEnclosingValuesFromPredecessors(
639+
public func gatherEnclosingValuesFromPredecessors(
651640
for phi: Phi,
652641
in enclosingValues: inout Stack<Value>,
653642
_ context: some Context
@@ -669,7 +658,7 @@ func gatherEnclosingValuesFromPredecessors(
669658

670659
extension BasicBlock {
671660
// Returns either the `incomingEnclosingValue` or an adjacent phi in the successor block.
672-
func getEnclosingValueInSuccessor(ofIncoming incomingEnclosingValue: Value) -> Value {
661+
public func getEnclosingValueInSuccessor(ofIncoming incomingEnclosingValue: Value) -> Value {
673662
let branch = terminator as! BranchInst
674663
if let incomingEV = branch.operands.first(where: { branchOp in
675664
// Only if the lifetime of `branchOp` ends at the branch (either because it's a reborrow or an owned value),
@@ -697,7 +686,7 @@ extension BasicBlock {
697686
}
698687
}
699688

700-
let borrowIntroducersTest = FunctionTest("borrow_introducers") {
689+
let borrowIntroducersTest = Test("borrow_introducers") {
701690
function, arguments, context in
702691
let value = arguments.takeValue()
703692
print(function)
@@ -707,7 +696,7 @@ let borrowIntroducersTest = FunctionTest("borrow_introducers") {
707696
}
708697
}
709698

710-
let enclosingValuesTest = FunctionTest("enclosing_values") {
699+
let enclosingValuesTest = Test("enclosing_values") {
711700
function, arguments, context in
712701
let value = arguments.takeValue()
713702
print(function)
@@ -721,14 +710,3 @@ let enclosingValuesTest = FunctionTest("enclosing_values") {
721710
}
722711
}
723712

724-
extension Value {
725-
var lookThroughBorrowedFromUser: Value {
726-
for use in uses {
727-
if let bfi = use.forwardingBorrowedFromUser {
728-
return bfi
729-
}
730-
}
731-
return self
732-
}
733-
}
734-

SwiftCompilerSources/Sources/SIL/Utilities/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
swift_compiler_sources(SIL
1010
AccessUtils.swift
11+
BorrowUtils.swift
12+
ForwardingUtils.swift
1113
SequenceUtilities.swift
1214
SmallProjectionPath.swift
1315
SSAUpdater.swift

0 commit comments

Comments
 (0)