The ComputeEffects pass derives escape information for function arguments and adds those effects in the function.
This needs a lot of changes in check-lines in the tests, because the effects are printed in SIL
The ComputeEffects pass derives escape information for function arguments and adds those effects in the function.
This needs a lot of changes in check-lines in the tests, because the effects are printed in SIL
This attribute allows to define a pre-specialized entry point of a
generic function in a library.
The following definition provides a pre-specialized entry point for
`genericFunc(_:)` for the parameter type `Int` that clients of the
library can call.
```
@_specialize(exported: true, where T == Int)
public func genericFunc<T>(_ t: T) { ... }
```
Pre-specializations of internal `@inlinable` functions are allowed.
```
@usableFromInline
internal struct GenericThing<T> {
@_specialize(exported: true, where T == Int)
@inlinable
internal func genericMethod(_ t: T) {
}
}
```
There is syntax to pre-specialize a method from a different module.
```
import ModuleDefiningGenericFunc
@_specialize(exported: true, target: genericFunc(_:), where T == Double)
func prespecialize_genericFunc(_ t: T) { fatalError("dont call") }
```
Specially marked extensions allow for pre-specialization of internal
methods accross module boundries (respecting `@inlinable` and
`@usableFromInline`).
```
import ModuleDefiningGenericThing
public struct Something {}
@_specializeExtension
extension GenericThing {
@_specialize(exported: true, target: genericMethod(_:), where T == Something)
func prespecialize_genericMethod(_ t: T) { fatalError("dont call") }
}
```
rdar://64993425
Accessors logically belong to their storage and can be synthesized
on the fly, so removing them from the members list eliminates one
source of mutability (but doesn't eliminate it; there are also
witnesses for derived conformances, and implicit constructors).
Since a few ASTWalker implementations break in non-trivial ways when
the traversal is changed to visit accessors as children of the storage
rather than peers, I hacked up the ASTWalker to optionally preserve
the old traversal order for now. This is ugly and needs to be cleaned up,
but I want to avoid breaking _too_ much with this commit.
Most of this patch is just removing special cases for materializeForSet
or other fairly mechanical replacements. Unfortunately, the rest is
still a fairly big change, and not one that can be easily split apart
because of the quite reasonable reliance on metaprogramming throughout
the compiler. And, of course, there are a bunch of test updates that
have to be sync'ed with the actual change to code-generation.
This is SR-7134.
The SILGen testsuite consists of valid Swift code covering most language
features. We use these tests to verify that no unknown nodes are in the
file's libSyntax tree. That way we will (hopefully) catch any future
changes or additions to the language which are not implemented in
libSyntax.
I am going to leave in the infrastructure around this just in case. But there is
no reason to keep this in the tests themselves. I can always just revert this
and I don't think merge conflicts are likely due to previous work I did around
the tooling for this.
Otherwise, the plus_zero_* tests will have plus_zero_* as a module name, causing
massive FileCheck problems.
The reason why I am doing it with the main tests is so that I can use it when
syncing branches/etc.
radar://34222540
Also, add a third [serializable] state for functions whose bodies we
*can* serialize, but only do so if they're referenced from another
serialized function.
This will be used for bodies synthesized for imported definitions,
such as init(rawValue:), etc, and various thunks, but for now this
change is NFC.
We had some non-deterministic behavior where depending on
validation order, synthesized accessors would end up in
different places because we would sometimes just add them
at the end of the member list.
Now add the getter right after the storage, the setter
right after the getter and the materializeForSet right
after the setter.
This changes some test output where the declaration order
did not make sense before but should otherwise have no
functional effect.
In 74d979f0ac, the policy was changed
so that only value type accessors are ever marked transparent, and
not class accessors.
This was intended to fix a bug where inlining an accessor of an
Objective-C-derived class across module boundaries caused a linker
failure because the accessor referenced a field offset variable,
which has hidden visibility.
However, this also caused a performance regression for Swift native
classes. Bring back the old behavior for Swift native classes in
non-resilient modules.
Fixes <rdar://problem/29884727>.
Recently I changed the ArchetypeBuilder is minimize requirements
in generic signatures. However substitution lists still contained
all recursively-expanded nested types.
With recursive conformances, this list becomes potentially
infinite, so we can't expand it out anymore. Also, it is just
a waste of time to have them there.
There was a ton of complicated logic here to work around
two problems:
- Same-type constraints were not represented properly in
RequirementReprs, requiring us to store them in strong form
and parse them out when printing type interfaces.
- The TypeBase::getAllGenericArgs() method did not do the
right thing for members of protocols and protocol extensions,
and so instead of simple calls to Type::subst(), we had
an elaborate 'ArchetypeTransformer' abstraction repeated
in two places.
Rewrite this code to use GenericSignatures and
GenericFunctionType instead of old-school GenericParamLists
and PolymorphicFunctionType.
This changes the code completion and AST printer output
slightly. A few of the changes are actually fixes for cases
where the old code didn't handle substitutions properly.
A few others are subjective, for example a generic parameter
list of the form <T : Proto> now prints as <T where T : Proto>.
We can add heuristics to make the output whatever we want
here; the important thing is that now we're using modern
abstractions.
Instead of walking over PotentialArchetypes representatives directly
and using a separate list to record same-type constraints, just use
enumerateRequirements() and check the RequirementSource to drop
redundant requirements.
This means getGenericSignature() and getCanonicalManglingSignature()
can share the same logic for collecting requirements; the only
differences are the following:
- both drop requirements from Redundant sources, but mangling
signatures also drop requirements from Protocol sources
- mangling signatures also canonicalize the types appearing in the
final requirement
As proposed in SE-0107: UnsafeRawPointer:
Rename 'init(allocatingCapacity:)' to 'UnsafeMutablePointer.allocate(capacity:)'
Rename 'deallocateCapacity' to 'deallocate(capacity:)'
`allocate` should not be an initializer. It's primary function is to allocate
memory, not initialize a pointer.
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.
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)