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
All llvm::Functions created during IRGen will have target-cpu and target-features
attributes if they are non-null.
Update testing cases to expect the attribute in function definition.
Add testing case function-target-features.swift to verify target-cpu and
target-features.
rdar://20772331
Swift SVN r28186
Store the number of payload and no-payload cases, the case names, and a lazy case type accessor function for enums, like we do for stored properties of structs and classes. This will be useful for multi-payload runtime support, and should also be enough info to hack together a reflection implementation for enums.
For dynamic multi-payload enums to not be ridiculously inefficient, we'll need to track the size of the payload area in the enum, like we do the field offsets of generic structs and classes, so hack off a byte in the payload case count to track the offset of that field in metadata records. 16 million payloads ought to be enough for anyone, right? (and 256 words between the enum metadata's address point and the payload size offset)
Swift SVN r27789
In particular, we reset the accumulated spare bit vector when we saw a class-constrained generic payload, which would cause the enum to be laid out with the incorrect payload size.
Swift SVN r27782
We have to guarantee memory safety in the presence of the user violating the
inout assumption. Claiming NoAlias for parameters that might alias is not
memory safe because LLVM will optimize based on that assumption.
Unfortunately, this means that llvm can't optimize arrays as aggressively. For
example, the load of array->buffer won't get hoisted out of loops (this is the
Sim2DArray regression below).
-O numbers (before/after):
CaptureProp 0.888365
Chars 1.09143
ImageProc 0.917197
InsertionSort 0.895204
JSONHelperDeserialize 0.909717
NSDictionaryCastToSwift 0.923466
Sim2DArray 0.76296
SwiftStructuresBubbleSort 0.897483
Continue emitting noalias for inout when compiling Ounchecked.
rdar://20041458
Swift SVN r25770
We still preserve IRGen's current ordering of vtable slots, but use SIL's record of which SILFunction implements which method instead of walking overrides independently. Another step on the way to rdar://problem/19321484; if SILGen determines that a thunk is needed to interface an override with its base method, IRGen will now pick it up. (Thunk generation is still busted in certain inheritance cases I need to fix before declaring victory though.)
Swift SVN r24732
Most tests were using %swift or similar substitutions, which did not
include the target triple and SDK. The driver was defaulting to the
host OS. Thus, we could not run the tests when the standard library was
not built for OS X.
Swift SVN r24504
terminators"
This is an assumption that the SSAUpdater makes. Verify that we preserve this
property.
With changes to the test cases, SIL documentation and add a critical edge (non
cond_br only) splitting pass to the mandatory pipeline.
This reapplies commit 22775.
Swift SVN r22803
existential (and existential metatype, and unowned
class existential) values when checking for extra
inhabitants. We don't guarantee the meaningfulness
of these bits.
Fixes rdar://17431105, where this showed up as
affecting correctness in debug vs. optimized builds.
Swift SVN r22608
unexpected forematter from the superclass.
This requires a pretty substantial shift in the
generic-metadata allocation/initialization dance
because (1) we can't allocate class metadata without
knowing what the superclass is and (2) the offset
from the metadata cache entry to the address point is
no longer determined solely by the metadata pattern.
While I'm making invasive changes to metadata, fix
two race conditions in metadata creation. The first
is that we need to ensure that only one thread succeeds
at lazily creating a generic-metadata cache. The second
is that we need to ensure that only one thread actually
attempts to create a particular metadata; any others
should block until the metadata is successfully built.
This commit finishes rdar://17776354. LLDB will
need to adjust to the runtime-private metadata layout
changes.
Swift SVN r20537
This only tackles the protocol case (<rdar://problem/17510790>); it
does not yet generalize to an arbitrary "class" requirement on either
existentials or generics.
Swift SVN r19896
Don't use spare bits on platforms that use ObjC tagged pointers when an enum payload involves a class-constrained existential, archetype, or ObjC-defined class type. If a payload is of a Swift-defined class type, we can still assume it's a real pointer and use its spare bits. Add an @unsafe_no_objc_tagged_pointer attribute that can be applied to protocols to denote that existentials bounded by that protocol can use spare bits; this is necessary to preserve the layout of bridged Array and Dictionary types, which should not be bound to tagged pointer types in practice (fingers crossed). Fixes <rdar://problem/16270219>.
Swift SVN r18781
We were miscalculating the number of empty-payload cases representable by each tag value and failing to lower cases after the first two. Fixes <rdar://problem/17025341>.
Swift SVN r18620
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
We really don't need to support individual objects
this large, much less more than 4 billion fields in
a single type.
Also rearrange the fields to bring the instance
size/alignment fields closer to the class header,
just for a minor locality win.
Swift SVN r16879
Add value witnesses for destroyArray, initializeArrayWithCopy, and initializeArrayWithTake{FrontToBack,BackToFront}, and fill out the runtime value witness table implementations. Stub out the IRGen ones for now.
Swift SVN r16772
This allows the payload for a loadable enum to be unsafely projected without branching, enabling more enum optimizations when switch branches can be culled or when indirect enum code can be promoted.
Swift SVN r16729
pointer first.
This most important effect of this is that accesses to that
field don't need to be dynamically offsetted past an arbitrary
number of value witnesses, which is pretty nice for the
generic value witnesses.
Swift SVN r16243
For example:
@class_protocol, @objc
is now just:
@class_protocol @objc
Once we removed attribute grouping in brackets this comma separation
became vestigial. Doug and I discussed this and thought this
was a good simplification in the grammar.
This change still remains to be done for type attributes.
Swift SVN r15540
As part of the nominal type descriptor for a struct or class, build a function that lazily generates the vector of type metadata for the fields of the nominal type given an instantiation of the type's metadata. To cache this for nongeneric types, produce a global variable we can stash the result in, or for generic types, reserve some space in the metadata template so that generic metadata instantiation naturally provides a space for every instance of the type.
Reapplying now that the missing Float80 builtin metadata is available.
Swift SVN r15260
As part of the nominal type descriptor for a struct or class, build a function that lazily generates the vector of type metadata for the fields of the nominal type given an instantiation of the type's metadata. To cache this for nongeneric types, produce a global variable we can stash the result in, or for generic types, reserve some space in the metadata template so that generic metadata instantiation naturally provides a space for every instance of the type.
Swift SVN r15256
-emit-llvm in Clang is a modifier on the -S and -c actions. In Swift,
it's a separate action equivalent to "-S -emit-llvm". Be less ambiguous.
Part of the migration to the new driver.
Swift SVN r13029
This is easier to emit optimal code for on our target platforms, and is more likely to find a contiguous range of spare bits to place the tag in.
Swift SVN r12435
It was convenient to just assume that the SILModule defines
the deallocating destructor function. This should probably
be represented somehow in e.g. the sil_vtable instead of
being an implicit dependency.
Swift SVN r12412
Only claim spare bits we actually use as tag bits in the result of getTagBitsForPayloadCases(), and fix up some crashers in corner cases. Add some assertions so these APIs get tested as part of normal compiler runs, and some DEBUG() macros so interested compiler users can see what enum layout is doing with -debug-only=enum-layout. This should also lead to slightly better codegen for some multi-payload enums because we don't pointlessly try to gather spare bits from the entire payload anymore, only the bits we actually need to discern the tag.
Swift SVN r12314