Commit Graph

1047 Commits

Author SHA1 Message Date
Sean Callanan
09f48ee2b4 Revert "Runtime: Rename reportMissingMethod to deletedMethodError."
This reverts commit bdffe703b0.
Required to revert b1e3120a28.
2015-12-23 15:41:06 -08:00
Joe Groff
bdffe703b0 Runtime: Rename reportMissingMethod to deletedMethodError.
The runtime entry doesn't just report the error, unlike the other report* functions, it also does the crashing.
2015-12-23 09:17:07 -08:00
John McCall
b1e3120a28 Include access functions for the metadata and witness tables
of associated types in protocol witness tables.

We use the global access functions when the result isn't
dependent, and a simple accessor when the result can be cheaply
recovered from the conforming metadata.  Otherwise, we add a
cache slot to a private section of the witness table, forcing
an instantiation per conformance.  Like generic type metadata,
concrete instantiations of generic conformances are memoized.

There's a fair amount of code in this patch that can't be
dynamically tested at the moment because of the widespread
reliance on recursive expansion of archetypes / dependent
types.  That's something we're now theoretically in a position
to change, and as we do so, we'll test more of this code.
2015-12-23 00:37:24 -08:00
Dmitri Gribenko
6a66b3cff8 Merge pull request #561 from practicalswift/typos-again
[Typo] Replace PR#514-525 with one large PR
2015-12-18 03:37:02 -08:00
John McCall
d09e08454f Abstract FulfillmentMap a little bit better so that it can be
made to work on archetypes instead of interface types.  NFC.
2015-12-16 18:13:15 -08:00
practicalswift
8ab8847684 Fix typos. 2015-12-16 22:09:32 +01:00
John McCall
7f3e98ef9d Extract IRGen's fulfillments-search algorithm into a helper class. NFC. 2015-12-15 18:13:24 -08:00
Slava Pestov
65a5a03f26 IRGen: Add a new destructiveInjectEnumTag value witness function
This value witness function takes an address of an enum value where the
payload has already been initialized, together with a case index, and
forms the enum value.

The formal behavior can be thought of as satisfying an identity in
relation to the existing two enum value witnesses. For any enum
value, the following is to leave the value unchanged:

  tag = getEnumTag(value)
  destructiveProjectEnumData(value)
  destructiveInjectEnumData(value, tag)

This is the last missing piece for the inject_enum_addr SIL instruction
to handle resilient enums, allowing the implementation of an enum to be
decoupled from its uses. Also, it should be useful for dynamically
constructing enum cases with write reflection, once we get around to
doing such a thing.

The body of the value witness is emitted by a new emitStoreTag() method
on EnumImplStrategy. This is similar to the existing storeTag(), except
the case index is a value instead of a contant.

This is implemented as follows for the different enum strategies:

1) For enums consisting of a single case, this is trivial.

2) For enums where all cases are empty, stores the case index into the
   payload area.

3) For enums with a single payload case, emits a call to a runtime
   function. Note that for non-generic single payload enums, this could
   be open-coded more efficiently, but the function still has the
   correct behavior since it supports extra inhabitants and so on.
   A follow-up patch will make this more efficient.

4) For multi-payload enums, there are two cases:

   a) If one of the payloads is generic or resilient, the enum is
      dynamically-sized, and a call to a runtime function is emitted.

   b) If the entire enum is fixed-size, the value witness checks if
      the case is empty or not.

      If the case has a payload, the case index is swizzled into
      spare bits of the payload, if any, with remaining bits going
      into the extra tag area.

      If the case is empty, the case index is swizzled into the
      spare bits of the payload, the remaining bits of the payload,
      and the extra tag area.

The implementations of emitStoreTag() duplicate existing logic in the
enum strategies, in particular case 4)b) is rather complicated.

Code cleanups are welcome here!
2015-12-08 15:43:55 -08:00
Joe Groff
b1667ec705 SIL: Introduce a new @inout_aliasable parameter convention.
Modeling nonescaping captures as @inout parameters is wrong, because captures are allowed to share state, unlike 'inout' parameters, which are allowed to assume to some degree that there are no aliases during the parameter's scope. To model this, introduce a new @inout_aliasable parameter convention to indicate an indirect parameter that can be written to, not only by the current function, but by well-typed, well-synchronized aliasing accesses too. (This is unrelated to our discussions of adding a "type-unsafe-aliasable" annotation to pointer_to_address to allow for safe pointer punning.)
2015-12-08 14:35:47 -08:00
John McCall
4d1b6e2eb6 Reform the runtime interface for unowned reference-counting.
This is a bit of a hodge-podge of related changes that I decided
weren't quite worth teasing apart:

First, rename the weak{Retain,Release} entrypoints to
unowned{Retain,Release} to better reflect their actual use
from generated code.

Second, standardize the names of the rest of the entrypoints around
unowned{operation}.

Third, standardize IRGen's internal naming scheme and API for
reference-counting so that (1) there are generic functions for
emitting operations using a given reference-counting style and
(2) all operations explicitly call out the kind and style of
reference counting.

Finally, implement a number of new entrypoints for unknown unowned
reference-counting.  These entrypoints use a completely different
and incompatible scheme for working with ObjC references.  The
primary difference is that the new scheme abandons the flawed idea
(which I take responsibility for) that we can simulate an unowned
reference count for ObjC references, and instead moves towards an
address-only scheme when the reference might store an ObjC reference.
(The current implementation is still trivially takable, but that is
not something we should be relying on.)  These will be tested in a
follow-up commit.  For now, we still rely on the bad assumption of
reference-countability.
2015-12-04 13:18:14 -08:00
Slava Pestov
9ee10e7d39 IRGen: destructiveProjectEnumData() value witness doesn't need a return value
The rest of the runtime assumes the payload starts at the beginning
of the enum, so simplify some code by removing the return value here.
2015-11-30 13:32:55 -08:00
Slava Pestov
6c2d5b1b6c IRGen: GenEnum.cpp cleanups, NFC
- Better comment at top of file
- Factor out common projectDataForStore() and
  destructivelyProjectDataForLoad() implementations
- Formatting cleanups
2015-11-18 18:20:54 -08:00
Slava Pestov
1adf7534d7 IRGen: Collapse down ResilienceScope enum
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.
2015-11-13 17:56:17 -08:00
Michael Gottesman
9fb54bf4bf Fix for upstream ilist changes. 2015-11-11 16:07:41 -08:00
Chris Willmore
295a6b2580 [IRGen] Fix source list computation in PolymorphicConvention
Currently, a source for polymorphic parameter fulfillments is removed
from the source list if the size of the map of fulfillments does not
increase during its consideration. This isn't quite correct because it's
possible for a new fulfillment that uses the source to replace an
existing one without creating a new entry in the map. Have the code be
more explicit about the condition under which a source may be safely
discarded.

<rdar://problem/23121786> Crash emitting IR SIL function for Carthage

Swift SVN r32763
2015-10-19 20:46:24 +00:00
John McCall
76e324a950 Refactors leading towards the use of protocol witness table access functions.
This re-applies r32541 with a few changes to the demangling logic and associated test fixes.

Swift SVN r32553
2015-10-09 05:49:18 +00:00
Erik Eckstein
19bb23a63f Revert r32541 "Refactors leading towards the use of protocol witness table access functions."
It broke the build: 2 demangle tests failed.




Swift SVN r32552
2015-10-09 04:42:19 +00:00
John McCall
9af9b9914d Refactors leading towards the use of protocol witness table
access functions.  NFC for now.

Swift SVN r32541
2015-10-09 01:06:06 +00:00
John McCall
a945bacc6b Split GenProto.cpp into three files; NFC.
- GenProto.cpp for protocols and protocol conformances
  - GenExistential.cpp for existential type layout and operations
  - GenArchetype.cpp for archetype type layout and operations

Swift SVN r32493
2015-10-07 18:41:12 +00:00
John McCall
2d38e26eca Move IRGen's PolymorphicConvention off of ArchetypeBuilder and onto
direct queries against the GenericSignature.

Thanks to Doug for some fixes to GenericSignature and a lot of advice.

Swift SVN r32481
2015-10-07 00:44:09 +00:00
John McCall
6cc655cf8c Introduce a more general mechanism for metadata fulfillment
which allows the use of an arbitrary-length path.

Eventually, this will also allow us to be much lazier in IRGen
about actually materializing such information in a function;
but for now, leave the existing code-generation patterns intact.

Swift SVN r32454
2015-10-06 01:14:32 +00:00
Joe Groff
773eadb9f2 IRGen/Runtime: Populate the runtime protocol conformance table with relative references.
By using relative references, either directly to symbols internal to the current TU, or to the GOT entry for external symbols, we avoid unnecessary runtime relocations, and we save space on 64-bit platforms, since a single image is still <2GB in size. For the 64-bit standard library, this trades 26KB of fake-const data in __DATA,__swift1_proto for 13KB of true-const data in __TEXT,__swift2_proto. Implements rdar://problem/22334380.

Swift SVN r31555
2015-08-28 18:07:22 +00:00
Joe Groff
ec61fa4c5a IRGen/Runtime: Use only the 'layout' subset of the vwtable to perform value type layout.
Full type metadata isn't necessary to calculate the runtime layout of a dependent struct or enum; we only need the non-function data from the value witness table (size, alignment, extra inhabitant count, and POD/BT/etc. flags). This can be generated more efficiently than the type metadata for many types--if we know a specific instantiation is fixed-layout, we can regenerate the layout information, or if we know the type has the same layout as another well-known type, we can get the layout from a common value witness table. This breaks a deadlock in most (but not all) cases where a value type is recursive using classes or fixed-layout indirected structs like UnsafePointer. rdar://problem/19898165

This time, factor out the ObjC-dependent parts of the tests so they only run with ObjC interop.

Swift SVN r30266
2015-07-16 15:38:17 +00:00
Ted Kremenek
a3d88266b2 Revert "IRGen/Runtime: Use only the 'layout' subset of the vwtable to perform value type layout."
This reverts commit r30243.

This appears to be breaking the Linux build.

Swift SVN r30253
2015-07-16 06:28:24 +00:00
Joe Groff
2641d566ac IRGen/Runtime: Use only the 'layout' subset of the vwtable to perform value type layout.
Full type metadata isn't necessary to calculate the runtime layout of a dependent struct or enum; we only need the non-function data from the value witness table (size, alignment, extra inhabitant count, and POD/BT/etc. flags). This can be generated more efficiently than the type metadata for many types--if we know a specific instantiation is fixed-layout, we can regenerate the layout information, or if we know the type has the same layout as another well-known type, we can get the layout from a common value witness table. This breaks a deadlock in most (but not all) cases where a value type is recursive using classes or fixed-layout indirected structs like UnsafePointer. rdar://problem/19898165

Swift SVN r30243
2015-07-16 01:28:42 +00:00
Slava Pestov
cdd5a4121c IRGen: Generate value witnesses to get enum tag and project payload
These will be used for reflection, and eventually to speed up generic
operations on single payload enums as well.

Progress on <rdar://problem/21739870>.

Swift SVN r30214
2015-07-15 06:03:18 +00:00
Joe Groff
feebd56bf4 IRGen: Reorder the extra inhabitant value witnesses so that the count and flags go first.
This nicely gathers all the layout information together in one contiguous bundle we can potentially emit independently for use in generic type layout. A step on the way to rdar://problem/19898165.

Swift SVN r30128
2015-07-12 01:06:15 +00:00
Doug Gregor
3023a710fc Split TypeBase::isDependentType() into isTypeParameter() and hasTypeParameter().
The isDependentType() query is woefully misunderstood. Some places
seem to want it to mean "a generic type parameter of dependent member
type", which corresponds to what is effectively a type parameter in
the language, while others want it to mean "contains a type parameter
anywhere in the type". Tease out these two meanings in
isTypeParameter() and hasTypeParameter(), respectively, and sort out
the callers.

Swift SVN r29945
2015-07-07 21:20:54 +00:00
Slava Pestov
c033da92a4 IRGen: Implement emission of ExistentialMetatypeInst for boxed existentials
This is based on code from emitMetatypeOfOpaqueExistential() and
emitBoxedExistentialProjection().

Fixes <rdar://problem/21498036>.

Swift SVN r29735
2015-06-26 07:29:52 +00:00
Dmitri Hrybenko
2fc1cbe8c1 Adjust to the new IRBuilder APIs
Swift SVN r29692
2015-06-25 22:01:24 +00:00
Joe Groff
e57c470019 Introduce a "@box T" type for SIL.
Represents a heap allocation containing a value of type T, which we'll be able to use to represent the payloads of indirect enum cases, and also improve codegen of current boxes, which generates non-uniqued box metadata on every allocation, which is dumb. No codegen changes or IRGen support yet; that will come later.

This time, fix a paste-o that caused SILBlockStorageTypes to get replaced with SILBoxTypes during type substitution. Oops.

Swift SVN r29489
2015-06-18 15:21:52 +00:00
Mark Lacey
39087cd36b Revert "Introduce a "@box T" type for SIL."
This reverts commit r29474 because it looks like it is breaking the
build of the SpriteKit overlay.

Swift SVN r29482
2015-06-18 06:28:04 +00:00
Joe Groff
7b0045c790 Introduce a "@box T" type for SIL.
Represents a heap allocation containing a value of type T, which we'll be able to use to represent the payloads of indirect enum cases, and also improve codegen of current boxes, which generates non-uniqued box metadata on every allocation, which is dumb. No codegen changes or IRGen support yet; that will come later.

Swift SVN r29474
2015-06-18 04:07:03 +00:00
Slava Pestov
1052d095c4 Sema: Fixes for conformance between higher-kind metatypes
For a concrete type A and protocol type P, A <c P now implies
A.Type <c P.Type, not just A.Type < P.Type. This in turn means
that A.Type.Type <c P.Type.Type. To make the coercion work,
recursively peel off metatype layers when collecting conformances
and in a similar situation in IRGen.

Swift SVN r29377
2015-06-15 02:00:47 +00:00
Joe Groff
2852a3951f IRGen: Mark metadata loads as invariant.
And mark loads of the value witness table as dereferenceable, so that LLVM is able to better optimize metadata accesses.

Swift SVN r29372
2015-06-13 20:44:05 +00:00
Joe Groff
e22908f569 IRGen: Peephole (copy_addr to [initialization] (init_existential_addr)) as well.
We can simultaneously allocate and initialize an opaque existential container's fixed-size buffer the same way, which benefits conversions from generic types to protocol types.

Swift SVN r29371
2015-06-13 00:35:04 +00:00
Joe Groff
a321938d34 IRGen: Peephole (copy_addr to [initialization] (alloc_stack)) operations to use initializeBuffer value witnesses.
This saves a value witness call in the common case where a generic local variable or temporary is initialized from another value.

Swift SVN r29366
2015-06-12 16:59:14 +00:00
Slava Pestov
3330b5ed85 IRGen: Support polymorphic @objc_method functions
The type of the self parameter of an @objc_method might be a
BoundGenericClassType or a GenericTypeParamType. In these cases
we have to bind metadata.

For an @objc protocol P, the calling convention for an existential P
would try to pass type metadata in an extra argument, just like it
would for a <T : P> T. However, it is only necessary in the latter
case, because only there we can reflect on T to observe the statically
bound generic type. Fix this with a small hack so that ObjC protocol
methods don't get an extra argument for Self.

This patch alone doesn't enable any new functionality by itself,
because we hit the 'unimplemented dynamic layout' error instead of
crashing.

Swift SVN r29258
2015-06-03 00:01:22 +00:00
Ted Kremenek
a154ae25f8 Revert "Revert "Revert "IRGen: Support polymorphic @objc_method functions"""
I didn't revert in the right order.

Swift SVN r29152
2015-05-29 19:16:32 +00:00
Ted Kremenek
7c24079ead Revert "Revert "IRGen: Support polymorphic @objc_method functions""
Start reverting 'reverts' incrementally to see if they trigger issues
on the iOS builder.

Swift SVN r29151
2015-05-29 18:38:12 +00:00
Ted Kremenek
ac40accfc1 Revert "IRGen: Support polymorphic @objc_method functions"
Speculatively reverting because the iOS bots are broken.

Swift SVN r29147
2015-05-29 14:11:29 +00:00
Slava Pestov
70db2c18d1 IRGen: Support polymorphic @objc_method functions
The type of the self parameter of an @objc_method might be a
BoundGenericClassType or a GenericTypeParamType. In these cases
we have to bind metadata.

For an @objc protocol P, the calling convention for an existential P
would try to pass type metadata in an extra argument, just like it
would for a <T : P> T. However, it is only necessary in the latter
case, because only there we can reflect on T to observe the statically
bound generic type. Fix this with a small hack so that ObjC protocol
methods don't get an extra argument for Self.

This patch alone doesn't enable any new functionality by itself,
because we hit the 'unimplemented dynamic layout' error instead of
crashing.

Swift SVN r29136
2015-05-29 06:19:00 +00:00
Joe Groff
79dc6db4bb IRGen: Redesign enum codegen to break payloads into word-sized chunks.
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
2015-05-24 16:20:21 +00:00
Ted Kremenek
bbf61217cd Revert "IRGen: Redesign enum codegen to break payloads into word-sized chunks."
This is asserting on the bots:

Assertion failed: ((~mask & value) == 0 && "value has masked out bits set?!"), function emitCompare

Swift SVN r28983
2015-05-24 05:38:53 +00:00
Joe Groff
3691991374 IRGen: Redesign enum codegen to break payloads into word-sized chunks.
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
2015-05-24 05:23:23 +00:00
Slava Pestov
419ad24e09 IRGen: don't consider @objc protocols when looking for a path
If we had a protocol P that refines <Q, R> and R was @objc, we would
crash when looking for a path from P to Q because R does not appear in
P's witness table.

Fixes <rdar://problem/21029254>.

Swift SVN r28832
2015-05-20 17:59:15 +00:00
Ted Kremenek
9f9bb725cf Rename '_ErrorType' to 'ErrorType'.
Swift SVN r28293
2015-05-07 21:59:29 +00:00
Slava Pestov
6a31cb242f IRGen: use concrete inherited conformances for archetypes
Refactor emitWitnessTableRefs(), EmitPolymorphicArguments::emit() and
getProtocolWitnessTable() to share code, and make them work for the case
where we have a concrete conformance for an archetype.

Fixes <rdar://problem/20628295>

Swift SVN r28138
2015-05-04 23:50:27 +00:00
Joe Groff
2d3eba9e0d IRGen: Reuse value witness table projections.
Don't project every value witness from the metadata every time we need one; this wastes code size in a way LLVM can't really optimize since it doesn't know the metadata is immutable. The code size wins on the standard library are disappointingly small (stdlib only shrinks by 4KB), but this makes generic IR a lot more compact and easier to read.

Swift SVN r28095
2015-05-03 05:00:40 +00:00
Slava Pestov
9d2d52b7ff SILWitnessVisitor: canonicalize protocols for associated types
Fixes <rdar://problem/20714534>.

Swift SVN r27990
2015-04-30 18:41:11 +00:00