@@ -526,6 +526,82 @@ producers. For example:
526526Trivial values are never consumed and therefore don't have any restrictions on
527527where they are used on any control flow paths.
528528
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+
529605### Borrow Introducers and Enclosing Values
530606
531607Every guaranteed value has a set of borrow-introducers (usually one), each of
0 commit comments