Skip to content

Commit aed60d6

Browse files
authored
Merge pull request #78403 from eeckstein/borrow-scope-doc
docs: add a section about borrow scopes in SIL.md
2 parents 4c4a57d + 1753c81 commit aed60d6

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

docs/SIL/SIL.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,82 @@ producers. For example:
526526
Trivial values are never consumed and therefore don't have any restrictions on
527527
where 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

531607
Every guaranteed value has a set of borrow-introducers (usually one), each of

0 commit comments

Comments
 (0)