The type info for a class described its layout using a combination of a
StructLayout and ClassLayout, with different information stored in both.
Since we never use a class as a struct, it's simpler to add the relevant
bits to ClassLayout, and not build a StructLayout at all.
Also, drop inherited properties from the ClassLayout -- they're no
longer needed.
This is an error introduced as the result of a refactoring a while ago
and means that we will store dependently typed stored properties at the
wrong offset in a generic struct if it has stored properties of empty
types before said property.
rdar://36384871
We would lay out all classes starting with a Swift-style two-word header, even classes that inherit NSObject and therefore don't have Swift refcounting. The ObjC runtime would slide our ivars down for us at realization time, but it's nice to avoid unnecessarily dirtying memory in the not-uncommon case of direct NSObject subclasses.
Give empty fields a notional byte offset so we can still use the offset of the first field as an approximation of the instanceStart of a class.
Fixes SR-1055.
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.
John and I discussed this and agreed that we only need two cases here,
not four. In the future this may be merged with ResilienceExpansion,
and become a struct with additional availability information, but
we're definitely sure we don't need four levels here.
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
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
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
We need these for dependent-layout generic classes so we know the allocation/deallocation size and alignment. When I figure out ObjC interop with generic subclasses these should move to the rodata so they get handled resiliently by the ObjC runtime, but for generic class bringup this is convenient.
Swift SVN r9249
LLVM's normal data layout doesn't jive with our own StructLayout's more aggressive use of padding space, and causes problems such as <rdar://problem/14336903>. Because we do our own alignment and stride management, we can safely use LLVM packed struct types with manual padding to get the level of control we need to accurately reflect our desired struct layout.
Swift SVN r9056
{ %swift.opaque } freaks out InstCombine and other optimization passes. Just leave opaque types out of the struct type, even if they appear first in the layout.
Swift SVN r5066
of a GEP.
LLVM does not permit GEPs over unsized types, even if the index
is a constant zero.
This makes simple code involving generic tuples work.
Swift SVN r4969
handling non-fixed layouts.
This uncovered a bug where we weren't rounding up the header
size to the element alignment when allocating an array of archetypes.
Writing up a detailed test case for *that* revealed that we were
never initializing the length field of heap arrays. Fixing that
caused a bunch of tests to crash trying to release stuff. So...
I've left this in a workaround state right now because I have to
catch a plane.
Swift SVN r4804
I had thought that we could get away with letting the
runtime figure out that these offsets were invalid (and
thus recompute them), but it turns out that the runtime
has some basic consistency requirements: basically, it
expects the ivars to have been correctly laid out, and
it merely slides them around according to the layout of
the superclass.
Swift SVN r3747
The test changes are that we're setting a class body on
some types that we weren't before. For some of these,
this is okay; for others, it's more questionable, but
ultimately not *harmful*.
Swift SVN r3746
The motivations here are that (1) the parametric types
that actually need the 'self' argument don't necessarily
all want to do what tuples do and put the VWT relative
to the metatype at some definable offset and (2)
recovering type parameters from the metatype is much
better defined than also hopping some relationship back.
Plus this allows VWTs to be shared across instances of
generic types. Also, I'm going to need to add a VW
that takes a metatype, and consistency seems right here.
If keeping two values live is actually punishing, I
might have to reconsider this. But the VWT is at least
always recoverable from the metatype, so....
I ended up abstracting the thing that GenHeap was doing
in order to save archetypes for arrays, because I
needed it to save metatypes instead of VWTs and because
it really needed abstractin'.
Swift SVN r3096
Mangling is still a hack, pending a better type AST. Fixed
a bug where arguments passed indirectly were not being destroyed
by the callee (when passed by value). Changed some of the protocol
signatures to use the generic opaque pointer type, making the
types a bit more self-documenting in the IR.
Swift SVN r2274
It does seem silly for this to all be templated, but I couldn't
really see a very elegant solution given how I wanted things to
be genericized.
...interestingly, a ?t.t[] type would have done nicely for some
of this.
Swift SVN r1807
heap allocations it makes, and switch swift_alloc over to pass
that pointer in as well as the alignment. Also, compute
whether a type is POD during its generation and cache that in
the object, and introduce a method on TypeInfo to destroy an
object in memory.
Swift SVN r1356