@@ -1675,17 +1675,17 @@ Ownership SSA
1675
1675
A SILFunction marked with the ``[ossa] `` function attribute is considered to be
1676
1676
in Ownership SSA form. Ownership SSA is an augmented version of SSA that
1677
1677
enforces ownership invariants by imbuing value-operand edges with semantic
1678
- ownership information. All SIL values are statically assigned an ownership kind
1678
+ ownership information. All SIL values are assigned a constant ownership kind
1679
1679
that defines the ownership semantics that the value models. All SIL operands
1680
1680
that use a SIL value are required to be able to be semantically partitioned in
1681
- between "normal uses" that just require the value to be live and "consuming
1682
- uses" that end the lifetime of the value and after which the value can no longer
1683
- be used. Since operands that are consuming uses end a value's lifetime,
1684
- naturally we must have that the consuming use points jointly post-dominate all
1685
- non-consuming use points and that a value must be consumed exactly once along
1686
- all reachable program paths, preventing leaks and use-after-frees. As an
1687
- example, consider the following SIL example with partitioned defs/uses annotated
1688
- inline::
1681
+ between "non-lifetime ending uses" that just require the value to be live and
1682
+ "lifetime ending uses" that end the lifetime of the value and after which the
1683
+ value can no longer be used. Since by definition operands that are lifetime
1684
+ ending uses end their associated value's lifetime, we must have that the
1685
+ lifetime ending use points jointly post-dominate all non-lifetime ending use
1686
+ points and that a value must have exactly one lifetime ending use along all
1687
+ reachable program paths, preventing leaks and use-after-frees. As an example,
1688
+ consider the following SIL example with partitioned defs/uses annotated inline::
1689
1689
1690
1690
sil @stash_and_cast : $@convention(thin) (@owned Klass) -> @owned SuperKlass {
1691
1691
bb0(%kls1 : @owned $Klass): // Definition of %kls1
@@ -1710,7 +1710,7 @@ inline::
1710
1710
1711
1711
Notice how every value in the SIL above has a partionable set of uses with
1712
1712
normal uses always before consuming uses. Any such violations of ownership
1713
- semantics would trigger a static SILVerifier error allowing us to know that we
1713
+ semantics would trigger a SILVerifier error allowing us to know that we
1714
1714
do not have any leaks or use-after-frees in the above code.
1715
1715
1716
1716
Ownership Kind
@@ -1719,13 +1719,13 @@ Ownership Kind
1719
1719
The semantics in the previous example is of just one form of ownership semantics
1720
1720
supported: "owned" semantics. In SIL, we map these "ownership semantics" into a
1721
1721
form that a compiler can reason about by mapping semantics onto a lattice with
1722
- the following elements: `None `_, `Owned `_, `Guaranteed `_, `Unowned `_, `Any `_ . We
1722
+ the following elements: `None `_, `Owned `_, `Guaranteed `_, `Unowned `_, `Any `. We
1723
1723
call this the lattice of "Ownership Kinds" and each individual value an
1724
1724
"Ownership Kind". This lattice is defined as a 3-level lattice with::
1725
1725
1726
- 1. None being Top.
1727
- 2. Any being Bottom.
1728
- 3. All non-Any, non-None OwnershipKinds being defined as a mid-level elements of the lattice
1726
+ 1. None being Top.
1727
+ 2. Any being Bottom.
1728
+ 3. All non-Any, non-None OwnershipKinds being defined as a mid-level elements of the lattice
1729
1729
1730
1730
We can graphically represent the lattice via a diagram like the following::
1731
1731
@@ -1757,43 +1757,44 @@ and one moves up the lattice by performing a "join" operation, e.x.::
1757
1757
1758
1758
This lattice is applied to SIL by requiring well formed SIL to:
1759
1759
1760
- 1. Define a static map of each SIL value to an OwnershipKind that classify the
1761
- semantics that the SIL value obeys. We call this subset of OwnershipKind to
1762
- be the set of `Value Ownership Kind `_: `None `_, `Unowned `_, `Guaranteed `_,
1763
- `Owned `_ (note conspiciously missing `Any `_). This is because in our model
1764
- `Any `_ represents an unknown ownership semantics and since our model is
1765
- statically strict, we do not allow for values to have unknown ownership.
1766
-
1767
- 2. Define a static map from each operand of a SILInstruction, `i `, to an
1768
- (Ownership Kind, Boolean) called the operand's `Ownership Constraint `_. The
1769
- Ownership Kind element of the `Ownership Constraint `_ acts as a a static
1770
- "constraint" on the Value Ownership Kind that the operand's value can be mapped
1771
- to. The second boolean value is used to know if an operand will end the
1772
- lifetime of the incoming value when checking dataflow rules. The dataflow
1773
- rules that each `Value Ownership Kind `_ obeys is documented for each
1774
- `Value Ownership Kind `_ in its detailed description below.
1775
-
1776
- Then we take these static definitions and require that valid SIL has the
1777
- property that given a value ``v ``, an instruction ``i `` and said instruction's
1778
- operand ``operand(i) ``, that ``v `` can be used as a value in ``operand(i) `` only
1779
- if the join of the ownership constraint of ``operand(i) `` with ``v `` is the
1780
- ownership kind of ``v ``! In symbols, we must have the following join is
1781
- defined::
1760
+ 1. Define a map of each SIL value to a constant OwnershipKind that classify the
1761
+ semantics that the SIL value obeys. This ownership kind may be static (i.e.:
1762
+ the same for all instances of an instruction) or dynamic (e.x.: forwarding
1763
+ instructions set their ownership upon construction). We call this subset of
1764
+ OwnershipKind to be the set of `Value Ownership Kind `_: `None `_, `Unowned `_,
1765
+ `Guaranteed `_, `Owned `_ (note conspiciously missing `Any `). This is because
1766
+ in our model `Any ` represents an unknown ownership semantics and since our
1767
+ model is strict, we do not allow for values to have unknown ownership.
1768
+
1769
+ 2. Define a map from each operand of a SILInstruction, `i `, to a constant
1770
+ Ownership Kind, Boolean pair called the operand's `Ownership
1771
+ Constraint `_. The Ownership Kind element of the `Ownership Constraint `_
1772
+ determines semantically which ownership kind's the operand's value can take
1773
+ on. The Boolean value is used to know if an operand will end the lifetime of
1774
+ the incoming value when checking dataflow rules. The dataflow rules that each
1775
+ `Value Ownership Kind `_ obeys is documented for each `Value Ownership Kind `_
1776
+ in its detailed description below.
1777
+
1778
+ Then we take these two maps and require that valid SIL has the property that
1779
+ given an operand, ``op(i) `` of an instruction ``i `` and a value ``v `` that
1780
+ ``op(i) `` can only use ``v `` if the ``join `` of
1781
+ ``OwnershipConstraint(operand(i)) `` with ``ValueOwnershipKind(v) `` is equal to
1782
+ the ``ValueOwnershipKind `` of ``v ``. In symbols, we must have that::
1782
1783
1783
1784
join : (OwnershipConstraint, ValueOwnershipKind) -> ValueOwnershipKind
1784
1785
OwnershipConstraint(operand(i)) join ValueOwnershipKind(v) = ValueOwnershipKind(v)
1785
1786
1786
- In prose , a value can be passed to an operand if applying the operand's
1787
+ In words , a value can be passed to an operand if applying the operand's
1787
1788
ownership constraint to the value's ownership does not change the value's
1788
1789
ownership. Operationally this has a few interesting effects on SIL::
1789
1790
1790
- 1. We have defined away invalid value-operand (aka def-use) pairing since the
1791
- SILVerifier validates the aforementioned relationship on all SIL values,
1792
- uses at all points of the pipeline until ossa is lowered.
1791
+ 1. We have defined away invalid value-operand (aka def-use) pairing since the
1792
+ SILVerifier validates the aforementioned relationship on all SIL values,
1793
+ uses at all points of the pipeline until ossa is lowered.
1793
1794
1794
- 2. Many SIL instructions do not care about the ownership kind that their value
1795
- will take. They can just define all of their operand's as having an
1796
- ownership constraint of Any.
1795
+ 2. Many SIL instructions do not care about the ownership kind that their value
1796
+ will take. They can just define all of their operand's as having an
1797
+ ownership constraint of Any.
1797
1798
1798
1799
Now lets go into more depth upon `Value Ownership Kind `_ and `Ownership Constraint `_.
1799
1800
0 commit comments