This is mostly intended to be used for testing at this point; in the
long run, we want to be using availability information to decide
whether to weak-link something or not. You'll notice a bunch of FIXMEs
in the test case that we may not need now, but will probably need to
handle in the future.
Groundwork for doing backward-deployment execution tests.
This will allow key paths to resiliently reference public properties from other binaries by referencing a descriptor vended by the originating binary. NFC yet, this just provides printing/parsing/verification of the new component.
@noescape function types will eventually be trivial. A
convert_escape_to_noescape instruction does not take ownership of its
operand. It is a projection to the trivial value carried by the closure
-- both context and implementation function viewed as a trivial value.
A safe SIL program must ensure that the object that the project value is based
on is live beyond the last use of the trivial value. This will be
achieve by means of making the lifetimes dependent.
For example:
%e = partial_apply [callee_guaranteed] %f(%z) : $@convention(thin) (Builtin.Int64) -> ()
%n = convert_escape_to_noescape %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
%n2 = mark_dependence %n : $@noescape @callee_guaranteed () -> () on %e : $@callee_guaranteed () -> ()
%f2 = function_ref @use : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
apply %f2(%n2) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
release_value %e : $@callee_guaranteed () -> ()
Note: This is not yet actually used.
Part of:
SR-5441
rdar://36116691
This is going to be used for "always emit into client" functions,
such as default argument generators and stored property
initializers.
- In dead function elimination, these functions behave identically to
public functions, serving as "anchors" for the mark-and-sweep
analysis.
- There is no external variant of this linkage, because external
declarations can use HiddenExternal linkage -- the definition should
always be emitted by another translation unit in the same Swift
module.
- When deserialized, they receive shared linkage, because we want the
linker to coalesce multiple copies of the same deserialized
definition if it was deserialized from multiple translation units
in the same Swift module.
- When IRGen emits a definition with this linkage, it receives the
same LLVM-level linkage as a hidden definition, ensuring it does not
have a public entry point.
* Reduce array abstraction on apple platforms dealing with literals
Part of the ongoing quest to reduce swift array literal abstraction
penalties: make the SIL optimizer able to eliminate bridging overhead
when dealing with array literals.
Introduce a new classify_bridge_object SIL instruction to handle the
logic of extracting platform specific bits from a Builtin.BridgeObject
value that indicate whether it contains a ObjC tagged pointer object,
or a normal ObjC object. This allows the SIL optimizer to eliminate
these, which allows constant folding a ton of code. On the example
added to test/SILOptimizer/static_arrays.swift, this results in 4x
less SIL code, and also leads to a lot more commonality between linux
and apple platform codegen when passing an array literal.
This also introduces a couple of SIL combines for patterns that occur
in the array literal passing case.
For now these are underscored attributes, i.e. compiler internal attributes:
@_optimize(speed)
@_optimize(size)
@_optimize(none)
Those attributes override the command-line specified optimization mode for a specific function.
The @_optimize(none) attribute is equivalent to the already existing @_semantics("optimize.sil.never") attribute
Except GenericEnvironment.h, because you can't meaningfully use a
GenericEnvironment without its signature. Lots less depends on
GenericSignature.h now. NFC
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.
Pre-specializations need some special handling when it comes to the Serialized attribute. Their bodies should not be SIL serialized. Instead, only their declarations should be serialized.
And since their bodies are not serialized and cannot be imported by the client code, it is OK if pre-specializations reference non-fragile functions inside their bodies. Due to the same reason, it is fine if pre-specializations are referenced from fragile functions, even though these pre-specializations are not fragile in a usual sense.
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 etymology of these terms isn't about race, but "black" = "blocked"
and "white" = "allowed" isn't really a good look these days. In most
cases we weren't using these terms particularly precisely anyway, so
the rephrasing is actually an improvement.
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.
Consider a class hierarchy like the following:
class Base {
func m1() {}
func m2() {}
}
class Derived : Base {
override func m2() {}
func m3() {}
}
The SIL vtable for 'Derived' now records that the entry for m1
is inherited, the entry for m2 is an override, and the entry
for m3 is a new entry:
sil_vtable Derived {
#Base.m1!1: (Base) -> () -> () : _T01a4BaseC2m1yyF [inherited]
#Base.m2!1: (Base) -> () -> () : _T01a7DerivedC2m2yyF [override]
#Derived.m3!1: (Derived) -> () -> () : _T01a7DerivedC2m3yyF
}
This additional information will allow IRGen to emit the vtable
for Derived resiliently, without referencing the symbol for
the inherited method m1() directly.
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".
With the introduction of special decl names, `Identifier getName()` on
`ValueDecl` will be removed and pushed down to nominal declarations
whose name is guaranteed not to be special. Prepare for this by calling
to `DeclBaseName getBaseName()` instead where appropriate.
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.