@@ -526,6 +526,82 @@ producers. For example:
526
526
Trivial values are never consumed and therefore don't have any restrictions on
527
527
where they are used on any control flow paths.
528
528
529
+ ### Borrow Scopes
530
+
531
+ A borrow scope is a liverange of a guaranteed value which keeps its
532
+ [ enclosing value] ( #Borrow-Introducers-and-Enclosing-Values ) (s) alive.
533
+ It prevents optimizations from destroying an enclosing value before the borrow
534
+ scope has ended.
535
+ The most common borrow scope is a ` begin_borrow ` -` end_borrow ` pair. But there
536
+ are other instructions which introduce borrow scopes:
537
+
538
+ #### ` begin_borrow `
539
+
540
+ A [ ` begin_borrow ` ] ( Instructions.md#begin_borrow ) defines a borrow scope for its
541
+ operand. The borrow scope ends at an ` end_borrow ` .
542
+
543
+ ```
544
+ %2 = begin_borrow %1 -+ borrow scope for %1
545
+ // ... |
546
+ end_borrow %2 -+ %1 must be alive until here
547
+ ```
548
+
549
+ Such a borrow scope can also "go through" a phi-argument. In this case the
550
+ overall borrow scope is the combination of multiple borrow lifetimes which are
551
+ "connected" by reborrow phi-arguments (see [ Phi arguments] ( #phi-arguments ) ).
552
+
553
+ #### ` load_borrow `
554
+
555
+ A [ ` load_borrow ` ] ( Instructions.md#load_borrow ) is similar to ` begin_borrow ` ,
556
+ except that its enclosing value is not an SSA value but a memory location.
557
+ During the scope of a ` load_borrow ` -` end_borrow ` the memory location must not be mutated.
558
+
559
+ ```
560
+ %2 = load_borrow %addr -+ borrow scope for memory value at %addr
561
+ // ... |
562
+ end_borrow %2 -+ memory at %addr must not be mutated until here
563
+ ```
564
+
565
+ #### ` store_borrow `
566
+
567
+ A [ ` store_borrow ` ] ( Instructions.md#store_borrow ) is similar to ` begin_borrow ` ,
568
+ except that beside defining a borrow scope it also stores the borrowed value
569
+ to a stack location. During the borrow scope (which ends at an ` end_borrow ` ), the
570
+ borrowed value lives at the stack location.
571
+
572
+ ```
573
+ %s = alloc_stack $T
574
+ %2 = store_borrow %1 to %s -+ borrow scope for %1
575
+ // ... |
576
+ end_borrow %2 -+ %1 must be alive until here
577
+ dealloc_stack %s
578
+ ```
579
+
580
+ #### ` partial_apply `
581
+
582
+ A [ ` partial_apply [on_stack] ` ] ( Instructions.md#partial_apply ) defines borrow
583
+ scopes for its non-trivial arguments. The scope begins at the ` partial_apply `
584
+ and ends at the end of the forward-extended lifetime of the ` partial_apply ` 's
585
+ result - the non-escaping closure.
586
+
587
+ ```
588
+ %3 = partial_apply [on_stack] %f(%1, %2) -+ borrow scope for %1 and %2
589
+ %4 = convert_function %3 to $SomeFuncType |
590
+ destroy_value %4 -+ %1 and %2 must be alive until here
591
+ ```
592
+
593
+ #### ` mark_dependence `
594
+
595
+ A [ ` mark_dependence [nonescaping] ` ] ( Instructions.md#mark_dependence ) defines a
596
+ borrow scope for its base operand. The scope begins at the ` mark_dependence `
597
+ and ends at the forward-extended lifetime of the ` mark_dependence ` 's result.
598
+
599
+ ```
600
+ %3 = mark_dependence %2 on %1 -+ borrow scope for %1
601
+ %4 = upcast %3 to $C |
602
+ destroy_value %4 -+ %1 must be alive until here
603
+ ```
604
+
529
605
### Borrow Introducers and Enclosing Values
530
606
531
607
Every guaranteed value has a set of borrow-introducers (usually one), each of
0 commit comments