This establishes a real def-use relation from the self-parameter to any instruction which uses the dynamic-self type.
This is an addition to what was already done for opened archetypes.
The biggest part of this commit is to rename "OpenedArchetypeOperands" to "TypeDependentOperands" as this name is now more appropriate.
Other than that the change includes:
*) type-dependent operands are now printed after a SIL instruction in a comment as "type-defs:" (for debugging)
*) FuncationSignatureOpts doesn't need to explicitly check if a function doesn't bind dynamic self to remove a dead self metadata argument
*) the check if a function binds dynamic self (used in the inliner) is much simpler now
*) also collect type-dependent operands for ApplyInstBase::SubstCalleeType and not only in the substitution list
*) with this SILInstruction::mayHaveOpenedArchetypeOperands (used in CSE) is not needed anymore and removed
*) add type dependent operands to dynamic_method instruction
Regarding the generated code it should be a NFC.
When DynamicSelfType occurs outside of a class body (for example,
inside of a SIL function), it is not enough to simply utter 'Self',
because then we lose the underlying type.
Instead, print it out as '@dynamic_self Foo', where 'Foo' is the
underlying class type or archetype, and add parser support for
the same.
Fixes <rdar://problem/27735857>.
Previously, if a generic type had a stored property with
a generic type and an initializer expression, we would
emit the expression directly in the body of each designated
initializer.
This is a problem if the designated initializer is defined
within an extension (even in the same source file), because
extensions have a different set of generic parameters and
archetypes.
Also, we've had bugs in the past where emitting an
expression multiple times didn't work properly. While these
might currently all be fixed, this is a tricky case to test
and it would be best to avoid it.
Fix both problems by emitting the initializer expression
inside its own function at the SIL level, and call the
initializer function from each designated initializer.
I'm using the existing 'variable initializer' mangling for this;
it doesn't seem to be used for anything else right now.
Currently, the default memberwise initializer does not use
this, because the machinery for emitting it is somewhat
duplicated and separate from the initializer expressions in
user-defined constructors. I'll clean this up in an upcoming
patch.
Fixes <https://bugs.swift.org/browse/SR-488>.
Adds a "[clang <value_decl>]" attribute to a SIL function declaration for clang imported functions.
SIL serialization already handled this attribute, but not the SIL parser.
Fixes rdar://problem/27378249, SR-2089
This was done some time ago to make it easier to diff large amounts of SIL
output. The problem is that it makes it difficult to know the *true* memory
order that the predecessor list is in which can lead to surprise when working
with SIL and create test cases.
I believe some time after that point we added the notion of "sorted" sil, i.e.
SIL that does not guarantee any relation to the actual memory representation of
the SIL and is meant to ease diffing. This fits nicely with the true intention
of this sort of sorting.
Thus this commit puts sorting PredIDs, UserIDs behind that flag.
In Swift, default arguments are associated with a function or
initializer's declaration---not with its type. This was not always the
case, and TupleType's ability to store a default argument kind is a
messy holdover from those dark times.
Eliminate the default argument kind from TupleType, which involves
migrating a few more clients over to declaration-centric handling of
default arguments. Doing so is usually a bug-fix anyway: without the
declaration, one didn't really have
The SILGen test changes are due to a name-mangling fix that fell out
of this change: a tuple type is mangled differently than a non-tuple
type, and having a default argument would make the parameter list of a
single-parameter function into a tuple type. Hence,
func foo(x: Int = 5)
would get a different mangling from
func foo(x: Int)
even though we didn't actually allow overloading.
Fixes rdar://problem/24016341, and helps us along the way to SE-0111
(removing the significance of argument labels) because argument labels
are also declaration-centric, and need the same information.
Strict aliasing only applies to memory operations that use strict
addresses. The optimizer needs to be aware of this flag. Uses of raw
addresses should not have their address substituted with a strict
address.
Also add Builtin.LoadRaw which will be used by raw pointer loads.
Till now there was no way in SIL to explicitly express a dependency of an instruction on any opened archetypes used by it. This was a cause of many errors and correctness issues. In many cases the code was moved around without taking into account these dependencies, which resulted in breaking the invariant that any uses of an opened archetype should be dominated by the definition of this archetype.
This patch does the following:
- Map opened archetypes to the instructions defining them, i.e. to open_existential instructions.
- Introduce a helper class SILOpenedArchetypesTracker for creating and maintaining such mappings.
- Introduce a helper class SILOpenedArchetypesState for providing a read-only API for looking up available opened archetypes.
- Each SIL instruction which uses an opened archetype as a type gets an additional opened archetype operand representing a dependency of the instruction on this archetype. These opened archetypes operands are an in-memory representation. They are not serialized. Instead, they are re-constructed when reading binary or textual SIL files.
- SILVerifier was extended to conduct more thorough checks related to the usage of opened archetypes.
Till now there was no way in SIL to explicitly express a dependency of an instruction on any opened archetypes used by it. This was a cause of many errors and correctness issues. In many cases the code was moved around without taking into account these dependencies, which resulted in breaking the invariant that any uses of an opened archetype should be dominated by the definition of this archetype.
This patch does the following:
- Map opened archetypes to the instructions defining them, i.e. to open_existential instructions.
- Introduce a helper class SILOpenedArchetypesTracker for creating and maintaining such mappings.
- Introduce a helper class SILOpenedArchetypesState for providing a read-only API for looking up available opened archetypes.
- Each SIL instruction which uses an opened archetype as a type gets an additional opened archetype operand representing a dependency of the instruction on this archetype. These opened archetypes operands are an in-memory representation. They are not serialized. Instead, they are re-constructed when reading binary or textual SIL files.
- SILVerifier was extended to conduct more thorough checks related to the usage of opened archetypes.
Till now there was no way in SIL to explicitly express a dependency of an instruction on any opened archetypes used by it. This was a cause of many errors and correctness issues. In many cases the code was moved around without taking into account these dependencies, which resulted in breaking the invariant that any uses of an opened archetype should be dominated by the definition of this archetype.
This patch does the following:
- Map opened archetypes to the instructions defining them, i.e. to open_existential instructions.
- Introduce a helper class SILOpenedArchetypesTracker for creating and maintaining such mappings.
- Introduce a helper class SILOpenedArchetypesState for providing a read-only API for looking up available opened archetypes.
- Each SIL instruction which uses an opened archetype as a type gets an additional opened archetype operand representing a dependency of the instruction on this archetype. These opened archetypes operands are an in-memory representation. They are not serialized. Instead, they are re-constructed when reading binary or textual SIL files.
- SILVerifier was extended to conduct more thorough checks related to the usage of opened archetypes.
Now that ObjC types can be generic, we need to satisfy the type system by plumbing pseudogeneric parameters through func-to-block invocation thunks. Fixes rdar://problem/26524763.
This was mistakenly reverted in an attempt to fix buildbots.
Unfortunately it's now smashed into one commit.
---
Introduce @_specialize(<type list>) internal attribute.
This attribute can be attached to generic functions. The attribute's
arguments must be a list of concrete types to be substituted in the
function's generic signature. Any number of specializations may be
associated with a generic function.
This attribute provides a hint to the compiler. At -O, the compiler
will generate the specified specializations and emit calls to the
specialized code in the original generic function guarded by type
checks.
The current attribute is designed to be an internal tool for
performance experimentation. It does not affect the language or
API. This work may be extended in the future to add user-visible
attributes that do provide API guarantees and/or direct dispatch to
specialized code.
This attribute works on any generic function: a freestanding function
with generic type parameters, a nongeneric method declared in a
generic class, a generic method in a nongeneric class or a generic
method in a generic class. A function's generic signature is a
concatenation of the generic context and the function's own generic
type parameters.
e.g.
struct S<T> {
var x: T
@_specialize(Int, Float)
mutating func exchangeSecond<U>(u: U, _ t: T) -> (U, T) {
x = t
return (u, x)
}
}
// Substitutes: <T, U> with <Int, Float> producing:
// S<Int>::exchangeSecond<Float>(u: Float, t: Int) -> (Float, Int)
---
[SILOptimizer] Introduce an eager-specializer pass.
This pass finds generic functions with @_specialized attributes and
generates specialized code for the attribute's concrete types. It
inserts type checks and guarded dispatch at the beginning of the
generic function for each specialization. Since we don't currently
expose this attribute as API and don't specialize vtables and witness
tables yet, the only way to reach the specialized code is by calling
the generic function which performs the guarded dispatch.
In the future, we can build on this work in several ways:
- cross module dispatch directly to specialized code
- dynamic dispatch directly to specialized code
- automated specialization based on less specific hints
- partial specialization
- and so on...
I reorganized and refactored the optimizer's generic utilities to
support direct function specialization as opposed to apply
specialization.
Temporarily reverting @_specialize because stdlib unit tests are
failing on an internal branch during deserialization.
This reverts commit e2c43cfe14, reversing
changes made to 9078011f93.
Introduce a new SILPrintContext class which is the main handle passed to the SILModule's and SILFunction's print functions.
It also allows to let derived classes implement call backs on instruction printing.
NFC for now, but needed for the upcoming SIL-debuginfo change.
This attribute can be attached to generic functions. The attribute's
arguments must be a list of concrete types to be substituted in the
function's generic signature. Any number of specializations may be
associated with a generic function.
This attribute provides a hint to the compiler. At -O, the compiler
will generate the specified specializations and emit calls to the
specialized code in the original generic function guarded by type
checks.
The current attribute is designed to be an internal tool for
performance experimentation. It does not affect the language or
API. This work may be extended in the future to add user-visible
attributes that do provide API guarantees and/or direct dispatch to
specialized code.
This attribute works on any generic function: a freestanding function
with generic type parameters, a nongeneric method declared in a
generic class, a generic method in a nongeneric class or a generic
method in a generic class. A function's generic signature is a
concatenation of the generic context and the function's own generic
type parameters.
e.g.
struct S<T> {
var x: T
@_specialize(Int, Float)
mutating func exchangeSecond<U>(u: U, _ t: T) -> (U, T) {
x = t
return (u, x)
}
}
// Substitutes: <T, U> with <Int, Float> producing:
// S<Int>::exchangeSecond<Float>(u: Float, t: Int) -> (Float, Int)
This is only used in the verifier, to ensure that default witness
thunks are suffiently visible.
Also this patch removes the asserts enforcing that only resilient
protocols have a default witness table. This will change in an
upcoming patch, and in this patch is necessary for the test to work.
This instruction creates a "virtual" address to represent a property with a behavior that supports definite initialization. The instruction holds references to functions that perform the initialization and 'set' logic for the property. It will be DI's job to rewrite assignments into this virtual address into calls to the initializer or setter based on the initialization state of the property at the time of assignment.
Previously SILDefaultWitnessTables only included "resilient" default
implementations, which are currently defined as those that appear at the
end of a protocol, after any requirements without defaults.
However, this was too inflexible. Instead, include all entries in the
SILDefaultWitnessTable, with invalid entries standing in for requirements
without defaults.
Previously, the minimum witness table size was a separate parameter, also
appearing in SIL syntax; now it can be calculated by looking at the entries
themselves. The getResilientDefaultEntries() method of SILDefaultWitnessTable
returns the same result as getEntries() did previously.
This ireapplies commit 255c52de9f.
Original commit message:
Serialize debug scope and location info in the SIL assembler language.
At the moment it is only possible to test the effects that SIL
optimization passes have on debug information by observing the
effects of a full .swift -> LLVM IR compilation. This change enable us
to write targeted testcases for single SIL optimization passes.
The new syntax is as follows:
sil-scope-ref ::= 'scope' [0-9]+
sil-scope ::= 'sil_scope' [0-9]+ '{'
sil-loc
'parent' scope-parent
('inlined_at' sil-scope-ref )?
'}'
scope-parent ::= sil-function-name ':' sil-type
scope-parent ::= sil-scope-ref
sil-loc ::= 'loc' string-literal ':' [0-9]+ ':' [0-9]+
Each instruction may have a debug location and a SIL scope reference
at the end. Debug locations consist of a filename, a line number, and
a column number. If the debug location is omitted, it defaults to the
location in the SIL source file. SIL scopes describe the position
inside the lexical scope structure that the Swift expression a SIL
instruction was generated from had originally. SIL scopes also hold
inlining information.
<rdar://problem/22706994>
At the moment it is only possible to test the effects that SIL
optimization passes have on debug information by observing the
effects of a full .swift -> LLVM IR compilation. This change enable us
to write targeted testcases for single SIL optimization passes.
The new syntax is as follows:
sil-scope-ref ::= 'scope' [0-9]+
sil-scope ::= 'sil_scope' [0-9]+ '{'
sil-loc
'parent' scope-parent
('inlined_at' sil-scope-ref )?
'}'
scope-parent ::= sil-function-name ':' sil-type
scope-parent ::= sil-scope-ref
sil-loc ::= 'loc' string-literal ':' [0-9]+ ':' [0-9]+
Each instruction may have a debug location and a SIL scope reference
at the end. Debug locations consist of a filename, a line number, and
a column number. If the debug location is omitted, it defaults to the
location in the SIL source file. SIL scopes describe the position
inside the lexical scope structure that the Swift expression a SIL
instruction was generated from had originally. SIL scopes also hold
inlining information.
<rdar://problem/22706994>
remove the mixed concept that was SILFileLocation.
Also add support for a third type of underlying storage that will be used
for deserialized debug lcoations from textual SIL.
NFC
<rdar://problem/22706994>
For long names this is easier to read and in most cases the omitted information can be seen in the actual SIL code.
With the option -Xllvm -sil-full-demangle the old behavior can be restored.
This will be used to help IRGen record protocol requirements
with resilient default implementations in protocol metadata.
To enable testing before all the Sema support is in place, this
patch adds SIL parser, printer and verifier support for default
witness tables.
For now, SILGen emits empty default witness tables for protocol
declarations in resilient modules, and IRGen ignores them when
emitting protocol metadata.
inlined-at chain.
The previous implementation was only correct for cases where the inliner
inlined bottom-up in the call graph, which happened to cover the majority
of all cases.
rdar://problem/24462475
The SIL parser used PolymorphicFunctionType in two places:
- Internals of SILFunctionType parsing
- Overload selection for class_method / super_method / dynamic_method
instructions
It is better to have Sema construct GenericFunctionType directly
in SIL mode. In particular, the overload selection logic is simpler
now, since it does not have to deal with the fact that
PolymorphicFunctionTypes do not canonicalize.
Mostly NFC, except the SIL printer output is a bit different; for a
generic method on a generic type, the type parameters all come first,
like ``<T><U> G<T> -> (U) -> ()'' -vs- ``<T> G<T> -> <U> (U) -> ()''.
Also, generic constraints look different, instead of ``<`Self` : P>``
we now have ``<Self where Self : P>''.
This patch has two consequences that will become important later:
- While code that constructs PolymorphicFunctionType still exists in
Sema, the SIL parser was the last major component that *consumed*
PolymorphicFunctionType.
- Everywhere we set SILFunction::ContextGenericParams, we now have
a well-formed context GenericSignature available, allowing
ContextGenericParams to be replaced by a GenericSignature
eventually.
As part of SE-0022, introduce an 'objc_selector' encoding for string
literals that places the UTF-8 string literal into the appropriate
segment for uniquing of Objective-C selector names.
As there are no instructions left which produce multiple result values, this is a NFC regarding the generated SIL and generated code.
Although this commit is large, most changes are straightforward adoptions to the changes in the ValueBase and SILValue classes.