Storing this separately is unnecessary since we already
serialize the enum element's interface type. Also, this
eliminates one of the few remaining cases where we serialize
archetypes during AST serialization.
This seems to more than fix a performance regression that we
detected on a metadata-allocation microbenchmark.
A few months ago, I improved the metadata cache representation
and changed the metadata allocation scheme to primarily use malloc.
Previously, we'd been using malloc in the concurrent tree data
structure but a per-cache slab allocator for the metadata itself.
At the time, I was concerned about the overhead of per-cache
allocators, since many metadata patterns see only a small number
of instantiations. That's still an important factor, so in the
new scheme we're using a global allocator; but instead of using
malloc for individual allocations, we're using a slab allocator,
which should have better peak, single-thread performance, at the
cost of not easily supporting deallocation. Deallocation is
only used for metadata when there's contention on the cache, and
specifically only when there's contention for the same key, so
leaking a little isn't the worst thing in the world.
The initial slab is a 64K globally-allocated buffer.
Successive slabs are 16K and allocated with malloc.
rdar://28189496
[NFC] Add -enable-sil-opaque-values frontend option.
This will be used to change the SIL-level calling convention for opaque values,
such as generics and resilient structs, to pass-by-value. Under this flag,
opaque values have SSA lifetimes, managed by copy_value and destroy_value.
This will make it easier to optimize copies and verify ownership.
* [SILGen] type lowering support for opaque values.
Add OpaqueValueTypeLowering.
Under EnableSILOpaqueValues, lower address-only types as opaque values.
* [SIL] Fix ValueOwnershipKind to support opaque SIL values.
* Test case: SILGen opaque value support for Parameter/ResultConvention.
* [SILGen] opaque value support for function arguments.
* Future Test case: SILGen opaque value specialDest arguments.
* Future Test case: SILGen opaque values: emitOpenExistential.
* Test case: SIL parsing support for EnableSILOpaqueValues.
* SILGen opaque values: prepareArchetypeCallee.
* [SIL Verify] allow copy_value for EnableSILOpaqueValues.
* Test cast: SIL serializer support for opaque values.
* Add a static_assert for ParameterConvention layout.
* Test case: Mandatory SILOpt support for EnableSILOpaqueValues.
* Test case: SILOpt support for EnableSILOpaqueValues.
* SILGen opaque values: TypeLowering emitCopyValue.
* SILBuilder createLoad. Allow loading opaque values.
* SIL Verifier. Allow loading and storing opaque values.
* SILGen emitSemanticStore support for opaque values.
* Test case for SILGen emitSemanticStore.
* Test case for SIL mandatory support for inout assignment.
* Fix SILGen opaque values test case after rebasing.
Textual SIL was sometimes ambiguous when SILDeclRefs were used, because the textual representation of SILDeclRefs was the same for functions that have the same name, but different signatures.
This API is meant to enable people working in SIL to be able to retrieve the
type lowering of a lowered type within the GenericSignature associated with a
given SILFunction's SILFunctionType.
Formal types are defined by the language's type system. SIL types are
lowered. They are no longer part of that type system.
The important distinction here is between the SIL storage type and the SIL value
type. To make this distinction clear, I refer to the SILFunctionTypes "formal"
conventions. These conventions dictate the SIL storage type but *not* the SIL
value type. I call them "formal" conventions because they are an immutable
characteristic of the function's type and made explicit via qualifiers on the
function type's parameters and results. This is in contrast to to SIL
conventions which depend on the SIL stage, and in the short term whether the
opaque values flag is enabled.
Separate formal lowered types from SIL types.
The SIL type of an argument will depend on the SIL module's conventions.
The module conventions are determined by the SIL stage and LangOpts.
Almost NFC, but specialized manglings are broken incidentally as a result of
fixes to the way passes handle book-keeping of aruments. The mangler is fixed in
the subsequent commit.
Otherwise, NFC is intended, but quite possible do to rewriting the logic in many
places.
Names matter. When using an unsigned int to index arguments, always make it
clear what the index refers to. It is a particularly confusing in this code because:
- mangling should not care about argument indices at all, only the function type should matter.
- argument indices for a given function type may be different depending on the SIL stage.
- these indices are actually a contract between the client code and the mangler.
- the specialized function's argument indices are different than the original indices!
This issue was hiding bugs in the mangler. The bug fixes will be in a separate PR.
There's a class of errors in Serialization called "circularity
issues", where declaration A in file A.swift depends on declaration B
in file B.swift, and B also depends on A. In some cases we can manage
to type-check each of these files individually due to the laziness of
'validateDecl', but then fail to merge the "partial modules" generated
from A.swift and B.swift to form a single swiftmodule for the library
(because deserialization is a little less lazy for some things). A
common case of this is when at least one of the declarations is
nested, in which case a lookup to find that declaration needs to load
all the members of the parent type. This gets even worse when the
nested type is defined in an extension.
This commit sidesteps that issue specifically for nested types by
creating a top-level, per-file table of nested types in the "partial
modules". When a type is in the same module, we can then look it up
/without/ importing all other members of the parent type.
The long-term solution is to allow accessing any members of a type
without having to load them all, something we should support not just
for module-merging while building a single target but when reading
from imported modules as well. This should improve both compile time
and memory usage, though I'm not sure to what extent. (Unfortunately,
too many things still depend on the whole members list being loaded.)
Because this is a new code path, I put in a switch to turn it off:
frontend flag -disable-serialization-nested-type-lookup-table
https://bugs.swift.org/browse/SR-3707 (and possibly others)
This also avoids undefined behavior when we try to look up the
ParameterConvention of a type dependent operand. Since type dependent operands
do not have a convention, this causes us to hit an assertion.
rdar://29791263
This is a generic signature that stores exactly the requirements that a
protocol decl introduces, not letting them be implied by the Self :
Protocol requirement, nor storing any requirements introduced by the
protocols requirements.
Specifically, suppose we have
protocol Foo {}
protocol Bar {}
protocol Baz {
associatedtype X : Foo
}
protocol Qux: Baz {
associatedtype X : Bar
}
The normal generic signature and (canonical) protocol requirement
signature of `Baz` will be, respectively
<Self where Self : Baz>
<Self where Self : Baz, Self.X : Foo>
And for `Qux`, they will be:
<Self where Self : Qux>
<Self where Self : Qux, Self : Baz, Self.X : Bar>
Note that the `Self.X : Foo` requirement is not listed.
For the moment, this is unused except for `-debug-generic-signatures`.
SIL Location diagnostics point at the getLoc, so when the EqualLoc is invalid we get no loc, while the startLoc is a fine alternative for these types of diagnostics.
This is only enabled when semantic sil is enabled /and/ we are not parsing
unqualified SIL.
*NOTE* To properly write tests for this, I had to rework how we verified
Branch/CondBranch insts to be actually correct (instead of pseudo-correct). I
have to put this functionality together in order to write tests.
rdar://29791263