-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Generic metadata prespecialization, part 1 #28610
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generic metadata prespecialization, part 1 #28610
Conversation
@swift-ci please test |
Build failed |
e5ebb66
to
952248a
Compare
@swift-ci please test |
Build failed |
Build failed |
952248a
to
1c3e71c
Compare
@swift-ci please test |
Build failed |
Build failed |
@swift-ci please test |
Build failed |
7d00476
to
8a0ab08
Compare
@swift-ci please test |
Build failed |
Build failed |
8a0ab08
to
76124ba
Compare
@swift-ci please test os x platform |
Build failed |
@swift-ci please smoke test os x platform |
b5496df
to
c188697
Compare
@swift-ci please test |
Build failed |
Build failed |
Added a new flag to the GenericMetadataPatternFlags flagset for whether the metadata has a set of flags at its tail. When that flag is set, there will be an extra uint64_t flagset at the end of the metadata. For struct metadata, the type of that flagset will be StructMetadataTrailingFlags. The first flag in that trailing flagset indicates whether the metadata was statically specialized. The second flag in that trailing flagset indicates whether the metadata is statically canonical. When verifying the metadata cache, a check is done for whether the metadata was statically specialized and whether it was known to be canonical statically. If so, verification is skipped. Skipping it is necessary because the known-canonical statically specialized metadata will not be in the cache. In that case, the canonical statically specialized metadata will be returned from the metadata accessor and never be cached.
Previously, the various generic builders implemented the methods addGenericArgument and addGenericWitnessTable without being provided what argument or witness table they were to add (because it was not previously needed). Now, the GenericRequirement is passed along to both methods.
The new frontend flag -prespecialize-generic-metadata must be passed in order for generic metadata to be specialized statically. rdar://problem/56984885
Compatibility with earlier swift runtimes would require modifying the runtime compatibility libraries to adjust the behavior of checkMetadataState by way of typeForMangledNode or even typeForMangledName. For now, simply require that a version of swift whose runtime knows about prespecialized metadata is being targeted.
When emitting a reference to the metadata for a generic type, prepare to, rather than always inserting calls to the type metadata access function, emit direct references to static specializations when possible and emit calls to the forthcoming swift_getCanonicalSpecializedMetadata when not possible. For now, the metadata access function is always called.
Added worklist of prespecializations awaiting lazy emission to IRGenModule. Added map from type decl to list of bound types for which prespecializations will be emitted. For now, no specializations are emitted.
For every prespecialization of generic metadata that exists in the module where the generic type is defined, the metadata accessor gains code with the following effect switch arguments { case prespecialization1.genericArguments: return prespecialization1 case prespecialization2.genericArguments: return prespecialization2 ... default: return swift_getGenericMetadata(...) } rdar://problem/56961700
Prespecialized records contain direct references to the generic arguments and protocol witnesses with which it is specialized for now. Both prespecialized records and the records that are specialized at runtime gain a trailing pointer-sized flagset. For now, the flags in it include whether the record was prespecialized and whether it was known to be canonical at compile time (which is true for prespecialized records within the module which defines the type whose metadata is specialized since in those cases the metadata accessor can be modified). rdar://problem/56960307
When possible, directly reference metadata prespecializations. Doing so is possible when the type is defined in the same module, because in those cases the metadata accessor can be modified to ensure that the prespecialized metadata is canonical. rdar://problem/56994171
Metadata accessors are dependent on prespecializations of the metadata of generic, in-module types. Those prespecializations are themselves dependent on usages of the types in functions. Consequently, the accessors must be emitted after all the functions are emitted.
The usages of a type that happen to be made in a module are implementation details of that module and should not be exported.
Prespecialized metadata records must refer to value witness tables that have correct values for size and stride. In order to do that, a prespecialized value witness table must emitted and referred to. Here, a fully specialized value witness table is emitted. For the moment, the value witness table is fully specialized. Having it be specialized, though, will likely cause serious code size problems, since it results in specialized value witness functions being generated. rdar://problem/58088270
ab7acac
to
d78dc03
Compare
@swift-ci please test |
Build failed |
Build failed |
@swift-ci please test source compatibility |
@swift-ci please test linux platform |
Build failed |
@swift-ci please clean test linux platform |
Build failed |
@swift-ci please clean test linux platform |
Initial support for compile-time specialization of generic metadata. The support here is very limited: static specializations are generated only for usages of generic structs which are defined in the same module as the use none of whose generic arguments are themselves generic. In these cases, a direct reference to the emitted static specialization is emitted into the using function. The metadata accessor is modified in order to make those static specializations canonical. The runtime has to be modified in order to avoid checking the cache for the specialization since the static specializations never make their way into the cache. Compatibility with old-runtimes, which will need a patched version of getTypeByMangledNode in order to avoid looking in the cache for statically specialized metadata, is not present yet. The feature is gated behind the -prespecialize-generic-metadata flag.