Since LayoutPrespecialization has been enabled by default in all compiler
invocations for quite some time, it doesn't make sense for it to be treated as
experimental feature. Make it a baseline feature and remove all the
checks for it from the compiler.
Need to canonicalize the replacement type. Otherwise it could be generic if it is a typealias inside a generic type, e.g.
```
struct S<T> {
typealias I = Int
}
```
Addressable parameters must remain indirect.
Incidentally also fixes an obvious latent bug in which all specialization was
disabled if any metatypes could not be specialized.
Fixes rdar://145687827 (Crash of inline-stored Span properties with optimizations)
The conformances no longer match the replacement types after the
transformation here, so we must look them up again. This is now
flagged by SubstitutionMap::verify().
* fix a false error if a derived class has different generic parameters than its base class
* fix a similar problem if a non-generic class derives from a generic class
* fix a compiler crash for calling a class method on a class metatype
rdar://137692055
Pre-specialization of `Array._endMutation` (for AnyObject) prevents inlining this function and that results in sub-optimal code.
This function is basically a no-op. So it should be inlined.
Unfortunately we cannot remove the specialize-attributes anymore because the pre-specialized function(s) are now part of the stdlib's ABI.
Therefore make an exception for `Array._endMutation` in the generic specializer.
In Embedded Swift, witness method lookup is done from specialized witness tables.
For this to work, the type of witness_method must be specialized as well.
Otherwise the method call would be done with wrong parameter conventions (indirect instead of direct).
MandatoryPerformanceOptimizations already did most of the vtable specialization work.
So it makes sense to remove the VTableSpecializerPass completely and do everything in MandatoryPerformanceOptimizations.
The generality of the `AvailabilityContext` name made it seem like it
encapsulates more than it does. Really it just augments `VersionRange` with
additional set algebra operations that are useful for availability
computations. The `AvailabilityContext` name should be reserved for something
pulls together more than just a single version.
Some requirement machine work
Rename requirement to Value
Rename more things to Value
Fix integer checking for requirement
some docs and parser changes
Minor fixes
If there is no read from an indirect argument, this argument has to be dropped.
At the call site the store to the argument's memory location could have been removed (based on the callee's memory effects).
Therefore, converting such an unused indirect argument to a direct argument, would load an uninitialized value at the call site.
This would lead to verifier errors and in worst case to a miscompile because IRGen can implicitly use dead arguments, e.g. for getting the type of a class reference.
Instead of adding a "flag" (`m` in `...Tgm5`) make it more generic to allow to drop any unused argument.
Add all dropped arguments with a `t<n-1>` (where `<n-1>` is empty for n === 0). For example `...Ttt2g5`.
This corresponds to the parameter-passing convention of the Itanium C++
ABI, in which the argument is passed indirectly and possibly modified,
but not destroyed, by the callee.
@in_cxx is handled the same way as @in in callers and @in_guaranteed in
callees. OwnershipModelEliminator emits the call to destroy_addr that is
needed to destroy the argument in the caller.
rdar://122707697
Create two versions of the following functions:
isConsumedParameter
isGuaranteedParameter
SILParameterInfo::isConsumed
SILParameterInfo::isGuaranteed
SILArgumentConvention::isOwnedConvention
SILArgumentConvention::isGuaranteedConvention
These changes will be needed when we add a new convention for
non-trivial C++ types as the functions will return different answers
depending on whether they are called for the caller or the callee. This
commit doesn't change any functionality.
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
inlining, generic/closure specialization, and devirtualization optimization passes.
SILFunction::canBeInlinedIntoCaller now exlicitly requires a caller's SerializedKind_t arg.
isAnySerialized() is added as a convenience function that checks if [serialized] or [serialized_for_pkg].
Resolves rdar://128704752
[serialized_for_package] if Package CMO is enabled. The latter kind
allows a function to be serialized even if it contains loadable types,
if Package CMO is enabled. Renamed IsSerialized_t as SerializedKind_t.
The tri-state serialization kind requires validating inlinability
depending on the serialization kinds of callee vs caller; e.g. if the
callee is [serialized_for_package], the caller must be _not_ [serialized].
Renamed `hasValidLinkageForFragileInline` as `canBeInlinedIntoCaller`
that takes in its caller's SerializedKind as an argument. Another argument
`assumeFragileCaller` is also added to ensure that the calle sites of
this function know the caller is serialized unless it's called for SIL
inlining optimization passes.
The [serialized_for_package] attribute is allowed for SIL function, global var,
v-table, and witness-table.
Resolves rdar://128406520
We weren't looking at the length of an opaque archetype's type parameter,
which could lead to unbounded growth in the number of emitted specializations.
Fixes rdar://problem/121867690.
This may involve changing the linkage of the specialized function.
If called from a serialized function we cannot make the specialized function shared and non-serialized.
The only other option is to keep the original function's linkage.
rdar://121675461
Marker protocols can be ignored in the specialization, because they have no witness and the conformance will be checked before the specialization is applied.
Also fixes an issue where multiple requirements on the same type caused type mismatches in the erased signature.
rdar://121071710
Currently it uses builtin integers, which round up to the next power of 2, which is not what we want here. Instead it should use builtin vectors of uint8 and a number of elements equal to the stride in bytes.
rdar://119329771
This layout allows adding pre-specializations for trivial types that have a different size, but the same stride. This is especially useful for collections, where the stride is the important factor.
* [SILOpt] Allow pre-specializations for _Trivial of known size
rdar://119224542
This allows pre-specializations to be generated and applied for trivial types of a shared size.
* [SILOpt] Apply _Class pre-specializations to wrapped single references
rdar://119047505
A struct wrapping a single reference has an identical layout to the reference itself, so we can apply the same pre-specializations.
* Add test case for overaligned struct
This means to support specializing functions with indirect error results.
Also, when specializing (and the concrete error type is loadable), convert the indirect error to a direct error.
rdar://118532113
Unlike in regular swift, The class_method instruction references the specialized version of a class method.
This must be handled in ReabstractionInfo: it needs to work without a concrete callee SIL function.
Also, the SILVerifier must handle the case that a class_method instruction references a specialized method.
- VTableSpecializer, a new pass that synthesizes a new vtable per each observed concrete type used
- Don't use full type metadata refs in embedded Swift
- Lazily emit specialized class metadata (LazySpecializedClassMetadata) in IRGen
- Don't emit regular class metadata for a class decl if it's generic (only emit the specialized metadata)
llvm::SmallSetVector changed semantics
(https://reviews.llvm.org/D152497) resulting in build failures in Swift.
The old semantics allowed usage of types that did not have an
`operator==` because `SmallDenseSet` uses `DenseSetInfo<T>::isEqual` to
determine equality. The new implementation switched to using
`std::find`, which internally uses `operator==`. This type is used
pretty frequently with `swift::Type`, which intentionally deletes
`operator==` as it is not the canonical type and therefore cannot be
compared in normal circumstances.
This patch adds a new type-alias to the Swift namespace that provides
the old semantic behavior for `SmallSetVector`. I've also gone through
and replaced usages of `llvm::SmallSetVector` with the
`Swift::SmallSetVector` in places where we're storing a type that
doesn't implement or explicitly deletes `operator==`. The changes to
`llvm::SmallSetVector` should improve compile-time performance, so I
left the `llvm::SmallSetVector` where possible.
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".
I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.