This replaces the '[volatile]' flag. Now, class_method and
super_method are only used for vtable dispatch.
The witness_method instruction is still overloaded for use
with both ObjC protocol requirements and Swift protocol
requirements; the next step is to make it only mean the
latter, also using objc_method for ObjC protocol calls.
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.
These will be used for unit-testing the Type::join functionality in the
type checker. The result of the join is replaced during constraint
generation with the actual type.
There is currently no checking for whether the arguments can be used to
statically compute the value, so bad things will likely happen if
e.g. they are type variables. Once more of the basic functionality of
Type::join is working I'll make this a bit more bullet-proof in that
regard.
They include:
// Compute the join of T and U and return the metatype of that type.
Builtin.type_join<T, U, V>(_: T.Type, _: U.Type) -> V.Type
// Compute the join of &T and U and return the metatype of that type.
Builtin.type_join_inout<T, U, V>(_: inout T, _: U.Type) -> V.Type
// Compute the join of T.Type and U.Type and return that type.
Builtin.type_join_meta<T, U, V>(_: T.Type, _: U.Type) -> V.Type
I've added a couple simple tests to start off, based on what currently
works (aka doesn't cause an assert, crash, etc.).
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.
This commit contains:
-) adding the new instructions + infrastructure, like parsing, printing, etc.
-) support in IRGen to generate global object-variables (i.e. "heap" objects) which are statically initialized in the data section.
-) IRGen for global_value which lazily initializes the object header and returns a reference to the object.
For details see the documentation of the new instructions in SIL.rst.
Static initializers are now represented by a list of literal and aggregate instructions in a SILGlobalVariable.
For details see SIL.rst.
This representation is cleaner than what we did so far (point to the initializer function and do some pattern matching).
One implication of that change is that now (a subset of) instructions not necessarily have a parent function.
Regarding the generated code it's a NFC.
Also the swift module format didn't change because so far we don't serializer global variables.
We compile with a pedantic warning that complains about these things,
and the massive flood of warnings is actually causing problems for the
build infrastructure.
This is the first in a series of commits that cleans up the SILOwnershipVerifier
based off of discussions/feedback with other people who are now using it. The
next step is to split the checker from the declarative computation of what I
call the UseOwnershipRequirement.
rdar://33358110
Otherwise, one can run into situations where an Any from a SILUndef results in
SSA values having destroying uses. Since we are dealing with an undef value,
from an ownership perspective, we can assume any form of ownership constraints
that we want. Thus we can treat the value as being eternal and thus from the
ownership verifier's perspective like a metatype.
rdar://33358110
This has the same semantics as open_existential_box, but returns an object value
instead of an address.
This is used in SIL opaque values mode. Attempting to reuse open_existential_box
in this mode causes SIL type inconsistencies that are too difficult to work
around. Adding this instruction allows for consistent handling of opaque values.
The original versions of several of these currently redundant instructions will
be removed once the SIL representation stabilizes.
These instructions have the same semantics as the *ExistentialAddr instructions
but operate directly on the existential value, not its address.
This is in preparation for adding ExistentialBoxValue instructions.
The previous name would cause impossible confusion with "opaque existentials"
and "opaque existential boxes".
This semantic attribute allows a user to disable ownership verification on
specific functions.
The intention is that once I turn on the sil ownership verifier for parts of the
stdlib, if an engineer exposes an ownership issue, they can disable ownership
verification on that specific function, file a bug, and continue with their
work.
rdar://31880847
This means that a trivial enum case of a non-trivial enum can be returned @owned
even though it is trivial. We already follow this pattern with bb arguments.
rdar://31880847
This is needed to ensure that SILGenPattern propagates values at +0 instead of
+1.
I also improved our handling of terminators in general when it comes to having
"borrowed" arguments. The basic verification requirement is that the
end_borrow_argument is treated as a use of the parent borrow. This ensures that
the borrowed argument can not extend the lifetime of the borrowed value without
the verifier triggering.
rdar://31880847