In a few places, we have to be careful about the distinction between
"empty in this resilience domain" versus "empty in all resilience
domains". Make callers think about this by adding a parameter instead
of relying on them to check isFixedSize() as necessary first.
While making this change I noticed that the code for checking if
types are empty when computing extra inhabitants of structs and enums
might be slightly wrong in the face of resilience; I will revisit
this later.
For example, if a @_fixed_layout struct A contains a resilient struct B
from the same module M, then inside M, A can have a fixed size, but
outside, A has a dynamic size because B is opaque. In this case, A is
not "universally fixed-size". This impacts multi-payload enums, because
if A is placed inside a multi-payload enum E which is lowered inside X,
we would get a fixed layout with spare bits, but lowering E outside of
X would yield a dynamic layout. This is incorrect.
Fix this by plumbing through a new predicate IsAlwaysFixedSize, which
is similar to IsPOD and IsBitwiseTakable, where a compound type inherits
the property if all leaf types exhibit it, and only use spare bits if
the original and substituted types have this property.
Using LLVM large integers to represent enum payloads has been causing compiler performance and code size problems with large types, and has also exposed a long tail of backend bugs. Replace them with an "EnumPayload" abstraction that manages breaking a large opaque binary value into chunks, along with masking, testing, and extracting typed data from the binary blob. For now, use a word-sized chunking schema always, though the architecture here is set up to eventually allow the use of an arbitrary explosion schema, which would benefit single-payload enums by allowing the payload to follow the explosion schema of the contained value.
This time, adjust the assertion in emitCompare not to perform a check before we've established that the payload is empty, since APInt doesn't have a 0-bit state and the default-constructed form is nondeterminisitic. (We should probably use a more-tailored representation for enum payload bit patterns than APInt or ClusteredBitVector.)
Swift SVN r28985
Using LLVM large integers to represent enum payloads has been causing compiler performance and code size problems with large types, and has also exposed a long tail of backend bugs. Replace them with an "EnumPayload" abstraction that manages breaking a large opaque binary value into chunks, along with masking, testing, and extracting typed data from the binary blob. For now, use a word-sized chunking schema always, though the architecture here is set up to eventually allow the use of an arbitrary explosion schema, which would benefit single-payload enums by allowing the payload to follow the explosion schema of the contained value.
Swift SVN r28982
This is an internal-only affordance for the numerics team to be able to work on SIMD-compatible types. For now, it can only increase alignment of fixed-layout structs and enums; dynamic layout, classes, and other obvious extensions are left to another day when we can design a proper layout control design.
Swift SVN r27323
Previously some parts of the compiler referred to them as "fields",
and most referred to them as "elements". Use the more generic 'elements'
nomenclature because that's what we refer to other things in the compiler
(e.g. the elements of a bracestmt).
At the same time, make the API better by providing "getElement" consistently
and using it, instead of getElements()[i].
NFC.
Swift SVN r26894
Sometimes these methods are overriding, sometimes they're not.
Unfortunately, there's not a very consistent solution, so just disable
the warning in these two .cpp files.
No functionality change.
Swift SVN r25604
IRGen uses a typedef, SpareBitVector, for its principal
purpose of tracking spare bits. Other uses should not
use this typedef, and I've tried to follow that, but I
did this rewrite mostly with sed and may have missed
some fixups.
This should be almost completely NFC. There may be
some subtle changes in spare bits for witness tables
and other off-beat pointer types. I also fixed a bug
where IRGen thought that thin functions were two
pointers wide, but this wouldn't have affected anything
because we never store thin functions anyway, since
they're not a valid AST type.
This commit repplies r24305 with two fixes:
- It fixes the computation of spare bits for unusual
integer types to use the already-agreed-upon type
size instead of recomputing it. This fixes the
i386 stdlib build. Joe and I agreed that we should
also change the size to use the LLVM alloc size
instead of the next power of 2, but this patch
does not do that yet.
- It changes the spare bits in function types back
to the empty set. I'll be changing this in a
follow-up, but it needs to be tied to runtime
changes. This fixes the regression test failures.
Swift SVN r24324
IRGen uses a typedef, SpareBitVector, for its principal
purpose of tracking spare bits. Other uses should not
use this typedef, and I've tried to follow that, but I
did this rewrite mostly with sed and may have missed
some fixups.
This should be almost completely NFC. There may be
some subtle changes in spare bits for witness tables
and other off-beat pointer types. I also fixed a bug
where IRGen thought that thin functions were two
pointers wide, but this wouldn't have affected anything
because we never store thin functions anyway, since
they're not a valid AST type.
Swift SVN r24305
llvm::Optional lives in "llvm/ADT/Optional.h". Like Clang, we can get
Optional in the 'swift' namespace by including "swift/Basic/LLVM.h".
We're now fully switched over to llvm::Optional!
Swift SVN r22477
- A spot fix in SILGen for reabstracting the result of a downcast, which fixes checked casts to function types.
- Associate the layout information in type metadata records with the most abstract representation of the type. This is the correct thing to do in cases where we need the metadata as a tag for an opaque value--if we store a value in an Any, or pass it as an unconstrained generic parameter, we must maximally reabstract it. This fixes the value semantics of existentials containing trivial metatypes.
- To ensure that we get runtime layout of structs and enums correct when they contain reabstractable types, introduce a "metadata for layout" concept, which doesn't need to describe the canonical metadata for the type, but only needs to describe a type with equivalent layout and value semantics. This is a correctness fix that allows us to correctly lay out generic types containing dependent tuples and functions, and although we don't really take advantage of it here, it's also a potential runtime performance win down the road, because we could potentially produce direct metadata for a primitive type that's layout-equivalent with a runtime-instantiated type. To aid in type safety here, push SILType deeper into IRGen in places where we potentially care about specific representations of types.
- Finally, fix an inconsistency between the runtime and IRGen's concept of what spare bits unmanaged references and thick metatypes have.
Together, these fixes address rdar://problem/16406907, rdar://problem/17822208, rdar://problem/18189508, and likely many other related issues, and also fixes crash suite cases 012 and 024.
Swift SVN r21963
If a type has to be passed or returned resiliently, it
will necessarily be passed indirectly, which is already
represented in SILFunctionType. There is no need to
represent this as a separate channel of information.
NFC. Also fixes a problem where the signature cache
for ExtraData::Block was writing past the end of an
array (but into the storage for an adjacent array
which was fortunately never used).
ExtraData should also disappear as a concept, but we're
still relying on that for existential protocol witnesses.
Swift SVN r21548
LLDB needs this in order to accurately test enums that use extra inhabitants of aggregates, for which we don't guarantee that we set all of the bits to an exact value. Allows lldb to address <rdar://problem/17787682>. Now with no test crashes.
Swift SVN r20545
LLDB needs this in order to accurately test enums that use extra inhabitants of aggregates, for which we don't guarantee that we set all of the bits to an exact value. Allows lldb to address <rdar://problem/17787682>.
Swift SVN r20527
for extra inhabitants.
For structs in particular, this eliminates a major source
of abstraction penatlies. For example, an optional struct
containing an object pointer is now represented the same
way as an optional object pointer, which is critical for
correctly importing CF types as Unmanaged<T>!.
In time, we should generalize this to consider all elements
as sources for extra inhabitants, as well as exploiting
spare bits in the representation, but getting the
single-element case right really provides the bulk of the
benefit.
This commit restores r17242 and r17243 with a fix to use
value witnesses that actually forward the right type metadata
down. We were already generating these value witnesses in
the dependent struct VWT pattern, but I was being too clever
and trying to use the underlying value witness directly.
Swift SVN r17267
This reverts commit r17242. We can't simply forward tuple element extra
inhabitant witnesses for the same reason laid out in the previous commit.
Swift SVN r17252
This reverts commit r17243. We can't just forward the extra inhabitant payloads
from a field, because they will end up receiving metadata for the incorrect
type and crashing.
Swift SVN r17251
extra inhabitants.
Obviously this should eventually be generalized to
take from any element, but this is good enough to
give us zero-cost abstraction via single-field structs.
Contains some bugfixes for the tuple-extra-inhabitant
changes as well, because test coverage for optional
structs is obviously quite a bit richer than for
optional tuples.
All of this is leading towards unblocking IRGen for
importing CFStringRef as Unmanaged<CFString>!.
Swift SVN r17243
extra inhabitants.
This is obviously not as general as it should be,
but it actually helps a lot.
I started doing enums assuming it would teach me
something about how to do it for structs, and it
kindof worked.
Swift SVN r17242
In value witness table generation, and probably other places, we're inappropriately assuming that 'initializeWithTake' is equivalent to a memcpy in all cases, which isn't true for types that carry weak references or for potentially other types in the future. Add an 'isBitwiseTakable' property to TypeInfos that can be checked to see whether a type is bitwise-takable.
Swift SVN r16799
When doing struct layout for fixed-layout structs or tuples, combine the spare bit masks of their elements to form the spare bit mask of the aggregate, treating padding between elements as spare bits as well.
For now, disable using these spare bits to form extra inhabitants for structs and tuples; we would need additional runtime work to expose these extra inhabitants for correct generic runtime behavior. This puts us in a weird situation where 'enum { case A(Struct), B, C }' spills a bit but 'enum { case A(Struct), B(Struct), C }' doesn't, but the work to make the former happen isn't immediately critical for String optimization.
Swift SVN r12165
IRGen type conversion is invariant with respect to archetypes with the same set of constraints, so instead of redundantly generating a TypeInfo object and IR type for Optional<T> for every T everywhere, key TypeInfo objects using an "exemplar type" that we form using a folding set to collapse together archetypes with the same class-ness, superclass constraint, and protocol constraints.
This is a nice memory and IR size optimization, but will be essential for correctness when lowering interface types, because there is no unique context to ground a dependent type, and we need to lower the same generic parameter with the same context requirements to the same type whenever we instantiate it in order for the IR to type-check.
In this revision, we profile the nested archetypes of each recursively, which I neglected to take into account originally in r12112, causing failures when archetypes that differed by associated type constraints were incorrectly collapsed.
Swift SVN r12116
IRGen type conversion is invariant with respect to archetypes with the same set of constraints, so instead of redundantly generating a TypeInfo object and IR type for Optional<T> for every T everywhere, key TypeInfo objects using an "exemplar type" that we form using a folding set to collapse together archetypes with the same class-ness, superclass constraint, and protocol constraints.
This is a nice memory and IR size optimization, but will be essential for correctness when lowering interface types, because there is no unique context to ground a dependent type, and we need to lower the same generic parameter with the same context requirements to the same type whenever we instantiate it in order for the IR to type-check.
Swift SVN r12112
Its job will be a bit more broad for generic structs, where it needs to fill field offsets into the metadata in addition to storing the final size, stride, and alignment information to the value witness table.
Swift SVN r9104
For dynamic generic types, this emits the sequence of operations to turn a value witness table template into a full, valid value witness table. For now, leave it stubbed out as empty, except for dynamic singleton unions, where we copy the size, flags, and stride from the lone element's table.
Swift SVN r8014
Dynamic forms of these methods will ultimately move to the fully general TypeInfo class, but for now I'm focusing on getting fixed-layout unions working. Set up methods on FixedTypeInfo for getting the fixed count of extra inhabitants and the spare bit mask for a type. Have the default implementation of extra inhabitants count use the spare bits. For now, only actually set spare bits for types with IR-level single scalar non-power-of-two integer representation (e.g., i1, or i21).
Swift SVN r7289
the new LoadableTypeInfo refinement interface.
This protects against bugs which would introduce unbalanced
allocations of temporary memory.
Swift SVN r7227