Skip to content

Commit e54dd22

Browse files
authored
Merge pull request swiftlang#34884 from gottesmm/pr-442f09fe972ba38c706b52acd381ab5982bd6e07
[sil.rst] Update OSSA section for the introduction of an explicit "Ownership Kind Lattice".
2 parents cd2dec4 + c80856c commit e54dd22

File tree

1 file changed

+108
-7
lines changed

1 file changed

+108
-7
lines changed

docs/SIL.rst

Lines changed: 108 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,9 +1713,97 @@ normal uses always before consuming uses. Any such violations of ownership
17131713
semantics would trigger a static SILVerifier error allowing us to know that we
17141714
do not have any leaks or use-after-frees in the above code.
17151715

1716+
Ownership Kind
1717+
~~~~~~~~~~~~~~
1718+
17161719
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:
17191807

17201808
* **None**. This is used to represent values that do not require memory
17211809
management and are outside of Ownership SSA invariants. Examples: trivial
@@ -1739,10 +1827,7 @@ different ownership kinds:
17391827
bitcasting a trivial type to a non-trivial type. This value should never be
17401828
consumed.
17411829

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.
17461831

17471832
Owned
17481833
`````
@@ -1912,10 +1997,26 @@ This is a form of ownership that is used to model two different use cases:
19121997
trivial pointer to a class. In that case, since we have no reason to assume
19131998
that the object will remain alive, we need to make a copy of the value.
19141999

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+
19152015
Forwarding Uses
19162016
~~~~~~~~~~~~~~~
19172017

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`_.
19192020

19202021
A subset of SIL instructions define the value ownership kind of their results in
19212022
terms of the value ownership kind of their operands. Such an instruction is

0 commit comments

Comments
 (0)