130
130
// patterns).
131
131
// ===----------------------------------------------------------------------===//
132
132
133
- import SIL
134
-
135
133
/// A scoped instruction that borrows one or more operands.
136
134
///
137
135
/// If this instruction produces a borrowed value, then BeginBorrowValue(resultOf: self) != nil.
@@ -151,7 +149,7 @@ import SIL
151
149
/// operand.
152
150
///
153
151
/// TODO: replace BorrowIntroducingInstruction with this.
154
- enum BorrowingInstruction : CustomStringConvertible , Hashable {
152
+ public enum BorrowingInstruction : CustomStringConvertible , Hashable {
155
153
case beginBorrow( BeginBorrowInst )
156
154
case borrowedFrom( BorrowedFromInst )
157
155
case storeBorrow( StoreBorrowInst )
@@ -160,7 +158,7 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
160
158
case markDependence( MarkDependenceInst )
161
159
case startAsyncLet( BuiltinInst )
162
160
163
- init ? ( _ inst: Instruction ) {
161
+ public init ? ( _ inst: Instruction ) {
164
162
switch inst {
165
163
case let bbi as BeginBorrowInst :
166
164
self = . beginBorrow( bbi)
@@ -185,7 +183,7 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
185
183
}
186
184
}
187
185
188
- var instruction : Instruction {
186
+ public var instruction : Instruction {
189
187
switch self {
190
188
case . beginBorrow( let bbi) :
191
189
return bbi
@@ -204,7 +202,7 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
204
202
}
205
203
}
206
204
207
- var innerValue : Value ? {
205
+ public var innerValue : Value ? {
208
206
if let dependent = dependentValue {
209
207
return dependent
210
208
}
@@ -214,7 +212,7 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
214
212
/// Returns non-nil if this borrowing instruction produces an guaranteed dependent value and does not have immediate
215
213
/// scope-ending uses. Finding the borrow scope in such cases requires recursively following uses of the guaranteed
216
214
/// value.
217
- var dependentValue : Value ? {
215
+ public var dependentValue : Value ? {
218
216
switch self {
219
217
case . borrowedFrom( let bfi) :
220
218
let phi = bfi. borrowedPhi
@@ -233,7 +231,7 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
233
231
}
234
232
235
233
/// If this is valid, then visitScopeEndingOperands succeeds.
236
- var scopedValue : Value ? {
234
+ public var scopedValue : Value ? {
237
235
switch self {
238
236
case . beginBorrow, . storeBorrow:
239
237
return instruction as! SingleValueInstruction
@@ -271,7 +269,7 @@ enum BorrowingInstruction : CustomStringConvertible, Hashable {
271
269
///
272
270
/// TODO: For instructions that are not a BeginBorrowValue, verify that scope ending instructions exist on all
273
271
/// 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 {
275
273
guard let val = scopedValue else {
276
274
return . abortWalk
277
275
}
@@ -326,7 +324,7 @@ extension BorrowingInstruction {
326
324
}
327
325
}
328
326
329
- var description : String { instruction. description }
327
+ public var description : String { instruction. description }
330
328
}
331
329
332
330
/// A value that introduces a borrow scope:
@@ -340,15 +338,15 @@ extension BorrowingInstruction {
340
338
/// one of the yielded values. In any case, the scope ending operands
341
339
/// are on the end_apply or abort_apply instructions that use the
342
340
/// token.
343
- enum BeginBorrowValue {
341
+ public enum BeginBorrowValue {
344
342
case beginBorrow( BeginBorrowInst )
345
343
case loadBorrow( LoadBorrowInst )
346
344
case beginApply( Value )
347
345
case uncheckOwnershipConversion( UncheckedOwnershipConversionInst )
348
346
case functionArgument( FunctionArgument )
349
347
case reborrow( Phi )
350
348
351
- init ? ( _ value: Value ) {
349
+ public init ? ( _ value: Value ) {
352
350
switch value {
353
351
case let bbi as BeginBorrowInst :
354
352
self = . beginBorrow( bbi)
@@ -369,7 +367,7 @@ enum BeginBorrowValue {
369
367
}
370
368
}
371
369
372
- var value : Value {
370
+ public var value : Value {
373
371
switch self {
374
372
case . beginBorrow( let bbi) : return bbi
375
373
case . loadBorrow( let lbi) : return lbi
@@ -380,7 +378,7 @@ enum BeginBorrowValue {
380
378
}
381
379
}
382
380
383
- init ? ( using operand: Operand ) {
381
+ public init ? ( using operand: Operand ) {
384
382
switch operand. instruction {
385
383
case is BeginBorrowInst , is LoadBorrowInst :
386
384
let inst = operand. instruction as! SingleValueInstruction
@@ -398,7 +396,7 @@ enum BeginBorrowValue {
398
396
}
399
397
}
400
398
401
- init ? ( resultOf borrowInstruction: BorrowingInstruction ) {
399
+ public init ? ( resultOf borrowInstruction: BorrowingInstruction ) {
402
400
switch borrowInstruction {
403
401
case let . beginBorrow( beginBorrow) :
404
402
self . init ( beginBorrow)
@@ -412,7 +410,7 @@ enum BeginBorrowValue {
412
410
}
413
411
}
414
412
415
- var hasLocalScope : Bool {
413
+ public var hasLocalScope : Bool {
416
414
switch self {
417
415
case . beginBorrow, . loadBorrow, . beginApply, . reborrow, . uncheckOwnershipConversion:
418
416
return true
@@ -425,7 +423,7 @@ enum BeginBorrowValue {
425
423
// load_borrow.
426
424
//
427
425
// Return nil for begin_apply and reborrow, which need special handling.
428
- var baseOperand : Operand ? {
426
+ public var baseOperand : Operand ? {
429
427
switch self {
430
428
case let . beginBorrow( beginBorrow) :
431
429
return beginBorrow. operand
@@ -438,7 +436,7 @@ enum BeginBorrowValue {
438
436
439
437
/// The EndBorrows, reborrows (phis), and consumes (of closures)
440
438
/// that end the local borrow scope. Empty if hasLocalScope is false.
441
- var scopeEndingOperands : LazyFilterSequence < UseList > {
439
+ public var scopeEndingOperands : LazyFilterSequence < UseList > {
442
440
switch self {
443
441
case let . beginApply( value) :
444
442
return ( value. definingInstruction
@@ -451,57 +449,37 @@ enum BeginBorrowValue {
451
449
}
452
450
}
453
451
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
-
474
452
extension Value {
475
- var lookThroughBorrowedFrom : Value {
453
+ public var lookThroughBorrowedFrom : Value {
476
454
if let bfi = self as? BorrowedFromInst {
477
455
return bfi. borrowedValue. lookThroughBorrowedFrom
478
456
}
479
457
return self
480
458
}
481
459
}
482
460
483
- struct BorrowIntroducers < Ctxt: Context > : CollectionLikeSequence {
461
+ public struct BorrowIntroducers < Ctxt: Context > : CollectionLikeSequence {
484
462
let initialValue : Value
485
463
let context : Ctxt
486
464
487
- func makeIterator( ) -> EnclosingValueIterator {
465
+ public func makeIterator( ) -> EnclosingValueIterator {
488
466
EnclosingValueIterator ( forBorrowIntroducers: initialValue, context)
489
467
}
490
468
}
491
469
492
- struct EnclosingValues < Ctxt: Context > : CollectionLikeSequence {
470
+ public struct EnclosingValues < Ctxt: Context > : CollectionLikeSequence {
493
471
let initialValue : Value
494
472
let context : Ctxt
495
473
496
- func makeIterator( ) -> EnclosingValueIterator {
474
+ public func makeIterator( ) -> EnclosingValueIterator {
497
475
EnclosingValueIterator ( forEnclosingValues: initialValue, context)
498
476
}
499
477
}
500
478
501
479
// This iterator must be a class because we need a deinit.
502
480
// It shouldn't be a performance problem because the optimizer should always be able to stack promote the iterator.
503
481
// TODO: Make it a struct once this is possible with non-copyable types.
504
- final class EnclosingValueIterator : IteratorProtocol {
482
+ public final class EnclosingValueIterator : IteratorProtocol {
505
483
var worklist : ValueWorklist
506
484
507
485
init ( forBorrowIntroducers value: Value , _ context: some Context ) {
@@ -535,7 +513,7 @@ final class EnclosingValueIterator : IteratorProtocol {
535
513
worklist. deinitialize ( )
536
514
}
537
515
538
- func next( ) -> Value ? {
516
+ public func next( ) -> Value ? {
539
517
while let value = worklist. pop ( ) {
540
518
switch value. ownership {
541
519
case . none, . unowned:
@@ -584,7 +562,9 @@ extension Value {
584
562
/// %field = ref_element_addr %first // (none)
585
563
/// %load = load_borrow %field : $*C // %load
586
564
///
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 > {
588
568
BorrowIntroducers ( initialValue: self , context: context) . lazy. map { BeginBorrowValue ( $0) ! }
589
569
}
590
570
@@ -625,15 +605,24 @@ extension Value {
625
605
/// bb1(%outerReborrow : @reborrow, // %0
626
606
/// %innerReborrow : @reborrow) // %outerReborrow
627
607
///
628
- func getEnclosingValues< Ctxt: Context > ( _ context: Ctxt ) -> EnclosingValues < Ctxt > {
608
+ public func getEnclosingValues< Ctxt: Context > ( _ context: Ctxt ) -> EnclosingValues < Ctxt > {
629
609
EnclosingValues ( initialValue: self , context: context)
630
610
}
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
+ }
631
620
}
632
621
633
622
extension Phi {
634
623
/// The inner adjacent phis of this outer "enclosing" phi.
635
624
/// 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 > {
637
626
value. uses. lazy. compactMap { use in
638
627
if let bfi = use. instruction as? BorrowedFromInst ,
639
628
use. index != 0
@@ -647,7 +636,7 @@ extension Phi {
647
636
648
637
/// Gathers enclosing values by visiting predecessor blocks.
649
638
/// Only used for updating borrowed-from instructions and for verification.
650
- func gatherEnclosingValuesFromPredecessors(
639
+ public func gatherEnclosingValuesFromPredecessors(
651
640
for phi: Phi ,
652
641
in enclosingValues: inout Stack < Value > ,
653
642
_ context: some Context
@@ -669,7 +658,7 @@ func gatherEnclosingValuesFromPredecessors(
669
658
670
659
extension BasicBlock {
671
660
// 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 {
673
662
let branch = terminator as! BranchInst
674
663
if let incomingEV = branch. operands. first ( where: { branchOp in
675
664
// 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 {
697
686
}
698
687
}
699
688
700
- let borrowIntroducersTest = FunctionTest ( " borrow_introducers " ) {
689
+ let borrowIntroducersTest = Test ( " borrow_introducers " ) {
701
690
function, arguments, context in
702
691
let value = arguments. takeValue ( )
703
692
print ( function)
@@ -707,7 +696,7 @@ let borrowIntroducersTest = FunctionTest("borrow_introducers") {
707
696
}
708
697
}
709
698
710
- let enclosingValuesTest = FunctionTest ( " enclosing_values " ) {
699
+ let enclosingValuesTest = Test ( " enclosing_values " ) {
711
700
function, arguments, context in
712
701
let value = arguments. takeValue ( )
713
702
print ( function)
@@ -721,14 +710,3 @@ let enclosingValuesTest = FunctionTest("enclosing_values") {
721
710
}
722
711
}
723
712
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
-
0 commit comments