introduce a common superclass, SILNode.
This is in preparation for allowing instructions to have multiple
results. It is also a somewhat more elegant representation for
instructions that have zero results. Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction. Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.
A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.
Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.
This involved a bit of cleanup in both ownership classification and
verification. Trivial argument types now have trivial ownership. Also, the
verifier allows
- enums with non-trivial ownership to be passed to trivial arguments as long as
it can verify that all payloads are trivial.
- enums with trivial ownership to be passed as owned arguments. Preventing this
didn't make sense.
Introduce a new runtime entry point,
`swift_objc_swift3ImplicitObjCEntrypoint`, which is called from any
Objective-C method that was generated due to `@objc` inference rules
that were removed by SE-0160. Aside from being a central place where
users can set a breakpoint to catch when this occurs, this operation
provides logging capabilities that can be enabled by setting the
environment variable SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT:
SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=0 (default): do not log
SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=1: log failed messages
SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=2: log failed messages with
backtrace
SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=3: log failed messages with
backtrace and abort the process.
The log messages look something like:
***Swift runtime: entrypoint -[t.MyClass foo] generated by
implicit @objc inference is deprecated and will be removed in
Swift 4
Previously often times when casting a value, we would just pass along the
cleanup of the uncasted value. With semantic SIL this is no longer correct since
the cleanup now needs to be on the cast result.
This caused problems for certain usages of Builtin.castToNativeObject(...) by
the stdlib. Specifically, the stdlib was using this on AnyObject values that
were not necessarily native. Since we were recreating the cleanup on the native
value, a swift native release was being used =><=.
In this commit I solve this problem by:
1. Adding an assert in Builtin.castToNativeObject(...) that ensures that any value
passed to Builtin.castToNativeObject() is known conservatively to use swift
native reference counting.
2. I changed all uses where we do not have a precondition of a native ref
counting type to use Builtin.castToUnknownObject(...).
3. I added a new Builtin called Builtin.unsafeCastToNativeObject(...) that does
not have the compile time check. I used this to rewrite callsites in the stdlib
where we know via preconditions that an AnyObject will dynamically always be
native.
rdar://29791263
...and IRGen it into a call to __tsan_write1 in compiler-rt. This is
preparatory work for a later patch that will add an experimental
option to treat Swift inout accesses as TSan writes.
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 allows for an unchecked_enum_data to be either a consumed instruction or a
borrowed instruction. The reason why this makes sense in contrast to other value
projection operations like struct_extract and tuple_extract is that an enum
payload is essentially a tuple. This means that we are extracting the entire
value when we perform a struct_extract. So forwarding is viable from a semantic
perspective since if we destroy the payload, there is nothing left to destroy.
This contrasts with struct_extract and tuple_extract where we may have other
parts of the struct/tuple to destroy.
rdar://29791263
This caused a crasher when running the ownership verifier. I don't have a test
case right now, since it happened several weeks ago.
The bug can not happen again since I eliminated the nullptr default argument.
rdar://29791263
I thought this was modeling a value returned at +0. But in reality, the
instruction is created a guaranteed region by performing the following
instruction sequence:
%1 = copy_value %0 : $GuaranteedValue
(%2, %3) = Builtin "unsafeGuaranteed" (%1)
... *STUFF* ...
Builtin "endUnsafeGuaranteed" (%2) : $Token
destroy_value %3 : $GuaranteedValue
rdar://29791263
[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.
This also avoids undefined behavior when we try to look up the
ParameterConvention of a type dependent operand. Since type dependent operands
do not have a convention, this causes us to hit an assertion.
rdar://29791263
This is only enabled when semantic sil is enabled /and/ we are not parsing
unqualified SIL.
*NOTE* To properly write tests for this, I had to rework how we verified
Branch/CondBranch insts to be actually correct (instead of pseudo-correct). I
have to put this functionality together in order to write tests.
rdar://29791263
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
Originally, we were going to use the result to enforce end_borrow lifetimes for
store_borrow. But with Andy's changes, this should no longer be necessary since
@in_guaranteed and @guaranteed will both take values.
rdar://29791263
The way SILResultInfo::getOwnershipKind(SILModule &) was implemented before was
incorrect, resulting in getTypeLowering being called on a lowered type without a
proper generic signature being pushed on the type lowering stack. This commit
fixes that issue locally.
The real fix is in a PR that Slava is preparing that provides a getTypeLowering
that takes a SILType and a GenericSignature so that the user does not need to
perform a push/pop.
rdar://29791263