The goal is to make it more composable to add trailing-objects fields in
a subclass.
While I was doing this, I noticed that the apply instructions provided
redundant getNumArguments() and getNumCallArguments() accessors, so I
went ahead and unified them.
This will allow us to remove dynamic_method, emitting objc_method
in its place. It will also allow objc_method to be used for
Objective-C protocol method calls, with witness_method used
for Swift native protocol method calls only.
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.
Update the SILBuilder and other relevant bits of SILGen s.t we pass
along branch taken counts whenever we create conditional branches.
There is a lot of unfinished work here: we need to teach ParseSIL,
DeserializeSIL, and the SILOptimizer about profile data. And add a
stable AST hasher. And add tests for it all.
Let's skip all of that for now. Next, we'll wire in some actual profile
data.
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.
The SIL witness_method instruction takes a protocol method and a
protocol conformance. IRGen lowers this as a load of a function
pointer from a fixed offset in the witness table for the
conformance.
IRGen also handled the case where the conformance is to a
protocol that refines the protocol containing the requirement,
by calling ProtocolConformanceRef::getInherited() to map the
conformance stored in the instruction to the correct conformance
for the protocol requirement being called.
It appears that this possibilty is not exercised through our
test suite, and if this does come up it is better to fix
SILGen and the optimizer to construct witness_method calls
using exact conformances only instead.
Furthermore, ProtocolConformanceRef::getInherited() only handles
a single level of refinement. So for example, if a protocol R
refines Q which refines R, we would crash when lowering a
witness_method instruction that calls P.foo() with a conformance
to R.
Therefore, code that emits witness_method instructions with a
conformance to a protocol that doesn't match the requirement was
likely going to do the wrong thing in this case anyway. Moving
the assertion earlier in the pipeline will help shake out these
cases.
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.
Remove the cast consumption kind from all unconditional casts. It
doesn't make sense for unconditional casts, complicates SIL ownership,
and wasn't fully supported for all variants. Copies should be
explicit.
This removes the function body, but preserves the SILFunction object, which may be still referenced by different kinds of meta-information e.g. debug info for inlined functions, generic specializations information, etc.
Doing this unconditionally simplifies the code and makes it less error-prone to reference SILFunctions from any kind of meta-information. It just works. No need to set any special flags, etc.
GenericSpecializationInformation contains information regarding how a given specialized function was created, e.g. which caller function triggered this specialization, which substitutions were used, etc. Provide some debugging flags to dump the collected specialization information.
The information about generic specializations is referenced by the specialized functions and by call-sites originating from specialized functions.
This information can be created/used by the generic specializer to detect generic call-sites whose specialization would result in non-terminating sequence of subsequent generic specializations.
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".
Till now createApply, createTryApply, createPartialApply were taking some arguments like SubstCalleeType or ResultType. But these arguments are redundant and can be easily derived from other arguments of these functions. There is no need to put the burden of their computation on the clients of these APIs.
The removal of these redundant parameters simplifies the APIs and reduces the possibility of providing mismatched types by clients, which often happened in the past.
All we need to store is whether the SILDeclRef directly
references the declaration, or if it references a curry
thunk, and we already have an isCurried bit for that.
The following instructions were enhanced with type dependent operands:
- convert_function
- pointer_to_thin_function
- upcast_inst
- thin_to_thick_function
Fixes rdar://31879356
A computed component needs:
- A stable identifier for equality checking. This can be either a static function reference for concrete property implementations, or a reference into a vtable or witness table for a dynamically dispatched property. This should correspond to a public ABI interface for public things.
- Getter and setter (TODO: and materializeForSet) references. These might be thunks to reach the necessary abstraction level for the keypath implementation, so they can't be used as stable identifiers directly.
- Separate out a uniquable KeyPathPattern that describes the context-free shape of the key path, with generic parameters and (eventually) subscript index slots factored out.
- Add component kinds for gettable and settable properties.