This is the lifetime ending variant of fix_lifetime. It is a lie to the
ownership verifier that a value is being consumed along a path. Its intention is
to be used to allow for the static verification of ownership in deallocating
deinits which for compatibility with objective-c have weird ownership behavior.
See the commit merged with this commit for more information.
This pass now canonicalizes results before lowering and handles all combinations
of direct and indirect multiple return values. The logic is much less ad-hoc and
more robust.
try_apply still isn't handled, but should be much easier now.
Add visitLoadInst, visitStoreInst, visitDebugValueInst, etc.
Once we move to a copy-on-write implementation of existential value buffers we
can no longer consume or destroy values of an opened existential unless the
buffer is uniquely owned.
Therefore we need to track the allowed operation on opened values.
Add qualifiers "mutable_access" and "immutable_access" to open_existential_addr
instructions to indicate the allowed access to the opened value.
Once we move to a copy-on-write implementation, an "open_existential_addr
mutable_access" instruction will ensure unique ownership of the value buffer.
SubstitutionList is going to be a more compact representation of
a SubstitutionMap, suitable for inline allocation inside another
object.
For now, it's just a typedef for ArrayRef<Substitution>.
[NFC] Add -enable-sil-opaque-values frontend option.
This will be used to change the SIL-level calling convention for opaque values,
such as generics and resilient structs, to pass-by-value. Under this flag,
opaque values have SSA lifetimes, managed by copy_value and destroy_value.
This will make it easier to optimize copies and verify ownership.
* [SILGen] type lowering support for opaque values.
Add OpaqueValueTypeLowering.
Under EnableSILOpaqueValues, lower address-only types as opaque values.
* [SIL] Fix ValueOwnershipKind to support opaque SIL values.
* Test case: SILGen opaque value support for Parameter/ResultConvention.
* [SILGen] opaque value support for function arguments.
* Future Test case: SILGen opaque value specialDest arguments.
* Future Test case: SILGen opaque values: emitOpenExistential.
* Test case: SIL parsing support for EnableSILOpaqueValues.
* SILGen opaque values: prepareArchetypeCallee.
* [SIL Verify] allow copy_value for EnableSILOpaqueValues.
* Test cast: SIL serializer support for opaque values.
* Add a static_assert for ParameterConvention layout.
* Test case: Mandatory SILOpt support for EnableSILOpaqueValues.
* Test case: SILOpt support for EnableSILOpaqueValues.
* SILGen opaque values: TypeLowering emitCopyValue.
* SILBuilder createLoad. Allow loading opaque values.
* SIL Verifier. Allow loading and storing opaque values.
* SILGen emitSemanticStore support for opaque values.
* Test case for SILGen emitSemanticStore.
* Test case for SIL mandatory support for inout assignment.
* Fix SILGen opaque values test case after rebasing.
Separate formal lowered types from SIL types.
The SIL type of an argument will depend on the SIL module's conventions.
The module conventions are determined by the SIL stage and LangOpts.
Almost NFC, but specialized manglings are broken incidentally as a result of
fixes to the way passes handle book-keeping of aruments. The mangler is fixed in
the subsequent commit.
Otherwise, NFC is intended, but quite possible do to rewriting the logic in many
places.
The reason why I am introducing special instructions is so I can maintain the
qualified ownership API wedge in between qualified SIL and the rest of the ARC
instructions that are pervasively used in the compiler.
These instructions in the future /could/ be extended to just take @sil_unmanaged
operands directly, but I want to maintain flexibility to take regular
non-trivial operands in the short term.
rdar://29791263
This is the first verifier for SemanticSIL. The verifier is very simple and
verifies that given a SILValue V, V->getOwnershipKind() returns an ownership
kind compatible with all of V's user instructions.
This is implemented by adding a new method to SILInstruction:
SILInstruction::verifyOperandOwnership()
This method creates an instance of the visitor OwnershipCompatibilityUseChecker
and then has the instance visit this.
The OwnershipCompatibilityUseChecker is a SILInstructionVisitor that for a given
instruction verifies that the given SILInstruction's operand SILValue's produce
ValueOwnershipKind that are compatible with the SILInstruction. The reason why
it is implemented as a visitor is to ensure that a warning is produced if a new
instruction is added and a method on the OwnershipCompatibleUseChecker isn't
added.
Keep in mind that this is just the first verifier and the full verifier (that
also verifies dataflow) is built on top of it. The reason why this separate API
to the use verifier is exposed is that exposing the checker enables us to place
an assert in SILBuilder to diagnose any places where SIL ownership is violated
immediately when the violation occurs allowing for an easy debugging experience
for compiler writers. This assert is a key tool that I am going to be using to
make SILGen conform to the SIL Ownership Model.
Again, this will be behind the -enable-semantic-sil flag, so normal development
will be unaffected by this change.
rdar://29671437
This was in the first high level ARC instruction proposal, but I have not needed
it until now. The use case for this is to ahandle strong_retain_unowned (which
takes in an unowned value, asserts it is still alive, performs a strong_retain,
and returns the @owned value). This @owned value needs a destroy_value.
rdar://29671437
Applying nontrivial generic arguments to a nontrivial SIL layout requires lowered SILType substitution, which requires a SILModule. NFC yet, just an API change.
This was made redundant by typed boxes, and the type operand was already removed from textual SIL, but the field was never removed from the instruction's in memory representation. It becomes wrong in the face of compound boxes with layout.
Today, loads and stores are treated as having @unowned(unsafe) ownership
semantics. This leaves the user to specify ownership changes on the loaded or
stored value independently of the load/store by inserting ARC operations. With
the change to Semantic SIL, this will no longer be true. Instead loads, stores
have ownership semantics that one must reason about such as copy, take, and
trivial.
This change moves us closer to that world by eliminating the default
OwnershipQualification argument from create{Load,Store}. This means that the
compiler developer cannot ignore reasoning about the ownership semantics of the
memory operation that they are creating.
Operationally, this is a NFC change since I have just gone through the compiler
and updated all places where we create loads, stores to pass in the former
default argument ({Load,Store}OwnershipQualifier::Unqualified), to
SILBuilder::create{Load,Store}(...). For now, one can just do that in situations
where one needs to create loads/stores, but over time, I am going to tighten the
semantics up via the verifier.
rdar://28685236
I am going to add asserts to SILBuilder to ensure that the leaf level functions
that create qualified ownership and unqualified ownership instructions assert if
one attempts to create functions with the wrong ownership qualification.
This creates problems in the parser though since we apply the ownership
qualification heuristic to SILInstructions after we have created the instruction
via SILBuilder. I could change the ownership model evaluator to have special
methods for various instructions, but I think that would introduce more
decentralized code in the Parser which I want to avoid. Instead this commit just
introduces a small isParsing flag that is set by SILParser on its SILBuilder
that will cause these invariants to be ignored. Since the bool is used in the
actual asserts themselves they are at the call site where they have an effect,
making it very clear what is going on.
rdar://28851920
This lets us get to the goal of +0 guaranteed closure contexts. NFC yet, just add the under-the-hood ability for partial_apply instructions producing callee-guaranteed closures to be parsed, printed, and serialized.
It's the same thing as for alloc_ref: the optional [tail_elems ...] attribute specify the tail elements to allocate.
For details see docs/SIL.rst
This feature is needed so that we can allocate a MangedBuffer with alloc_ref_dynamic.
The ManagedBuffer.create() function uses the dynamic self type to create the buffer instance.
The new instructions are: ref_tail_addr, tail_addr and a new attribute [ tail_elems ] for alloc_ref.
For details see docs/SIL.rst
As these new instructions are not generated so far, this is a NFC.
The new instructions are: ref_tail_addr, tail_addr and a new attribute [ tail_elems ] for alloc_ref.
For details see docs/SIL.rst
As these new instructions are not generated so far, this is a NFC.
If a SILBuilder creates a new instruction based on an old instruction and a new instruction is supposed to use some opened archetypes, one needs to set a proper opened archetypes context in the builder based on the opened archetypes used by the old instruction.
This fixes rdar://28024272