Commit Graph

336 Commits

Author SHA1 Message Date
Joe Groff
be71ab28e2 SIL: Add an MarkUninitializedBehavior instruction for behavior DI.
This instruction creates a "virtual" address to represent a property with a behavior that supports definite initialization. The instruction holds references to functions that perform the initialization and 'set' logic for the property. It will be DI's job to rewrite assignments into this virtual address into calls to the initializer or setter based on the initialization state of the property at the time of assignment.
2016-03-03 15:04:38 -08:00
Andrew Trick
d1892655b9 [SILOptimizer] Fix a slightly misleading comment. 2016-02-26 20:36:22 -08:00
Adrian Prantl
8e1d6c013b Make SILDebugLocation a value member of SILInstruction again.
The overhead of uniquing the locations in a Densemap isn't worth any of
the potential memory savings: While this adds an extra pointer and
unsigned to each SILInstruction, any extra memory is completely lost in
the noise (measured on a release -emit-ir build of the x86_64 stdlib).
This is not too surpising as the ratio between SILInstructions and unique
SILLocations is not very high and the DenseMap also needs space.

<rdar://problem/22706994>
2016-02-19 13:41:54 -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
Adrian Prantl
d01ca413d1 Remove redundant assertions that are already part of the SIL Verifier. 2016-02-05 14:00:57 -08:00
Adrian Prantl
0854b3ce6d SILDebugScope: Add accessors for the parent SIL functions and use them in
assertions. (NFC)
2016-02-03 14:48:06 -08:00
Adrian Prantl
75fc840126 Merge the parent scope and function fields of SILDebugScope into a
PointerUnion.

This saves 8 bytes per SILDebugScope.

rdar://problem/22706994
2016-01-29 17:21:26 -08:00
Erik Eckstein
506ab9809f SIL: remove getTyp() from SILValue 2016-01-25 15:00:49 -08:00
Erik Eckstein
b7ea3b9bb2 [SIL] Let alloc_existential_box return a single value.
And use the new project_existential_box to get to the address value.
SILGen now generates a project_existential_box for each alloc_existential_box.
And IRGen re-uses the address value from the alloc_existential_box if the operand of project_existential_box is an alloc_existential_box.
This lets the generated code be the same as before.
2016-01-20 11:27:06 -08:00
Erik Eckstein
4dab67c582 SIL: add a new project_existential_box instruction.
It will be used as a replacement for the second return value of alloc_existential_box.
2016-01-20 11:27:06 -08:00
John McCall
2df6880617 Introduce ProtocolConformanceRef. NFC.
The main idea here is that we really, really want to be
able to recover the protocol requirement of a conformance
reference even if it's abstract due to the conforming type
being abstract (e.g. an archetype).  I've made the conversion
from ProtocolConformance* explicit to discourage casual
contamination of the Ref with a null value.

As part of this change, always make conformance arrays in
Substitutions fully parallel to the requirements, as opposed
to occasionally being empty when the conformances are abstract.

As another part of this, I've tried to proactively fix
prospective bugs with partially-concrete conformances, which I
believe can happen with concretely-bound archetypes.

In addition to just giving us stronger invariants, this is
progress towards the removal of the archetype from Substitution.
2016-01-08 00:19:59 -08:00
Slava Pestov
046606a8f4 SIL: Add a new alloc_global instruction
If a global variable in a module we are compiling has a type containing
a resilient value type from a different module, we don't know the size
at compile time, so we cannot allocate storage for the global statically.

Instead, we will use a buffer, just like alloc_stack does for archetypes
and resilient value types.

This adds a new SIL instruction but does not yet make use of it.
2016-01-07 13:40:48 -08:00
practicalswift
50baf2e53b Use consistent formatting in top of file headers. 2016-01-04 02:17:48 +01:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
Adrian Prantl
64cbec3805 Add SIL syntax for declaring debug variables.
Debug variable info may be attached to debug_value, debug_value_addr,
alloc_box, and alloc_stack instructions.

In order to write textual SIL -> SIL testcases that exercise the handling
of debug information by SIL passes, we need to make a couple of additions
to the textual SIL language. In memory, the debug information attached to
SIL instructions references information from the AST. If we want to create
debug info from parsing a textual .sil file, these bits need to be made
explicit.

Performance Notes: This is memory neutral for compilations from Swift
source code, because the variable name is still stored in the AST. For
compilations from textual source the variable name is stored in tail-
allocated memory following the SIL instruction that introduces the
variable.

<rdar://problem/22707128>
2015-12-14 10:29:50 -08:00
John McCall
5fddd4a704 Remove the autorelease_return and strong_retain_autoreleased instructions.
There's a buggy SIL verifier check that was previously tautological,
and it turns out that it's violated, apparently harmlessly.  Since it
was already doing nothing, I've commented it out temporarily while
I figure out the right way to fix SILGen to get the invariant right.
2015-12-09 14:50:20 -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
ac5d14a185 Remove use of the GNU ?: extension from a core header.
Please stop adding uses of this; the source base should be portable
C++ to the greatest extent possible, and saving a few characters of
typing does not qualify for an exception.
2015-12-03 15:07:05 -08:00
Adrian Prantl
7821341542 Add an argument-number field to DebugValueInst and friends.
This commit adds a DebugVariable field that is shared by
- AllocBoxInst
- AllocStackInst
- DebugValueInst
- DebugValueAddrInst
Currently DebugVariable only holds the Swift argument number.

This allows us to retire several expensive heuristics in IRGen that
attempted to identify which local variables actually where arguments
and recover their relative order.

Memory footprint notes:
This commit adds a 4-byte field to 4 SILInstructin subclasses.
This was offset by 8ab1e2dd50
which removed 20 bytes from *every* SILInstruction.

Caveats:
This commit surfaces a known bug in FunctionSigantureOpts, tracked in
rdar://problem/23727705 — debug info for exploded function arguments
cannot be expressed until this is fixed.

This reapplies ed2b16dc5a with a bugfix for
generic function arrguments and an additional testcase.

<rdar://problem/21185379&22705926>
2015-12-03 13:40:35 -08:00
Adrian Prantl
2740ad6976 Temporarily Revert "Add an argument-number field to DebugValueInst and friends."
while investigating buildbot breakage.

This reverts commit ed2b16dc5a.
2015-12-02 19:10:05 -08:00
Adrian Prantl
ed2b16dc5a Add an argument-number field to DebugValueInst and friends.
This commit adds a DebugVariable field that is shared by
- AllocBoxInst
- AllocStackInst
- DebugValueInst
- DebugValueAddrInst
Currently DebugVariable only holds the Swift argument number.

This allows us to retire several expensive heuristics in IRGen that
attempted to identify which local variables actually where arguments
and recover their relative order.

Memory footprint notes:
This commit adds a 4-byte field to 4 SILInstructin subclasses.
This was offset by 8ab1e2dd50
which removed 20 bytes from *every* SILInstruction.

Caveats:
This commit surfaces a known bug in FunctionSigantureOpts, tracked in
rdar://problem/23727705 — debug info for exploded function arguments
cannot be expressed until this is fixed.

<rdar://problem/21185379&22705926>
2015-12-02 18:33:07 -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
Michael Gottesman
9fb54bf4bf Fix for upstream ilist changes. 2015-11-11 16:07:41 -08:00
Erik Eckstein
6fcb9ebb26 Fix cloning of (de)alloc_stack [stack]
And remove the default value for the canAllocOnStack parameter in SILBuilder (which was a bad idea to add it).
2015-11-08 13:59:43 -08:00
Erik Eckstein
ee988e21cb SIL: Add stack attributes to alloc_ref and dealloc_ref.
For details see docs/SIL.rst.
This is needed for the stack promotion optimization.



Swift SVN r32908
2015-10-27 15:29:20 +00:00
Adrian Prantl
2f9f964219 Change the contract between Swift compiler and LLDB about how the function
prologue is handled in the line table.
We now mark the first instruction after the stack setup as end_prologue and
any further initilizations (which may include function calls to metadata
accessors) with line 0 which lldb will skip. This allows swiftc to emit
debug info for compiler-generated functions such as metadata accessors.
Mixing debug and non-debug functions is not very well supported by LLVM
and the resulting line table makes it impossible for LLDB to determine
where a function with debug info ends and a nondebug function starts.

rdar://problem/23042642

Swift SVN r32816
2015-10-22 00:20:03 +00:00
Slava Pestov
76f1168adf Remove dealloc_ref's [constructor] form since its no longer needed
Swift SVN r32688
2015-10-14 22:50:09 +00:00
Slava Pestov
7cc59e01d7 SIL: Add DeallocPartialRefInst
This instruction destroys instance variables in a partially-initialized
object, then frees it.

Swift SVN r32661
2015-10-13 19:56:20 +00:00
Slava Pestov
090d723763 SIL: Remove null_class instruction
Swift SVN r32605
2015-10-11 02:11:22 +00:00
Andrew Trick
c20370a664 Remove the last remnants of unchecked_ref_bit_cast
Swift SVN r32598
2015-10-10 05:42:57 +00:00
Andrew Trick
57a450b28f Generate unchecked_ref_cast, not unchecked_ref_bit_cast.
This improves support for promoting to and generating
unchecked_ref_cast so we no longer need unchecked_ref_bit_cast, which
will just go away in the next commit.

Swift SVN r32597
2015-10-10 05:42:53 +00:00
Andrew Trick
665e5169d5 Add unchecked_ref_cast_addr SIL instruction.
Swift SVN r32587
2015-10-10 03:39:32 +00:00
Slava Pestov
b29bced97a SILGen: Use createBuiltinBinaryFunction() in place of createBuiltin() in one place
It seems that for SIL round-tripping to work, we have to emit the
builtin name with the right suffix, otherwise NFC. Noticed by
inspection.

Swift SVN r32499
2015-10-07 19:57:19 +00:00
Mark Lacey
46b2de075e Add instruction list manipulation functions to SILBasicBlock.
Begin using these functions to encapsulate the instruction list rather
than directly accessing it via getInstList().

Swift SVN r32298
2015-09-29 06:35:49 +00:00
Mark Lacey
33a99b61e3 Store a reference to SILBuilder in SILCombine.
Swift SVN r32101
2015-09-20 19:50:26 +00:00
Erik Eckstein
388bc31ba7 Add a nothrow flag to the SIL apply_inst.
If the compiler can prove that a throwing function actually does not throw it can
replace a try_apply with an "apply [nothrow]". Such an apply_inst calls a function
with an error result but does not have the overhead of checking for the error case.

Currently this flag is not set, yet.



Swift SVN r31151
2015-08-12 00:18:36 +00:00
Slava Pestov
1628bfc3e2 SIL: Split dealloc_ref into [constructor] and [destructor] kinds
dealloc_ref [destructor] is the existing behavior. It expects the
reference count to have reached zero and the isDeallocating bit to
be set.

The new [constructor] variant first drops the initial strong
reference.

This allows DI to properly free uninitialized instances in
constructors. Previously this would fail with an assertion if the
runtime was built with debugging enabled.

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

Swift SVN r31142
2015-08-11 18:38:00 +00:00
Chris Lattner
0001dc27bb remove support for the experiemental "character literals" feature.
Swift SVN r30509
2015-07-22 22:35:19 +00:00
Andrew Trick
778012c479 Handle SIL unchecked_addr_cast conservatively when promoting to a value cast.
Unless we can prove that the input and output are layout identical we must use either trivial_bit_cast or bitwise_cast.

This changes the lowering to be more conservative for:

- Builtin.reinterpretCast
- address_to_pointer -> pointer_to_address

This also makes LoadStoreOpts more conservative in:

- forwardAddrToUncheckedCastToLd

In order to commit this without massive performance regressions, I added SILType::canBitCastAsSingleRef. When this is true for both sides
of a bitwise case, we can convert it to a RefBitCast, which has RC identity.

Swift SVN r30172
2015-07-13 22:46:17 +00:00
Joe Groff
910badfe4d SIL: Stage in a typed-boxes dialect.
When -sil-enable-typed-boxes is passed, have alloc_box and dealloc_box instructions work with box types instead of NativeObject.

Swift SVN r29511
2015-06-19 16:39:04 +00:00
Andrew Trick
7565a65235 Introduce unchecked_bitwise_cast SIL instruction.
We need a SIL level unsafe cast that supports arbitrary usage of
UnsafePointer, generalizes Builtin.reinterpretCast, and has the same
semantics on generic vs. nongeneric code. In other words, we need to
be able to promote the cast of an address type to the cast of an
object type without changing semantics, and that cast needs to support
types that are not layout identical.

This patch introduces an unchecked_bitwise_cast instruction for that
purpose. It is different from unsafe_addr_cast, which has been our
fall-back "unknown" cast in the past. With unchecked_bitwise_cast we
cannot assume layout or RC identity. The cast implies a store and
reload of the value to obtain the low order bytes. I know that
bit_cast is just an abbreviation for bitwise_cast, but we use
"bitcast" throught to imply copying a same sized value. No one could
come up with a better name for copying an objects low bytes via:

  @addr = alloca $wideTy
    store @addr, $wideTy
      load  @addr, $narrowTy

Followup patches will optimize unchecked_bitwise_cast into more
semantically useful unchecked casts when enough type information is
present. This way, the optimizer will rarely need to be taught about
the bitwise case.

Swift SVN r29510
2015-06-19 16:29:35 +00:00
Joe Groff
821b0f488e SIL: Add a project_box insn to project the address of the value from a box.
Still no implementation yet; we'll need to renovate how boxes work a bit to make them projectable (and renovate SILGen to generate typed boxes for the insn to be useful).

Swift SVN r29490
2015-06-18 15:47:22 +00:00
Mark Lacey
75b5b1248e Small clean-up. Add createUncheckedBitCast to SILBuilder.
This new method eliminates repeated code sequences that all create an
unchecked_trivial_bit_cast if the result type is trivial or
unchecked_ref_bit_cast otherwise.

NFC.

Swift SVN r29486
2015-06-18 07:30:42 +00:00
Mark Lacey
f56ca1ed68 Revert "SIL: Add a project_box insn to project the address of the value from a box."
This reverts commit r29475 because it conflicts with reverting r29474,
and it looks like that commit is breaking the build of the SpriteKit
overlay.

Swift SVN r29481
2015-06-18 06:27:52 +00:00
Joe Groff
15c29e5d1f SIL: Add a project_box insn to project the address of the value from a box.
Still no implementation yet; we'll need to renovate how boxes work a bit to make them projectable (and renovate SILGen to generate typed boxes for the insn to be useful).

Swift SVN r29475
2015-06-18 04:07:23 +00:00
Joe Groff
96638e3028 SILGen: Properly type reabstracted overrides in calls and witness thunks.
Fixes most of rdar://problem/20874966, though curry thunks are still broken (filed as rdar://problem/21167978).

Swift SVN r29160
2015-05-30 00:41:55 +00:00
Joe Groff
af66dfb73d SIL verifier: Check that a class_method's type matches its override abstraction level.
Factor the code to compute an override's vtable type out of SILGen's emitVTableMethod into a method on TypeLowering, and use it to verify the type of class_method instructions. This catches rdar://problem/20874966 at SILGen time instead of letting the devirtualizer barf on it.

Swift SVN r29158
2015-05-30 00:41:49 +00:00
Slava Pestov
42d7c7251c SILGen: better diagnostic for code after break and throw
Swift SVN r28689
2015-05-18 00:26:19 +00:00
Michael Gottesman
96634b4be6 Add a SILBuilder::emitDestroyAddr API that returns a pointer union and use it to implement SILBuilder::emitDestroyAddrAndFold.
Now on SILBuilder, destroy_addr has an API that matches the APIs for
strong_release and release_value.

Done at Chris's request.

Swift SVN r28170
2015-05-05 17:23:11 +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