Commit Graph

227 Commits

Author SHA1 Message Date
John McCall
0ffb7278bc Only use metadata patterns for generic types; perform other
initialization in-place on demand.  Initialize parent metadata
references correctly on struct and enum metadata.

Also includes several minor improvements related to relative
pointers that I was using before deciding to simply switch the
parent reference to an absolute reference to get better access
patterns.

Includes a fix since the earlier commit to make enum metadata
writable if they have an unfilled payload size.  This didn't show
up on Darwin because "constant" is currently unenforced there in
global data containing relocations.

This patch requires an associated LLDB change which is being
submitted in parallel.
2016-03-24 15:10:31 -07:00
John McCall
abba7f0c8b Revert "Only use metadata patterns for generic types; perform other"
This reverts commit 41efb3d4d3.
LLDB has too many tendrils into our metadata.
2016-03-23 20:26:43 -07:00
John McCall
41efb3d4d3 Only use metadata patterns for generic types; perform other
initialization in-place on demand.  Initialize parent metadata
references correctly on struct and enum metadata.

Also includes several minor improvements related to relative
pointers that I was using before deciding to simply switch the
parent reference to an absolute reference to get better access
patterns.
2016-03-23 17:04:04 -07:00
Max Moiseev
cf4bafe9e3 Merge remote-tracking branch 'origin/master' into swift-3-api-guidelines 2016-03-03 13:22:03 -08:00
swiftix
2573782c8b Merge pull request #1357 from swiftix/wip-runtime-calling-convention
Prepare the ground for using a new calling convention for functions from the runtime library
2016-03-01 16:22:37 -08:00
Max Moiseev
488b464f10 Merge remote-tracking branch 'origin/master' into swift-3-api-guidelines 2016-02-25 12:21:56 -08:00
John McCall
3ce1ba3e65 Only store the minimal requirements in generic metadata, where
"minimal" is defined as the set of requirements that would be
passed to a function with the type's generic signature that
takes the thick metadata of the parent type as its only argument.
2016-02-25 10:33:33 -08:00
Roman Levenstein
2ff5755dc3 Use the "rt_" prefix for all generated wrappers to distinguish them from the actual runtime functions. 2016-02-25 06:00:30 -08:00
Dmitri Gribenko
0f36bec31f Merge remote-tracking branch 'origin/master' into swift-3-api-guidelines 2016-02-18 16:41:35 -08:00
John McCall
e249fd680e Destructure result types in SIL function types.
Similarly to how we've always handled parameter types, we
now recursively expand tuples in result types and separately
determine a result convention for each result.

The most important code-generation change here is that
indirect results are now returned separately from each
other and from any direct results.  It is generally far
better, when receiving an indirect result, to receive it
as an independent result; the caller is much more likely
to be able to directly receive the result in the address
they want to initialize, rather than having to receive it
in temporary memory and then copy parts of it into the
target.

The most important conceptual change here that clients and
producers of SIL must be aware of is the new distinction
between a SILFunctionType's *parameters* and its *argument
list*.  The former is just the formal parameters, derived
purely from the parameter types of the original function;
indirect results are no longer in this list.  The latter
includes the indirect result arguments; as always, all
the indirect results strictly precede the parameters.
Apply instructions and entry block arguments follow the
argument list, not the parameter list.

A relatively minor change is that there can now be multiple
direct results, each with its own result convention.
This is a minor change because I've chosen to leave
return instructions as taking a single operand and
apply instructions as producing a single result; when
the type describes multiple results, they are implicitly
bound up in a tuple.  It might make sense to split these
up and allow e.g. return instructions to take a list
of operands; however, it's not clear what to do on the
caller side, and this would be a major change that can
be separated out from this already over-large patch.

Unsurprisingly, the most invasive changes here are in
SILGen; this requires substantial reworking of both call
emission and reabstraction.  It also proved important
to switch several SILGen operations over to work with
RValue instead of ManagedValue, since otherwise they
would be forced to spuriously "implode" buffers.
2016-02-18 01:26:28 -08:00
Dmitri Gribenko
65d840c0ae stdlib: lowercase cases in Optional and ImplicitlyUnwrappedOptional 2016-02-18 00:40:33 -08:00
Joe Groff
8cb1175e49 IRGen: Emit public definitions with protected visibility on ELF.
This prevents the linker from trying to emit relative relocations to locally-defined public symbols into dynamic libraries, which gives ld.so heartache.
2016-02-08 13:09:27 -08:00
David Farler
a6a5ece206 IRGen: Emit type references for remote reflection
- Implement emission of type references for nominal type field
  reflection, using a small custom encoder resulting in packed
  structs, not strings. This will let us embed 7-bit encoded
  32-bit relative offsets directly in the structure (not yet
  hooked in).
- Use the AST Mangler for encoding type references
  Archetypes and internal references were complicating this before, so we
  can take the opportunity to reuse this machinery and avoid unique code
  and new ABI.

Next up: Tests for reading the reflection sections and converting the
demangle tree into a tree of type references.

Todo: For concrete types, serialize the types for associated types of
their conformances to bootstrap the typeref substitution process.

rdar://problem/15617914
2016-02-03 13:52:26 -08:00
Joe Groff
638e4b0984 IRGen/Runtime: Use relative addresses in nominal type descriptors.
Decrease the size of nominal type descriptors and make them true-const by relative-addressing the other metadata they need to reference, which should all be included in the same image as the descriptor itself. Relative-referencing string constants exposes a bug in the Apple linker, which crashes when resolving relative relocations to coalesceable symbols (rdar://problem/22674524); work around this for now by revoking the `unnamed_addr`-ness of string constants that we take relative references to. (I haven't tested whether GNU ld or gold also have this problem on Linux; it may be possible to conditionalize the workaround to only apply to Darwin targets for now.)
2016-01-20 14:41:53 -08:00
John McCall
f1682cd9a8 Use real types instead of "Self" for the IR value names of local type data.
Since that's somewhat expensive, allow the generation of meaningful
IR value names to be efficiently controlled in IRGen.  By default,
enable meaningful value names only when generating .ll output.

I considered giving protocol witness tables the name T:Protocol
instead of T.Protocol, but decided that I didn't want to update that
many test cases.
2016-01-13 19:26:18 -08:00
practicalswift
755513daf5 Fix typo: enhabitants → inhabitants 2015-12-14 00:11:42 +01:00
Joe Groff
fd457fb343 Revert "IRGen/Runtime: Use relative addresses in nominal type descriptors."
This reverts commit fbb832665a. It causes LLVM to complain with
"Cannot represent a subtraction with a weak symbol" when targeting Linux.
2015-12-11 15:41:11 -08:00
Joe Groff
fbb832665a IRGen/Runtime: Use relative addresses in nominal type descriptors.
Decrease the size of nominal type descriptors and make them true-const by relative-addressing the other metadata they need to reference, which should all be included in the same image as the descriptor itself. Relative-referencing string constants exposes a bug in the Apple linker, which crashes when resolving relative relocations to coalesceable symbols (rdar://problem/22674524); work around this for now by revoking the `unnamed_addr`-ness of string constants that we take relative references to. (I haven't tested whether GNU ld or gold also have this problem on Linux; it may be possible to conditionalize the workaround to only apply to Darwin targets for now.)
2015-12-11 15:21:12 -08:00
Dmitri Gribenko
4f67c5433d Fix test/IRGen/enum.sil on non-ObjC platforms 2015-12-10 11:21:51 -07:00
John McCall
f2f5050673 Fix test case to work on non-ObjC targets. 2015-12-10 08:12:02 -08:00
John McCall
e389ba080b Unowned references under ObjC interop only have one extra inhabitant.
A single extra inhabitant is good enough for the most important case,
that being a single level of optionality.  Otherwise, we want to
reserve maximal flexibility for the implementation.

This commit also fixes a bug where I was not correctly defining
the extra-inhabitant rules for all of the existential cases.
2015-12-09 19:28:38 -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
Slava Pestov
f98cd04853 IRGen: Don't use spare bits in address-only payloads
The previous patch added an assert, but it turns out we could still
end up in this code path if the payload was fixed-size *and*
address-only. This is not a very common case, so don't try to
optimize it.
2015-11-18 23:34:07 -08:00
Slava Pestov
72fa928b75 IRGen: name create_generic_metadata functions for easier debugging 2015-11-16 10:37:14 -08:00
Slava Pestov
3d19691bab IRGen: Always use Swift reference counting when Obj-C interop is not available
The swift_unknown* entry points are not available on the Linux port.
Previously we would still attempt to use them in a couple of cases:

1) Foreign classes
2) Existentials and archetypes
3) Optionals of boxed existentials

Note that this patch changes IRGen to never emit the
swift_errorRelease/Retain entry points on Linux. We would like to
use them in the future if we ever adopt a tagged-pointer representation
for small errors. In this case, they can be brought back, and the
TypeInfo for optionals will need to be generalized to propagate the
reference counting of the payload type, instead of defaulting to
unknown if the payload type is not natively reference counted.
A similar change will need to be made to support blocks, if we ever
want to use the blocks runtime on Linux.

Fixes <rdar://problem/23335318>, <rdar://problem/23335537>,
<rdar://problem/23335453>.
2015-11-03 13:03:50 -08:00
Joe Groff
2368ce774b Remove self types from mangling by default.
And include some supplementary mangling changes:

- Give the first generic param (depth=0, index=0) a single character mangling. Even after removing the self type from method declaration types, 'Self' still shows up very frequently in protocol requirement signatures.
- Fix the mangling of generic parameter counts to elide the count when there's only one parameter at the starting depth of the mangling.

Together these carve another 154KB out of a debug standard library. There's some awkwardness in demangled strings that I'll clean up in subsequent commits; since decl types now only mangle the number of generic params at their own depth, it's context-dependent what depths those represent, which we get wrong now. Currying markers are also wrong, but since free function currying is going away, we can mangle the partial application thunks in different ways.

Swift SVN r32896
2015-10-26 22:05:20 +00:00
Joe Groff
42c71b7972 Don't mangle directness into type metadata symbols.
Anywhere we can't directly address type metadata in Swift, we've found we need a function call. Directness isn't useful here.

Swift SVN r32626
2015-10-12 17:22:40 +00:00
Joe Groff
25f0dc31c2 IRGen: Fix up layout generation for reference storage types.
If we have an unowned/weak protocol type with witness tables, we can't use the prefab NativeObject/UnknownObject layouts. While we're here, fix up some tests for 32-bit portability too.

Swift SVN r30270
2015-07-16 20:07:35 +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
Mark Lacey
b809473a8e Fix typo in comment.
Swift SVN r30229
2015-07-15 22:27:50 +00:00
Mark Lacey
37a70ef1b3 Fix conditional branch generation for switch_enum.
In the case where there is a single tag bit and extra inhabitants, we
generate a conditional branch, but we weren't emitting both destination
blocks.

Fixes rdar://problem/21742335.

Swift SVN r30228
2015-07-15 22:05:52 +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
Jordan Rose
8106a11dac Disallow @objc on non-ObjC-rooted classes.
These classes don't show up well in generated headers (rdar://problem/20855568),
can't actually be allocated from Objective-C (rdar://problem/17184317), and
make the story of "what is exposed to Objective-C" more complicated. Better
to just disallow them.

All classes are still "id-compatible" in that they can be converted to
AnyObject and passed to Objective-C, they secretly implement NSObjectProtocol
(via our SwiftObject root class), and their members can still be individually
exposed to Objective-C.

The frontend flag -disable-objc-attr-requires-foundation-module will disable
this requirement as well, which is still necessary for both the standard
library and a variety of tests I didn't feel like transforming.

Swift SVN r29760
2015-06-27 16:27:56 +00:00
Dmitri Hrybenko
f08d1c9cfc Adjust tests for the new scheme of name conflict resolution in LLVM
Previously, LLVM appended numbers to disambiguate duplicate symbols.
Now it appends a dot an a number.

Swift SVN r29694
2015-06-25 22:01:33 +00:00
Joe Groff
2f56073145 IRGen: Slather attributes on indirect arguments.
@inout parameters can be nocapture and dereferenceable. @in, @in_guaranteed, and indirected @direct parameters can be noalias, nocapture, and dereferenceable.

Swift SVN r29353
2015-06-09 01:19:17 +00:00
Joe Groff
76b9838564 IRGen: Peephole improvements for enum switch codegen.
If an enum has only a single tag bit, emit a cond_br instead of a switch, and if it has only one no-payload case, jump directly to the destination for that case instead of wasting time testing the bit pattern and branching to unreachable. Fixes rdar://problem/21093111.

Reapplying now that Adrian fixed the debug info issue this exposed.

Swift SVN r29202
2015-06-01 19:17:54 +00:00
Joe Groff
4a77e4878b IRGen: Fix implementation of storeSpareBitExtraInhabitant.
It would overflow when a type had more than sizeof(unsigned) occupied bits. Fixes rdar://problem/21126703, now with the 64-bit-specific tests properly platform-gated.

Swift SVN r29159
2015-05-30 00:41:51 +00:00
Ted Kremenek
492309e62c Revert "IRGen: Fix implementation of storeSpareBitExtraInhabitant."
This is breaking the iOS bots.

Swift SVN r29134
2015-05-29 05:05:52 +00:00
Joe Groff
12283b43a8 IRGen: Fix implementation of storeSpareBitExtraInhabitant.
It would overflow when a type had more than sizeof(unsigned) occupied bits. Fixes rdar://problem/21126703.

Swift SVN r29128
2015-05-29 00:55:23 +00:00
Joe Groff
3a01e4666d IRGen: Fix miscompile when storing empty payloads represented as large extra inhabitants.
Stupid typo on my part. Fixes a new IRGen bug introduced by the EnumPayload code that's affecting rdar://problem/21126703; not sure if it addresses that bug yet though.

Swift SVN r29116
2015-05-28 21:57:53 +00:00
Joe Groff
aad6bc87fd IRGen: Pass large explosions as indirect arguments.
It's not worth burning more than three registers on a parameter, and doing so causes code size issues for large structs and enums. Make it so that values with more than three explosion members get passed indirectly, just like they get returned indirectly.

This time, modify emitPartialApplyForwarder not to attempt to 'tail' call the original function when indirect arguments get alloca'ed on the stack, which is UB, and don't use "byval", as suggested by John.

Swift SVN r29032
2015-05-26 17:38:22 +00:00
Ted Kremenek
c60b51be69 Revert "IRGen: Peephole improvements for enum switch codegen."
This may be the cause of a crash and burn on the iOS builders:

Assertion failed: (Offset <= PieceOffset && "overlapping or duplicate pieces"), function finalize

Swift SVN r29027
2015-05-26 06:06:43 +00:00
Joe Groff
c8238ffb17 IRGen: Peephole improvements for enum switch codegen.
If an enum has only a single tag bit, emit a cond_br instead of a switch, and if it has only one no-payload case, jump directly to the destination for that case instead of wasting time testing the bit pattern and branching to unreachable. Fixes rdar://problem/21093111.

Swift SVN r29023
2015-05-26 04:53:43 +00:00
Joe Groff
7a5b199a34 Revert "IRGen: Pass large explosions as indirect byval arguments."
This reverts commit r29016, because of a test failure on the bots.

Swift SVN r29018
2015-05-26 02:13:16 +00:00
Joe Groff
abba73c77f IRGen: Pass large explosions as indirect byval arguments.
It's not worth burning more than three registers on a parameter, and doing so causes code size issues for large structs and enums. Make it so that values with more than three explosion members get passed indirectly, just like they get returned indirectly.

Swift SVN r29016
2015-05-26 01:49:45 +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