@@ -1713,9 +1713,97 @@ normal uses always before consuming uses. Any such violations of ownership
1713
1713
semantics would trigger a static 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
+ Ownership Kind
1717
+ ~~~~~~~~~~~~~~
1718
+
1716
1719
The semantics in the previous example is of just one form of ownership semantics
1717
- supported: "owned" semantics. In SIL, we allow for values to have one of four
1718
- different ownership kinds:
1720
+ supported: "owned" semantics. In SIL, we map these "ownership semantics" into a
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
1723
+ call this the lattice of "Ownership Kinds" and each individual value an
1724
+ "Ownership Kind". This lattice is defined as a 3-level lattice with::
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
1729
+
1730
+ We can graphically represent the lattice via a diagram like the following::
1731
+
1732
+ +----+
1733
+ +-------- |None| -----------+
1734
+ | +----+ |
1735
+ | | |
1736
+ v v v ^
1737
+ +-------+ +-----+------+ +---------+ |
1738
+ | Owned | | Guaranteed | | Unowned | +--- Value Ownership Kinds and
1739
+ +-------+ +-----+------+ +---------+ Ownership Constraints
1740
+ | | |
1741
+ | v | +--- Only Ownership Constraints
1742
+ | +---+ | |
1743
+ +--------->|Any|<-----------+ v
1744
+ +---+
1745
+
1746
+ One moves down the lattice by performing a "meet" operation::
1747
+
1748
+ None meet OtherOwnershipKind -> OtherOwnershipKind
1749
+ Unowned meet Owned -> Any
1750
+ Owned meet Guaranteed -> Any
1751
+
1752
+ and one moves up the lattice by performing a "join" operation, e.x.::
1753
+
1754
+ Any join OtherOwnershipKind -> OtherOwnershipKind
1755
+ Owned join Any -> Owned
1756
+ Owned join Guaranteed -> None
1757
+
1758
+ This lattice is applied to SIL by requiring well formed SIL to:
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::
1782
+
1783
+ join : (OwnershipConstraint, ValueOwnershipKind) -> ValueOwnershipKind
1784
+ OwnershipConstraint(operand(i)) join ValueOwnershipKind(v) = ValueOwnershipKind(v)
1785
+
1786
+ In prose, a value can be passed to an operand if applying the operand's
1787
+ ownership constraint to the value's ownership does not change the value's
1788
+ ownership. Operationally this has a few interesting effects on SIL::
1789
+
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.
1793
+
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.
1797
+
1798
+ Now lets go into more depth upon `Value Ownership Kind `_ and `Ownership Constraint `_.
1799
+
1800
+ Value Ownership Kind
1801
+ ~~~~~~~~~~~~~~~~~~~~
1802
+
1803
+ As mentioned above, each SIL value is statically mapped to an `Ownership Kind `_
1804
+ called the value's "ValueOwnershipKind" that classify the semantics of the
1805
+ value. Below, we map each ValueOwnershipKind to a short summary of the semantics
1806
+ implied upon the parent value:
1719
1807
1720
1808
* **None **. This is used to represent values that do not require memory
1721
1809
management and are outside of Ownership SSA invariants. Examples: trivial
@@ -1739,10 +1827,7 @@ different ownership kinds:
1739
1827
bitcasting a trivial type to a non-trivial type. This value should never be
1740
1828
consumed.
1741
1829
1742
- We describe each of these semantics in more detail below.
1743
-
1744
- Value Ownership Kind
1745
- ~~~~~~~~~~~~~~~~~~~~
1830
+ We describe each of these semantics in below in more detail.
1746
1831
1747
1832
Owned
1748
1833
`````
@@ -1912,10 +1997,26 @@ This is a form of ownership that is used to model two different use cases:
1912
1997
trivial pointer to a class. In that case, since we have no reason to assume
1913
1998
that the object will remain alive, we need to make a copy of the value.
1914
1999
2000
+ Ownership Constraint
2001
+ ~~~~~~~~~~~~~~~~~~~~
2002
+
2003
+ NOTE: We assume that one has read the section above on `Ownership Kind `_.
2004
+
2005
+ As mentioned above, every operand ``operand(i) `` of a SIL instruction ``i `` has
2006
+ statically mapped to it:
2007
+
2008
+ 1. An ownership kind that acts as an "Ownership Constraint" upon what "Ownership
2009
+ Kind" a value can take.
2010
+
2011
+ 2. A boolean value that defines whether or not the execution of the operand's
2012
+ instruction will cause the operand's value to be invalidated. This is often
2013
+ times referred to as an operand acting as a "lifetime ending use".
2014
+
1915
2015
Forwarding Uses
1916
2016
~~~~~~~~~~~~~~~
1917
2017
1918
- NOTE: In the following, we assumed that one read the section above, `Value Ownership Kind `_.
2018
+ NOTE: In the following, we assumed that one read the section above, `Ownership
2019
+ Kind `_, `Value Ownership Kind `_ and `Ownership Constraint `_.
1919
2020
1920
2021
A subset of SIL instructions define the value ownership kind of their results in
1921
2022
terms of the value ownership kind of their operands. Such an instruction is
0 commit comments