This gives big code size wins for unused types and also for types, which are never used in a generic context.
Also it reduces the amount of symbols in the symbol table.
The size wins heavily depend on the project. I have seen binary size reductions from 0 to 20% on real world projects.
rdar://problem/30119960
This is NFC in intent, but I had to restructure the code to emit more
of the lists "inline", which means I inevitably altered some IRGen
emission patterns in ways that are visible to tests:
- GenClass emits property/ivar/whatever descriptors in a somewhat
different order.
- An ext method type list is now emitted as just an array, not a struct
containing only that array.
- Protocol descriptors are no longer emitted as packed structs.
I was sorely tempted to stop using packed structs for all the metadata
emission, but didn't really want to update that many tests in one go.
to correctly handle generalized protocol requirements.
The major missing pieces here are that the conformance search
algorithms in both the AST (type substitution) and IRGen
(witness table reference emission) need to be rewritten to
back-track requirement sources, and the AST needs to actually
represent this stuff in NormalProtocolConformances instead
of just doing ???.
The new generality isn't tested yet; I'm looking into that,
but I wanted to get the abstractions in place first.
This was an unnecessary complication and didn't make a lot of
logical sense, because we can recover the witness table from
substitutions when we call a @convention(witness_method) anyway.
Also, to fix materializeForSet for generic subscripts, I want the
materializeForSet *callback* of a protocol witness to have
@convention(witness_method), which requires representing such
functions as a single function pointer in IRGen.
The list of directly inherited protocols of a ProtocolDecl is already
encoded in the requirement signature, as conformance constraints where
the subject is Self. Gather the list from there rather than separately
computing/storing the list of "inherited protocols".
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.
When enumerating requirements, always use the archetype anchors to
express requirements. Unlike "representatives", which are simply there
to maintain the union-find data structure used to track equivalence
classes of potential archetypes, archetype anchors are the
ABI-stable canonical types within a fully-formed generic signature.
The test case churn comes from two places. First, while
representatives are *often* the same as the archetype anchors, they
aren't *always* the same. Where they differ, we'll see a change in
both the printed generic signature and, therefore, it's
mangling.
Additionally, requirement inference now takes much greater
care to make sure that the first types in the requirement follow
archetype anchor ordering, so actual conformance requirements occur in
the requirement list at the archetype anchor---not at the first type
that is equivalent to the anchor---which permits the simplification in
IRGen's emission of polymorphic arguments.
This commit introduces new kind of requirements: layout requirements.
This kind of requirements allows to expose that a type should satisfy certain layout properties, e.g. it should be a trivial type, have a given size and alignment, etc.
This is dead code and can be re-added if it is needed. Right now though there
really isnt a ValueOwnershipKind that corresponds to deallocating and I do not
want to add a new ValueOwnershipKind for dead code.
- The DeclContext versions of these methods have equivalents
on the DeclContext class; use them instead.
- The GenericEnvironment versions of these methods are now
static methods on the GenericEnvironment class. Note that
these are not made redundant by the instance methods on
GenericEnvironment, since the static methods can also be
called with a null GenericEnvironment, in which case they
just assert that the type is fully concrete.
- Remove some unnecessary #includes of ArchetypeBuilder.h
and GenericEnvironment.h. Now changes to these files
result in a lot less recompilation.
Changes:
* Terminate all namespaces with the correct closing comment.
* Make sure argument names in comments match the corresponding parameter name.
* Remove redundant get() calls on smart pointers.
* Prefer using "override" or "final" instead of "virtual". Remove "virtual" where appropriate.
Now that Optional's type parameter can be lowered, we can't make the assumption that a substituted nominal type in SIL is usable as-is as a formal type. At this moment, we can at least still rely on the fact that only nominals have methods, so we can at least go up to the original unsubstituted function type, extract the Self type from there, and do formal AST type substitution on it. This is still only a stopgap solution that wouldn't necessarily work once we start allowing conformances to be added to structural types, or even constrained extensions on Optional such as 'extension <T: class, U: class> Optional<(T) -> U>, but is good enough to fix SR-3021 for the language today. We would need something like the "substituted generic signature" concept to fully fix this.
Fixes rdar://problem/28873860, where we would miscompile when lightweight generic classes were extended to conform to Swift protocols because we tried to emit parameters for the class's generic parameters for the witness entry points. Prevent this by lowering the witness into a pseudogeneric function in SILGen, and teaching IRGen to do the right thing for a witness with pseudogeneric parameters.
We don't want the machine calling conventions for closure invocation functions to necessarily be tied to the convention for normal thin functions or methods. NFC yet; for now, 'closure' follows the same behavior as the 'method' convention, but as part of partial_apply simplification it will be a requirement that partial_apply takes a @convention(closure) function and a box and produces a @convention(thick) function from them.
basic block, revert to line number 0 instead of reusing the last location.
This avoids emitting illegal IR if there was no previous location and the
instruction being emitted is a function call.
rdar://problem/28237133
Now that the previous patches have shaken out implicit assumptions
about the order of generic requirements and substitutions, we can
make a more radical change, dropping redundant protocol requirements
when building the original generic signature.
This means that the canonical ordering and minimization that we
used to only perform when building the mangling signature is done
all of the time, and hence getCanonicalManglingSignature() can go
away.
Usages now either call getCanonicalSignature(), or operate on the
original signature directly.
When we call the DeclContext variants of these, use the
DeclContext's GenericEnvironment instead of GenericParamList.
Also, these functions would take a resolver argument, but we
always passed in nullptr, so just remove it now.
The old GenericParamList-based versions are still there
since they're called directly from SIL. They will go away
once SILFunction::ContextGenericParams is replaced with
a GenericEnvironment.
The self metadata in the changed method corresponds to the conforming type. For an inheritable conformance, that may be a subclass of the static type, and so the self metadata will be inexact. Currently, all conformances are inheritable.
rdar://27301453
When considering a type that declares an archetype bound to an
associated type, we were not generating the access paths to any
underlying conformance data and so were not properly able to grab the
witness table for those conformances resulting in a crash. This way,
all bound requirements also make sure to bind archetype access paths so
we can see actually see the conformances.
If the conformance in a witness_method instruction represented a derived protocol instead of the exact protocol of the desired method, we would crash. Handle this by drilling down to the exact conformance needed before forming a witness ref. Fixes rdar://problem/26633668.
not have access to their type arguments at runtime. Use this to
fix the emission of native thunks for imported ObjC-generic
initializers, since they may need to perform bridging.
For now, pseudo-genericity is all-or-nothing, but we may want to
make it apply only to certain type arguments.
Also, clean up some code that was using dead mangling nodes.
It can end up in having duplicate sumbols for generated associated type metadata access functions. rdar://problem/26360504
Also, it is not a big benefit for LLVM to emit such witness tables.