Commit Graph

283 Commits

Author SHA1 Message Date
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00: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
John McCall
bdb4b896a2 Move ObjC-compatible unowned references to the new runtime
functions.

Take the code for the old, broken reference-counting
implementation and delete it with prejudice.
2015-12-08 16:20:32 -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
Adrian Prantl
8ab1e2dd50 Unify debug scope and location handling in SILInstruction and SILBuilder.
The drivers for this change are providing a simpler API to SIL pass
authors, having a more efficient of the in-memory representation,
and ruling out an entire class of common bugs that usually result
in hard-to-debug backend crashes.

Summary
-------

SILInstruction

Old                   New
+---------------+     +------------------+    +-----------------+
|SILInstruction |     |SILInstruction    |    |SILDebugLocation |
+---------------+     +------------------+    +-----------------+
| ...           |     | ...              |    | ...             |
|SILLocation    |     |SILDebugLocation *| -> |SILLocation      |
|SILDebugScope *|     +------------------+    |SILDebugScope *  |
+---------------+                             +-----------------+

We’re introducing a new class SILDebugLocation which represents the
combination of a SILLocation and a SILDebugScope.
Instead of storing an inline SILLocation and a SILDebugScope pointer,
SILInstruction now only has one SILDebugLocation pointer. The APIs of
SILBuilder and SILDebugLocation guarantees that every SILInstruction
has a nonempty SILDebugScope.

Developer-visible changes include:

SILBuilder
----------

In the old design SILBuilder populated the InsertedInstrs list to
allow setting the debug scopes of all built instructions in bulk
at the very end (as the responsibility of the user). In the new design,
SILBuilder now carries a "current debug scope" state and immediately
sets the debug scope when an instruction is inserted.
This fixes a use-after-free issue with with SIL passes that delete
instructions before destroying the SILBuilder that created them.

Because of this, SILBuilderWithScopes no longer needs to be a template,
which simplifies its call sites.

SILInstruction
--------------

It is neither possible or necessary to manually call setDebugScope()
on a SILInstruction any more. The function still exists as a private
method, but is only used when splicing instructions from one function
to another.

Efficiency
----------

In addition to dropping 20 bytes from each SILInstruction,
SILDebugLocations are now allocated in the SILModule's bump pointer
allocator and are uniqued by SILBuilder. Unfortunately repeat compiles
of the standard library already vary by about 5% so I couldn’t yet
produce reliable numbers for how much this saves overall.

rdar://problem/22017421
2015-11-19 09:31:26 -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
Erik Eckstein
68fa1c2c34 Support for stack promotion in IRGen.
This means: handling of alloc_ref [stack].
It can be configured with two new options. See Option/FrontendOptions.td.

As the [stack] attribute is not generated yet, there should be NFC.




Swift SVN r32929
2015-10-28 00:44:25 +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
Joe Groff
2630dba793 Runtime: Rename Box2 functions to Box.
Swift SVN r29763
2015-06-27 18:10:17 +00:00
Joe Groff
8a04d67408 IRGen: Strip out dead code for untyped boxes.
Swift SVN r29761
2015-06-27 17:50:13 +00:00
Joe Groff
3c2ee54d43 IRGen: Implementation of typed box operations.
When producing TypeInfo for a box, try to reuse instantiations for common type structures:

- any POD type with the same stride and alignment can share a fixed HeapLayout;
- any single-refcounted-pointer type can share a fixed HeapLayout with types that have the same ReferenceCounting;
- dynamically-sized types can share a runtime-based box implementation.

For the runtime implementation, use new to-be-implemented variants of allocBox/deallocBox that will produce polymorphically-projectable boxes using instantiated metadata.

Swift SVN r29612
2015-06-24 19:43:24 +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
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
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
Andrew Trick
a174aa4dfe Add AST and SILGen support for Builtin.isUnique.
Preparation to fix <rdar://problem/18151694> Add Builtin.checkUnique
to avoid lost Array copies.

This adds the following new builtins:

    isUnique : <T> (inout T[?]) -> Int1
    isUniqueOrPinned : <T> (inout T[?]) -> Int1

These builtins take an inout object reference and return a
boolean. Passing the reference inout forces the optimizer to preserve
a retain distinct from what’s required to maintain lifetime for any of
the reference's source-level copies, because the called function is
allowed to replace the reference, thereby releasing the referent.

Before this change, the API entry points for uniqueness checking
already took an inout reference. However, after full inlining, it was
possible for two source-level variables that reference the same object
to appear to be the same variable from the optimizer's perspective
because an address to the variable was longer taken at the point of
checking uniqueness. Consequently the optimizer could remove
"redundant" copies which were actually needed to implement
copy-on-write semantics. With a builtin, the variable whose reference
is being checked for uniqueness appears mutable at the level of an
individual SIL instruction.

The kind of reference count checking that Builtin.isUnique performs
depends on the argument type:

    - Native object types are directly checked by reading the
      strong reference count:
      (Builtin.NativeObject, known native class reference)

    - Objective-C object types require an additional check that the
      dynamic object type uses native swift reference counting:
      (Builtin.UnknownObject, unknown class reference, class existential)

    - Bridged object types allow the dymanic object type check to be
      bypassed based on the pointer encoding:
      (Builtin.BridgeObject)

Any of the above types may also be wrapped in an optional.  If the
static argument type is optional, then a null check is also performed.

Thus, isUnique only returns true for non-null, native swift object
references with a strong reference count of one.

isUniqueOrPinned has the same semantics as isUnique except that it
also returns true if the object is marked pinned regardless of the
reference count. This allows for simultaneous non-structural
modification of multiple subobjects.

In some cases, the standard library can dynamically determine that it
has a native reference even though the static type is a bridge or
unknown object. Unsafe variants of the builtin are available to allow
the additional pointer bit mask and dynamic class lookup to be
bypassed in these cases:

    isUnique_native : <T> (inout T[?]) -> Int1
    isUniqueOrPinned_native : <T> (inout T[?]) -> Int1

These builtins perform an implicit cast to NativeObject before
checking uniqueness. There’s no way at SIL level to cast the address
of a reference, so we need to encapsulate this operation as part of
the builtin.

Swift SVN r27887
2015-04-28 22:54:24 +00:00
Joe Groff
768420d33b IRGen/Runtime: Give ErrorType its own retain/release entry points.
Some future-proofing to let us change ErrorType's reference counting in the future, or to use various tagged pointer optimizations in its representation.

Swift SVN r27213
2015-04-10 18:54:16 +00:00
John McCall
dc5a03a7bc Add IRGen support for error results from functions.
As part of this, re-arrange the argument order so that
generic arguments come before the context, which comes
before the error result.  Be more consistent about always
adding a context parameter on thick functions, even
when it's unused.  Pull out the witness-method Self
argument so that it appears last after the error
argument.

Swift SVN r26667
2015-03-28 02:00:17 +00:00
Erik Eckstein
9544893104 IRGen: Use a different cache for layout-metadata.
Metadata used for layout is (or may be) different than the "regular" metadata.
Therefore we need a separate cache for it.



Swift SVN r25238
2015-02-12 13:44:23 +00:00
Erik Eckstein
a5b8e05ea6 Reuse type metadata in the most obvious cases.
This avoids redundant calls of swift_get*Metadata() if the metadata is reused in the same basic block
or if it is already availabe in the function entry block.
There is still room for improvement, e.g. by not limiting the reuse to a single block.

This change reduces the dylib codesize by about 11%, mostly in protocoll witnesses (-34%).

It also results in some improvements for the -Onone performance:
RangeAssignment: +31%
StdlibSort: +20%




Swift SVN r25123
2015-02-10 14:42:39 +00:00
Joe Groff
3f2bb26c04 Reinstate r24526, r24548, r24549, and r24550.
OpaqueStorageTypeInfo will be adjusted to use [N x i8] storage types in the following commit.

Swift SVN r24569
2015-01-20 21:49:46 +00:00
Joe Groff
344514a39f Revert r24526, r24548, r24549, and r24550.
OpaqueStorageTypeInfo uses iNNN types that don't always have the correct alloc size for an expected
size at the LLVM level. This needs to be fixed before my partial apply closure fixes can hold.

Swift SVN r24551
2015-01-20 06:14:20 +00:00
Joe Groff
934661c000 IRGen: Wire up NonFixedOffsets for partial apply objects.
This gets generic curries working correctly. Add an interpreter test to verify.

Swift SVN r24548
2015-01-20 04:42:26 +00:00
John McCall
3b4e0d307e Intrinsic support for pinning.
Using the intrinsics is obnoxious because I needed them
to return Builtin.NativeObject?, but there's no reasonable
way to safely generate optional types from Builtins.cpp.
Ugh.

Dave and I also decided that there's no need for
swift_tryPin to allow a null object.

Swift SVN r23824
2014-12-10 00:52:48 +00:00
Joe Groff
f229840161 IRGen: Code generation for general class existential casts.
Emit a helper that invokes conformsToProtocol the appropriate number of times for the destination protocol type.

Swift SVN r23176
2014-11-08 04:53:46 +00:00
Joe Groff
5a2f48e3be Add a Builtin.BridgeObject type.
This is a type that has ownership of a reference while allowing access to the
spare bits inside the pointer, but which can also safely hold an ObjC tagged pointer
reference (with no spare bits of course). It additionally blesses one
Foundation-coordinated bit with the meaning of "has swift refcounting" in order
to get a faster short-circuit to native refcounting. It supports the following
builtin operations:

- Builtin.castToBridgeObject<T>(ref: T, bits: Builtin.Word) ->
  Builtin.BridgeObject

  Creates a BridgeObject that contains the bitwise-OR of the bit patterns of
  "ref" and "bits". It is the user's responsibility to ensure "bits" doesn't
  interfere with the reference identity of the resulting value. In other words,
  it is undefined behavior unless:

    castReferenceFromBridgeObject(castToBridgeObject(ref, bits)) === ref

  This means "bits" must be zero if "ref" is a tagged pointer. If "ref" is a real
  object pointer, "bits" must not have any non-spare bits set (unless they're
  already set in the pointer value). The native discriminator bit may only be set
  if the object is Swift-refcounted.

- Builtin.castReferenceFromBridgeObject<T>(bo: Builtin.BridgeObject) -> T

  Extracts the reference from a BridgeObject.

- Builtin.castBitPatternFromBridgeObject(bo: Builtin.BridgeObject) -> Builtin.Word

  Presents the bit pattern of a BridgeObject as a Word.

BridgeObject's bits are set up as follows on the various platforms:

i386, armv7:

  No ObjC tagged pointers
  Swift native refcounting flag bit: 0x0000_0001
  Other available spare bits:        0x0000_0002

x86_64:

  Reserved for ObjC tagged pointers: 0x8000_0000_0000_0001
  Swift native refcounting flag bit: 0x0000_0000_0000_0002
  Other available spare bits:        0x7F00_0000_0000_0004

arm64:

  Reserved for ObjC tagged pointers: 0x8000_0000_0000_0000
  Swift native refcounting flag bit: 0x4000_0000_0000_0000
  Other available spare bits:        0x3F00_0000_0000_0007

TODO: BridgeObject doesn't present any extra inhabitants. It ought to at least provide null as an extra inhabitant for Optional.

Swift SVN r22880
2014-10-23 00:09:23 +00:00
Jordan Rose
3fcdfd40e9 Remove the "swift/Basic/Optional.h" header.
llvm::Optional lives in "llvm/ADT/Optional.h". Like Clang, we can get
Optional in the 'swift' namespace by including "swift/Basic/LLVM.h".

We're now fully switched over to llvm::Optional!

Swift SVN r22477
2014-10-02 18:51:45 +00:00
Jordan Rose
042569a3be Optional: Replace uses of Nothing with None.
llvm::Optional (like Swift.Optional!) uses None as its placeholder value,
not Nothing.

Swift SVN r22476
2014-10-02 18:51:42 +00:00
Jordan Rose
9891c7f2f2 Replace swift::Optional with llvm::Optional.
There are some compatibility aliases here that will go away after the switch.

Swift SVN r22474
2014-10-02 18:51:38 +00:00
Joe Groff
1c4e08a9c8 Fix up a tangle of issues related to reabstraction.
- A spot fix in SILGen for reabstracting the result of a downcast, which fixes checked casts to function types.
- Associate the layout information in type metadata records with the most abstract representation of the type. This is the correct thing to do in cases where we need the metadata as a tag for an opaque value--if we store a value in an Any, or pass it as an unconstrained generic parameter, we must maximally reabstract it. This fixes the value semantics of existentials containing trivial metatypes.
- To ensure that we get runtime layout of structs and enums correct when they contain reabstractable types, introduce a "metadata for layout" concept, which doesn't need to describe the canonical metadata for the type, but only needs to describe a type with equivalent layout and value semantics. This is a correctness fix that allows us to correctly lay out generic types containing dependent tuples and functions, and although we don't really take advantage of it here, it's also a potential runtime performance win down the road, because we could potentially produce direct metadata for a primitive type that's layout-equivalent with a runtime-instantiated type. To aid in type safety here, push SILType deeper into IRGen in places where we potentially care about specific representations of types.
- Finally, fix an inconsistency between the runtime and IRGen's concept of what spare bits unmanaged references and thick metatypes have.

Together, these fixes address rdar://problem/16406907, rdar://problem/17822208, rdar://problem/18189508, and likely many other related issues, and also fixes crash suite cases 012 and 024.

Swift SVN r21963
2014-09-16 01:44:34 +00:00
Michael Gottesman
9514ba5a7d [irgen] Lower fix_lifetime => swift_keepAlive().
I introduced a function swift_keepAlive2() which has a different signature from
swift_keepAlive() until I can verify that the stdlib is using the new
infrastructure.

The difference in signature is that swift_keepAlive2 takes just a pointer while
swift_keepAlive also takes a metadata value that is not necessary for our
purposes anymore.

Swift SVN r21718
2014-09-04 21:53:18 +00:00
John McCall
0ddc7ee5b6 Resilience expansion is not an IR-generation concept.
If a type has to be passed or returned resiliently, it
will necessarily be passed indirectly, which is already
represented in SILFunctionType.  There is no need to
represent this as a separate channel of information.

NFC. Also fixes a problem where the signature cache
for ExtraData::Block was writing past the end of an
array (but into the storage for an adjacent array
which was fortunately never used).

ExtraData should also disappear as a concept, but we're
still relying on that for existential protocol witnesses.

Swift SVN r21548
2014-08-28 23:07:50 +00:00
Joe Groff
6cb2bf96b8 IRGen: Implement the dealloc_box instruction.
Failable initializers will need to clean up an uninitialized 'self' box in the case where a class initializer calls out to a 'super.init' or 'self.init' fails. Because some framework classes assume that they have a refcount of exactly one during initialization, we have to take 'self' from the box during the delegation, and reinitialize the box with the result of the delegation on success. This means we actually have to implement lowering for dealloc_box.

Swift SVN r21493
2014-08-27 22:44:53 +00:00
John McCall
6fb1dc2db1 Centralize more dynamic-casting code into GenCast.cpp. NFC.
Swift SVN r18818
2014-06-12 01:00:23 +00:00
John McCall
5e1c15df93 Rationalize the class-instance dynamicCast runtime functions.
dynamicCastClass assumes that the destination type is a
Swift class type.

dynamicCastObjCClass assumes that the destination type is
an ObjC class type (represented as ObjC metadata, not type
metadata).

dynamicCastUnknownClass assumes only that the destination
type is some kind of class.

Swift SVN r18776
2014-06-10 02:11:24 +00:00
John McCall
059ed4cd10 Propagate alignment arguments around through the
slow allocation/deallocation APIs.

Swift SVN r18160
2014-05-16 01:40:36 +00:00
Joe Groff
972ddc10d9 IRGen: Implement type metadata lookup for dynamic Self.
Fixes <rdar://problem/16925631>.

Swift SVN r18125
2014-05-15 20:44:59 +00:00
Joe Groff
bf858cc8a1 SILGen: Handle inner pointer returns through currying and dynamic lookup.
When we partially apply an inner-pointer method or property, the thunk or partial_apply that applies "self" needs to be the one that handles lifetime-extending "self". Verify that a partial_apply-ed inner pointer method is not inner pointer and implement lifetime extension in the partial apply thunk. Fixes <rdar://problem/16803701>.

Swift SVN r17321
2014-05-03 18:37:42 +00:00
Joe Groff
def2f97944 IRGen: Generalize 'hasSwiftRefcount' into an enum of reference counting mechanisms.
Replace HeapTypeInfo::hasSwiftRefcount with a "getSwiftRefcounting" method, returning an enum indicating whether a heap object has native/ObjC/block/unknown refcounting semantics. Use _Block_copy and _Block_release for block refcounting.

Swift SVN r16041
2014-04-08 02:43:16 +00:00
Mark Lacey
c06facbdd1 Small simplification of IRGenFunction::coerceValue().
We know the type of the value we are reinterpreting so it does not need
to be a parameter.

Swift SVN r12911
2014-01-24 07:51:26 +00:00
Mark Lacey
0564fae0bd Assert if we attempt to coerce types of different sizes.
We shouldn't store to one size and load as another, and shouldn't need
to handle things like truncation and extension of numeric types, either.

Swift SVN r12530
2014-01-18 04:49:32 +00:00
Mark Lacey
85edc079b7 Coerce scalar types in function returns.
Previously we coerced only struct return types, but we actually need to
be able to coerce scalar types as well, e.g. differing pointer types
when the ABI type differs from the type used in the body of the
function.

Swift SVN r12527
2014-01-18 02:08:04 +00:00
John McCall
a1b469ed2f ExplosionKind -> ResilienceExpansion. NFC.
Swift SVN r12364
2014-01-16 00:25:29 +00:00
Mark Lacey
9b81800432 Choose correct IR types for @objc return values.
This change updates signature generation as well as IR generation for
calls and returns so that the correct ABI types are generated for the
results of @objc functions.

Swift SVN r11527
2013-12-20 23:31:01 +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
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
Adrian Prantl
5bbe0afb9f Debug info: Properly handle the function prologue in the line table.
Introduces a new flag in SILLocation: InPrologue to mark instructions
that setup the stack and allocate storage for local variables/arguments.

Fixes rdar://problem/15290023: Breakpoint set on prologue - crash ensues.

Swift SVN r9686
2013-10-26 00:12:20 +00:00
Jordan Rose
25deab5f31 Misc. cleanup related to use of TranslationUnit.
Swift SVN r9164
2013-10-10 19:49:32 +00:00