NOTE: I am just adding coverage that we support these instructions. One can only
use this with Error today and Error is always Sendable. So this is just going
for completeness.
Semantically a mark_dependence returns a value that is equal to its first
parameter with the extra semantics that any destroys of the 2nd operand cannot
occur before any uses of the result of the instruction. From a region
perspective this suggests that the instruction should be an assign from the
first operand onto the result and act as a require on the result. Semantically
the requirement that the 2nd operand cannot be destroyed before any uses of the
result does not expose any memory or state from the first operand implying that
we don't need to merge it into the result region. The restriction is purely to
tell the optimizer what it can/cannot do rather.
We already only supported Ownership SSA since we run early in the pipeline
before OSSA is lowered. This just formalizes this behavior. I am marking these
instructions as Asserting (even though we will never see them) so I can
semantically be sure that all of the instructions are covered without using an
"unsupported" like moniker that I fear will lead to new instructions being added
as unsupported. Better to have a semantic thing for new instruction adders to
use.
This involved fixing a few different bugs.
1. We were just performing dataflow by setting that only the initial block needs
to be updated. This means that if there isn’t anything in the initial dataflow
block, we won’t visit any successor blocks. Instead the correct thing to do here
is to visit all blocks in the initial round.
2. I also needed to fix a separate issue where we were updating our union-find
data structure incorrectly as found by an assert on transfernonsendable.swift
that was triggered once I fixed 1. Put simply, we needed to set a new max label
+ 1 when our new max element is less than or equal to the old max label + 1…
before we just did less than so if we had a new max element that is the same as
our fresh label, we wouldn’t increment the fresh label.
rdar://119584497
Mark the result of a move-only addressor as unresolved. The pointed-at value
cannot be consumed so ensure that only [read] or [modify] accesses are
performed. Update the move-only checker to recognize code patterns
from addressors.
More specifically this patch does the following:
* Rather than having a large switch with misc code, I changed the partition op
translator to use a visitor that defines a declaration for all SILInstructions
and in translateSILInstruction visits all such instructions. This ensures via
the linker that when ever a new SILInstruction is added, a link error occurs.
* Rather than just have misc translation code from the switch in the visitor, I
created a new enum called TranslationSemantics that describes the semantics for
instructions and made it so that the visitor methods return an instance of the
enum. This enum is then switched over to determine the action to perform. This
handles the vast majority of cases and allows for a reader of the translation
code to read a small amount of code (< 20-30 lines) to understand at a glance
the available semantics rather than having to read a huge switch. To make it
easy to implement the constant semantics that most instructions have, I followed
what we did in OperandOwnership (the model that I followed here) by using
preprocessor macros to define explicitly the semantics for each instruction. In
the case where special handling is needed, we can create a custom method, handle
the translation by hand, and then return TranslationSemantics::Special to signal
to the handling loop to just not do anything.
Now that SILGen almost always represents a lexical lifetime with
move_value [lexical]
the fact that the checker doesn't consider such lifetimes is exposed.
Fix it to look for such lifetimes.
KeyPathProjector creates alloc_stack and dealloc_stack for temporaries.
Insertion of new dealloc_stack can modify stack discipline.
Invalidate stack nesting so that it can be fixed up in the pass.
The SILCombine of ref_to_raw_pointer uses ossa rauw which creates a copy.
The copy created cannot be removed because it has an escaping ownership.
Disabling the silcombine for ossa here to avoid generating unoptimizable copies.
Following https://github.com/apple/swift/pull/70333, do the same thing for
modify coroutines, marking the result so that we check uses of the result to
ensure it isn't consumed (without being reinitialized).