Commit Graph

397 Commits

Author SHA1 Message Date
John McCall
422df2e3bb Use the first element of an enum as a source for
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
2014-05-02 10:29:53 +00:00
Joe Groff
c0202d4fc2 IRGen: Push an 'isBitwiseTakable' bit through type infos.
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
2014-04-25 03:06:46 +00:00
Doug Gregor
09797f7f99 Introduce a new declaration node, ParamDecl, for function parameters.
Use this node to capture the argument name and its source location in
the AST. We're only building these in one place at the moment; the
rest will be updated soon.


Swift SVN r16581
2014-04-20 05:23:35 +00:00
John McCall
46d35ed288 Change the layout of class existentials to put the instance
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
2014-04-12 02:13:16 +00:00
Joe Groff
2189947cb0 Use report_fatal_error instead of exit(1) after unrecoverable problems in SILGen or IRGen.
Swift SVN r16059
2014-04-08 17:33:21 +00:00
Joe Pamer
f83f94d9d8 Support build and target configurations
These changes add support for build and target configurations in the compiler.
Build and target configurations, combined with the use of #if/#else/#endif allow
for conditional compilation within declaration and statement contexts.

Build configurations can be passed into the compiler via the new '-D' flag, or
set within the LangOptions class. Target configurations are implicit, and
currently only "os" and "arch" are supported.

Swift SVN r14305
2014-02-24 18:16:48 +00:00
Joe Groff
3951e6d460 IRGen: Reenable retain/release optimization of enums with all-refcounted payloads.
r12934 solved the memory corruption issues applying this optimization for String, so now we get a nice branchless implementation of its release operation:

__TwxxOVSs16ContiguousString5Owner:
00000000000828f0        pushq   %rbp
00000000000828f1        movq    %rsp, %rbp
00000000000828f4        movabsq $0x9fffffffffffffff, %rax
00000000000828fe        andq    (%rdi), %rax
0000000000082901        movq    %rax, %rdi
0000000000082904        popq    %rbp
0000000000082905        jmpq    0x881d0

Swift SVN r12937
2014-01-24 22:02:09 +00:00
Chris Lattner
f5b85341a1 Expand out the "isComputed" property in AbstractStorageDecl to be an enum
with two kinds, and some more specific predicates that clients can use.

The notion of 'computed or not' isn't specific enough for how properties
are accessed.  We already have problems with ObjC properties that are 
stored but usually accessed through getters and setters, and a bool here
isn't helping matters.

NFC.



Swift SVN r12593
2014-01-20 18:16:30 +00:00
Joe Groff
70d725717b IRGen: Disable the mask-and-retain optimization for mixed Swift/ObjC enums.
Retaining and releasing String's HeapBuffer with objc_retain/objc_release is causing mysterious heap corruption issues I haven't been able to sort out. Turn this off so it doesn't bite other people before we sort it out.

Swift SVN r12465
2014-01-17 05:39:58 +00:00
Joe Groff
5d6a6f6d38 IRGen: Favor high bits when scavenging tag bits for enums.
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
2014-01-16 23:57:04 +00:00
Joe Groff
0c20833d5f IRGen: Optimize copy/destroy of ObjC tagged or nullable enums too.
Rename TypeInfo::isSingleRetainablePointer to TypeInfo::isSingleSwiftRetainablePointer, and add an isSingleUnknownRetainablePointer entry point to ask whether a type has any single-refcounted representation, native or not. Use that to provide the same nullable-pointer and pointer-with-tag optimizations for copying and destroying enums with ObjC payloads as we do for Swift class payloads.

Swift SVN r12410
2014-01-16 19:08:01 +00:00
Joe Groff
5c52579cf1 IRGen: When an enum has all refcounted payloads, emit mask-and-retain/release.
We can copy and destroy enum values where all of the payloads are references by just masking out the tag bits and handing the pointer to swift_retain/swift_release, instead of creating a diamond. This could be generalized to aggregate payloads that all have refcounted pointers in the same place, and to mixed ObjC/Swift refcounted pointers, but this covers the "easy" case we can do with the layout info IRGen already tracks.

Swift SVN r12405
2014-01-16 18:01:58 +00:00
John McCall
a1b469ed2f ExplosionKind -> ResilienceExpansion. NFC.
Swift SVN r12364
2014-01-16 00:25:29 +00:00
Joe Groff
03011aaf93 IRGen: Improve EnumImplStrategy's layout querying functionality with feedback from Enrico.
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
2014-01-15 05:11:25 +00:00
Joe Groff
13d291e92c Fix up include order dependencies in IRGen's GenEnum.h.
Swift SVN r12304
2014-01-15 00:34:18 +00:00
Joe Groff
5b99962f1e IRGen: Expose APIs for asking about enum layout.
Export EnumImplStrategy from the GenEnum.h header, and add some accessors that LLDB or other interested parties can use to work out how an enum is laid out:

- getElementsWithPayload() and getElementsWithNoPayload(), to pick out the cases that were laid out as nonempty and empty (including those that are considered no-payload due to empty type optimization);

- getBitPatternForNoPayloadElement() to return the unique bit pattern representing a no-payload case; and

- getTagBitsForPayloads() to return the bitmask of the discriminator tag for payload cases.

Swift SVN r12269
2014-01-14 02:08:51 +00:00
Joe Groff
4488d269a3 IRGen: Forward spare bits through nested enums.
Offer spare bits unused by a multi-payload enum to outer enums for tag bit layout. Additionally, if an enum spills tag bits, offer the unused bits in that extra tag byte as spare bits as well. This lets us recover the last spilled bit in String, getting it down to an optimal-for-its-current-definition 32 bytes.

Swift SVN r12192
2014-01-11 02:03:11 +00:00
Joe Groff
9b38c4b5db IRGen: Forward spare bits through aggregates.
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
2014-01-10 23:15:34 +00:00
Joe Groff
5e5f31d5e3 IRGen: Share TypeInfo among equivalent generic instantiations, take 2.
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
2014-01-10 05:25:45 +00:00
Joe Groff
97ff9e47a8 Revert "IRGen: Share TypeInfo among equivalent generic instantiations."
This reverts commit r12112. It gives the buildbot indigestion.

Swift SVN r12113
2014-01-10 03:22:53 +00:00
Joe Groff
57cacbfe38 IRGen: Share TypeInfo among equivalent generic instantiations.
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
2014-01-10 02:02:58 +00:00
Joe Groff
4b94053e61 IRGen: Don't align the tag bits of multi-payload enums.
It's wasteful and doesn't match the IR we actually emit for switching and injecting multi-payload enums. Fixes <rdar://problem/15759464>.

Swift SVN r12055
2014-01-08 06:28:10 +00:00
Joe Groff
8f6a58b998 SIL: Split address-only enum dispatch from destructive projection.
Split 'destructive_switch_enum_addr' into separate 'switch_enum_addr' and 'take_enum_data_addr' instructions. This should unblock some optimization work we would like to do with enums.

Swift SVN r12015
2014-01-07 22:58:21 +00:00
Joe Groff
530e948cb2 SIL: Rename 'enum_data_addr' to 'init_enum_data_addr'.
Emphasize the fact that this address is only intended for initialization. When we split destructive_switch_enum_addr, there will be another similar instruction for destructively taking the payload out of an already-initialized enum.

Swift SVN r12000
2014-01-07 18:40:00 +00:00
Connor Wakamo
3e81830385 Move "include/swift/IRGen/Options.h" to "include/swift/AST/IRGenOptions.h".
This commit only moves the header file; updating the class so that it is no longer in the irgen namespace will be handled separately.

Swift SVN r11404
2013-12-18 01:17:09 +00:00
John McCall
4bba9b38f8 Make several new interfaces traffic in AbstractionPatterns.
Swift SVN r10621
2013-11-21 02:19:46 +00:00
John McCall
20e58dcf93 Change the type of function values in SIL to SILFunctionType.
Perform major abstraction remappings in SILGen.  Introduce
thunking functions as necessary to map between abstraction
patterns.

Swift SVN r10562
2013-11-19 22:55:09 +00:00
Joe Groff
934f02f8df Remove unnecessary #include.
Swift SVN r10557
2013-11-19 16:35:01 +00:00
Joe Groff
5caa24ae51 IRGen: Use swift_retain/swift_release directly for T? value semantics.
A single-payload enum with a single-refcounted-pointer payload and a single empty case will use a nullable pointer representation, which can be handled directly by swift_retain and swift_release. Take advantage of this to avoid some branching when copying or destroying values of this shape, such as T? for class T.

Swift SVN r10556
2013-11-19 16:32:26 +00:00
John McCall
93dfaa6bf4 Make everything getting a TypeInfo declare whether it's
working with a SIL-lowered or SIL-unlowered type.

Swift SVN r10067
2013-11-09 01:41:16 +00:00
Joe Groff
554abf2d7a IRGen/Runtime: Expose extra inhabitants of class types.
Start using null-page values as extra inhabitants when laying out single-payload enums that contain class pointers as their payload type. Don't use inhabitants that set the lowest bit, to avoid trampling potential ObjC tagged pointer representations. This means that 'T?' for class type T now has a null pointer representation. Enums with multiple empty cases, as well as nested enums like 'T??', should now have optimal representations for class type T as well.

Note that we don't yet expose extra inhabitants for aggregates that contain heap object references, such as structs with class fields, Swift function types, or class-bounded existentials (even when the existential has no witness tables).

Swift SVN r10061
2013-11-09 00:43:40 +00:00
Joe Groff
7b610ae55b IRGen: Don't round payload size up to alignment for single-payload enums.
We pack the tag for a single-payload enum into the padding space. Fixes one of the test cases in <rdar://problem/15410780>.

Swift SVN r10021
2013-11-07 04:25:13 +00:00
Joe Groff
aee4eefe81 IRGen: Emit metadata for imported NS_ENUMs.
Also, the extra inhabitant lookup for native Swift no-payload enums is inappropriate for C enums. For now, expose no extra inhabitants from C enums.

Swift SVN r10006
2013-11-06 21:45:53 +00:00
Joe Groff
e68fe3e238 IRGen: Fix up raw value evaluation for Clang-imported enums.
Use IntegerLiteralExpr's own parsing instead of APInt::fromString so we properly parse the literal string in the expr node.

Swift SVN r9991
2013-11-06 06:31:30 +00:00
Joe Groff
c5305f3e60 IRGen: Lay out enums from Clang with C-compatible layout.
Borrow the scalar type of the raw type as the representation type of C enums, and use the raw values from C as the discriminator values of the cases.

Swift SVN r9988
2013-11-06 05:54:17 +00:00
Joe Groff
9b3ca11639 IRGen: Fix leak when destroying dependent generic single-payload enum.
The payload type of a dependent single-payload enum is "empty" but we still need to run its destructor. Oops. Fixes <rdar://problem/15383966>.

Swift SVN r9932
2013-11-04 22:31:10 +00:00
Joe Groff
6676690ad2 IRGen: Handle single-payload enums with empty payload.
This arises when a generic single-payload type is instantiated on an empty type, such as '()?'.

Swift SVN r9609
2013-10-23 00:41:44 +00:00
Joe Groff
fe37b82a0b IRGen: Rename TypeInfo::initializeValueWitnessTable to initializeMetadata.
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
2013-10-09 22:40:28 +00:00
Joe Groff
50c7f54f07 IRGen: Anonymize EnumImplStrategy; it's a detail of GenEnum.cpp.
Swift SVN r9059
2013-10-09 15:31:49 +00:00
Joe Groff
99a0c64b5a IRGen: More robustly lay out enums with payloads.
John noted that LLVM's ABI rules for Integers of Unusual Size cause them to be aligned like the largest native integer type even inside packed structs, making them unsuited for byte-accurate layout in cases where the payload is a non-power-of-two size, so we have to bite the bullet and lay them out as arrays of i8, bitcasting to the payload type to load and store the payload and tag parts.

This still colors outside of the lines a bit because loading or storing e.g. an i72 is going to touch an i128's worth of memory. Baby steps. It'd be nice to be able to load and reconsistute the i72 without having to load and mask together all of the individual bytes.

Swift SVN r9058
2013-10-09 05:07:51 +00:00
Joe Groff
2ac198d16b IRGen: Use packed structs to accurately lay out aggregate types.
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
2013-10-09 04:12:46 +00:00
Joe Groff
3eb220da26 IRGen: Fix layout bug with payloaded enums.
If the enum gets laid out with a non-power-of-two payload and an extra tag, such as { i72, i2 }, then LLVM's natural location for the extra tag is going to be different from where we actually want it, so let's do our own byte offset calculation by bitcasting to i8* and gepping instead of trying to gep the struct directly.

Swift SVN r9023
2013-10-08 04:34:42 +00:00
Joe Groff
ae00d91bb1 IRGen: Remove needless empty enum assertion.
Swift SVN r8774
2013-09-30 15:22:52 +00:00
Jordan Rose
e05c03d5bc Standardize terminology for "computed", "stored", "variable", and "property".
These are the terms sent out in the proposal last week and described in
StoredAndComputedVariables.rst.

variable
  anything declared with 'var'
member variable
  a variable inside a nominal type (may be an instance variable or not)
property
  another term for "member variable"
computed variable
  a variable with a custom getter or setter
stored variable
  a variable with backing storage; any non-computed variable

These terms pre-exist in SIL and IRGen, so I only attempted to solidify
their definitions. Other than the use of "field" for "tuple element",
none of these should be exposed to users.

field
  a tuple element, or
  the underlying storage for a stored variable in a struct or class
physical
  describes an entity whose value can be accessed directly
logical
  describes an entity whose value must be accessed through some accessor

Swift SVN r8698
2013-09-26 18:50:44 +00:00
John McCall
ac290b2563 Don't claim all the elements from an explosion; we might be
getting used recursively.

Swift SVN r8534
2013-09-20 23:33:38 +00:00
Joe Groff
5d8a7ff9e7 Allow multiple comma-separated enum elements in a 'case' decl.
Introduce an EnumCaseDecl for source fidelity to track the 'case' location and ordering of EnumElementDecls. Parse a comma-separated list of EnumElementDecls after a 'case' token.

Swift SVN r8509
2013-09-20 19:51:13 +00:00
Joe Groff
e109124186 Replace 'union' keyword with 'enum'.
This only touches the compiler and tests. Doc updates to follow.

Swift SVN r8478
2013-09-20 01:33:14 +00:00