Skip to content

Commit f91f4bb

Browse files
authored
Merge pull request swiftlang#35164 from gottesmm/pr-a5db5d0be1148c32aa477a5cd1d529d5682592e3
[sil.rst] Update Ownership SSA section given further feedback
2 parents 5714a59 + 414b82e commit f91f4bb

File tree

1 file changed

+44
-43
lines changed

1 file changed

+44
-43
lines changed

docs/SIL.rst

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,17 +1675,17 @@ Ownership SSA
16751675
A SILFunction marked with the ``[ossa]`` function attribute is considered to be
16761676
in Ownership SSA form. Ownership SSA is an augmented version of SSA that
16771677
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
16791679
that defines the ownership semantics that the value models. All SIL operands
16801680
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::
16891689

16901690
sil @stash_and_cast : $@convention(thin) (@owned Klass) -> @owned SuperKlass {
16911691
bb0(%kls1 : @owned $Klass): // Definition of %kls1
@@ -1710,7 +1710,7 @@ inline::
17101710

17111711
Notice how every value in the SIL above has a partionable set of uses with
17121712
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
17141714
do not have any leaks or use-after-frees in the above code.
17151715

17161716
Ownership Kind
@@ -1719,13 +1719,13 @@ Ownership Kind
17191719
The semantics in the previous example is of just one form of ownership semantics
17201720
supported: "owned" semantics. In SIL, we map these "ownership semantics" into a
17211721
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
17231723
call this the lattice of "Ownership Kinds" and each individual value an
17241724
"Ownership Kind". This lattice is defined as a 3-level lattice with::
17251725

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
17291729

17301730
We can graphically represent the lattice via a diagram like the following::
17311731

@@ -1757,43 +1757,44 @@ and one moves up the lattice by performing a "join" operation, e.x.::
17571757

17581758
This lattice is applied to SIL by requiring well formed SIL to:
17591759

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::
17821783

17831784
join : (OwnershipConstraint, ValueOwnershipKind) -> ValueOwnershipKind
17841785
OwnershipConstraint(operand(i)) join ValueOwnershipKind(v) = ValueOwnershipKind(v)
17851786

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
17871788
ownership constraint to the value's ownership does not change the value's
17881789
ownership. Operationally this has a few interesting effects on SIL::
17891790

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

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

17981799
Now lets go into more depth upon `Value Ownership Kind`_ and `Ownership Constraint`_.
17991800

0 commit comments

Comments
 (0)