Commit Graph

268 Commits

Author SHA1 Message Date
Slava Pestov
41971fec99 SILGen: Introduce MaterializedLValue abstraction
This is used when materializing an LValue to share state between
the read and write phases of the access, replacing the 'temporary'
and 'extraInfo' parameters that were previously being passed around.

It adds two new fields, origSelfType and genericSig, which will be
used in an upcoming patch to actually apply the callback with the
current generic signature.

This will finally allow us to make use of materializeForSet
implementations in protocol extensions, which is a prerequisite
for enabling resilient default implementations of property and
subscript requirements.
2016-03-09 16:33:22 -08:00
Slava Pestov
08196c9f9a SILGen: Better type safety in SILGenApply.cpp, NFC 2016-03-07 17:05:06 -08:00
Slava Pestov
924e4c4e13 SILGen: Clean up lvalue re-abstraction a bit
When we emit calls to getters and setters with emitApply(), the call
emission code ends up re-abstracting the result of a getter or the
parameter to a setter.

As a result, getOrigFormalType() was incorrect for logical path
components. This was worked around by only adding an OrigToSubst
path component to an lvalue if the last path component was physical.

This caused a problem in the following case:

1) There was an abstraction difference between the storage of the
   protocol requirement and the storage of the protocol witness

2) There was an abstraction difference between the storage of the
   protocol witness, and the fully-substituted type of the witness

An example is when the witness is in a protocol extension, and uses
'Self' or some other associated type which is concrete and loadable
in the conformance.

Fix this properly by splitting up getStorageTypeData() into two
functions, one used when adding physical path components and another
one used for logical.

As a result, we can now give the correct abstraction pattern to
logical path components.
2016-03-07 17:05:06 -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
Daniel Duan
efe230774b [AST] rename some isXXX methods to getAsXXX
There's a group of methods in `DeclContext` with names that start with *is*,
such as `isClassOrClassExtensionContext()`. These names suggests a boolean
return value, while the methods actually return a type declaration. This
patch replaces the *is* prefix with *getAs* to better reflect their interface.
2016-02-11 16:23:40 -08:00
Erik Eckstein
506ab9809f SIL: remove getTyp() from SILValue 2016-01-25 15:00:49 -08:00
Slava Pestov
56b03642ac SILGen: Targeted fix for MaterializeForSet use
If we're accessing a field of a struct, ignore materializeForSet;
it will only have been synthesized if the struct conforms to a
protocol, and we don't want the presence of a conformance to
affect generated code.

A more principled fix would change the SILGen logic to use a
materializeForSet if it would have been synthesized anyway,
asserting that it was synthesized in that case. I'll clean this
up in the 'master' branch once these fixes settle.
2016-01-20 01:50:17 -08:00
Slava Pestov
df38bd1764 SILGen: More interface type abstraction pattern goodness, NFC 2016-01-18 23:17:17 -08:00
Slava Pestov
249242b08d SILGen: Always open-code materializeForSet
This improves MaterializeForSetEmitter to support emission
of static materializeForSet thunks, as well as witnesses.

This is now done by passing in a nullptr as the conformance
and requirement parameters, and adding some conditional code.

Along the way, I fixed a few limitations of the old code,
namely weak/unowned and static stored properties weren't
completely plumbed through. There was also a memory leak in
addressed materializeForSet, the valueBuffer was never freed.

Finally, remove the materializeForSet synthesis in Sema since
it is no longer needed, which fixes at least one known crash
case.
2016-01-11 19:53:16 -08:00
Slava Pestov
b70e4d2aad SILGen: Split off SILGenMaterializeForSet.cpp from SILGenLValue.cpp, NFC
In order to fix some other issues that came up with materializeForSet
and resilience, I had to bite the bullet and finish off John's code
for open-coding materializeForSet emission in SILGen. This patch
makes the subsequent changes easier to review.
2016-01-10 17:06:19 -08:00
Slava Pestov
6af7f95a5a We don't need to plumb a resilience expansion through mangling, NFC
I'm going to be adding deployment target info ResilienceExpansion
soon so removing unnecessary usages helps reduce the amount of
work there.
2016-01-07 08:15:26 -08:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
practicalswift
021a186c23 Fix typos. 2015-12-28 18:30:15 +01:00
Nadav Rotem
07d4558c1c [Mangler] Change the Swift mangler into a symbol builder.
This commit changes the Swift mangler from a utility that writes tokens into a
stream into a name-builder that has two phases: "building a name", and "ready".
This clear separation is needed for the implementation of the compression layer.

Users of the mangler can continue to build the name using the mangleXXX methods,
but to access the results the users of the mangler need to call the finalize()
method. This method can write the result into a stream, like before, or return
an std::string.
2015-12-25 21:40:25 -08:00
Nadav Rotem
6fa6ca563e [Mangler] Rename some of the mangler methods. NFC. 2015-12-24 14:35:33 -08:00
Nadav Rotem
b5e4197d33 [Mangler] Fix all of the places where users of the Mangler access the underlying buffer.
This commit fixes all of the places where users of the Mangler write to the stream that's used by the Mangler. The plan is to make the Mangler buffered, and this means that users can't assume that the mangler immediately writes the mangled tokens to the output stream.
2015-12-22 22:47:35 -08:00
Slava Pestov
8e0e2b4ea2 SIL: Nuke TypeConverter::getEffectiveGenericParamsForContext(), NFC 2015-12-20 16:57:23 -08:00
practicalswift
8ab8847684 Fix typos. 2015-12-16 22:09:32 +01: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
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
Slava Pestov
1b55becf76 SILGen: Fix issues with one-element tuples in thunks
Take apart exploded one-element tuples and be more careful with
passing around tuple abstraction patterns.

Also, now we can  remove the inputSubstType parameter from
emitOrigToSubstValue() and emitSubstToOrigValue(), making the
signatures of these functions nice and simple once again.

Fixes <rdar://problem/19506347> and <rdar://problem/22502450>.
2015-11-06 13:51:15 -08:00
Slava Pestov
533f42dd2f Closures and local functions only capture generic parameters if necessary
The CaptureInfo computed by Sema now records if the body of the
function uses any generic parameters from the outer context.
SIL type lowering only adds a generic signature if this is the
case, instead of unconditionally.

This might yield a marginal performance improvement in some cases,
but more interestingly will allow @convention(c) conversions from
generic context.

Swift SVN r32161
2015-09-22 21:08:28 +00:00
Slava Pestov
0af82e6345 SILGen: Move optional and existential conversions to SILGenConvert.cpp, NFC
This is a better place for code shared between expression emission
and thunks.

Swift SVN r31544
2015-08-27 21:53:49 +00:00
Slava Pestov
e1f0f02480 SILGen: Three-parameter re-abstraction thunks
Right now, re-abstraction thunks are set up to convert values
as follows, where L is type lowering:

- OrigToSubst: L(origType, substType) -> L(substType)
- SubstToOrig: L(substType) -> L(origType, substType)

This assumes there's no AST-level type conversion, because
when we visit a type in contravariant position, we flip the
direction of the transform but we're still converting *to*
substType -- which will now equal to the type of the input,
not the type of the expected result!

This caused several problems:

- VTable thunk generation had a bunch of special logic to
  compute a substOverrideType, and wrap the thunk result
  in an optional, duplicating work done in the transform

- Witness thunk generation similarly had to handle the case
  of upcasting to a base class to call the witness, and
  casting the result of materializeForSet back to the right
  type for properties defined on the base.

  Now the materializeForSet cast sequence is a bit longer,
  we unpack the returned tuple and do a convert_function
  on the function, then pack it again -- before we would
  unchecked_ref_cast the tuple, which is technically
  incorrect since the tuple is not a ref, but IRGen didn't
  seem to care...

To handle the conversions correctly, we add a third AST type
parameter to a transform, named inputType. Now, transforms
perform these conversions:

- OrigToSubst: L(origType, inputType) -> L(substType)
- SubstToOrig: L(inputType) -> L(origType, substType)

When we flip the direction of the transform while visiting
types in contravariant position, we also swap substType with
inputType.

Note that this is similar to how bridging thunks work, for
the same reason -- bridging thunks convert between AST types.

This is mostly just a nice cleanup that fixes some obscure
corner cases for now, but this functionality will be used
in a subsequent patch.

Swift SVN r31486
2015-08-26 09:15:29 +00:00
Slava Pestov
e416bfbc4e SILGen: Refactor code for existentials
We need to be able to introduce and eliminate existentials inside
reabstraction thunks, so make this logic independent of RValue
and Expr emission.

NFC for now.

Swift SVN r31375
2015-08-21 02:26:57 +00:00
Slava Pestov
9b74a4b0d6 SILGen: Fix memory leak when sub-expression of ErasureExpr throws
If we didn't initialize the existential, we have to emit a cleanup
because we may have allocated a buffer on the heap to store the value.

Factor out the TakeExistentialCleanup that appears in a few places,
rename it to DeinitExistentialCleanup and add support for deallocating
boxed existentials.

Then, use a special Initialization subclass to keep track of the
state of the memory in emit{AddressOnly,Boxed}Erasure().

Swift SVN r31259
2015-08-16 16:45:44 +00:00
John McCall
0c39ec02fa Don't use materializeForSet when accessing properties or
subscripts defined in protocol extensions.

The right condition for this is really direct uses of the
default implementation; right now, that just means all
direct uses of something from a protocol extension.

Fixes rdar://22109071.

Swift SVN r31228
2015-08-13 21:49:14 +00:00
John McCall
7e81f7e129 Fix a number of bugs with the new materializeForSet SILGen,
including one which triggered only for non-subscripts and
a number which triggered with different cases of classes.

Swift SVN r31198
2015-08-13 01:52:17 +00:00
John McCall
e56e4892a3 When performing a simple 'set' operation on an l-value,
peephole reabstraction components by applying them to
the r-value instead of materializing to a temporary
and then assigning to that.

Removes a completely unnecessary use of the getter
from simple assignments to properties or subscripts
at a different abstraction level.

Swift SVN r31197
2015-08-13 01:52:14 +00:00
John McCall
b667b1f26e Turn on the materializeForSet-in-protocol-extensions fix from
r31072 (<rdar://21836671>).

Passes the primary test suite; I'm still working on giving it
proper tests, but since time is of the essence, we can
streamline this process by doing a few things in parallel.

The test suite change here is interesting: we're no longer
emitting materializeForSet entrypoints for storage in
protocol extensions, because they were only getting emitted
lazily and we're no longer using them at all.  I think
that's fine because, well, we're no longer using them at
all.

Swift SVN r31192
2015-08-12 21:47:59 +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
John McCall
807f7f5434 Reimplement materializeForSet emission in SILGen instead of
the type-checker.  The strategy for now is to just use this
for protocol witness thunk emission, where it is required
when generating a materializeForSet for storage that is
either implemented in a protocol extension or requires
reabstraction to the requirement's pattern.

Eventually, this should be generalized to the point that
we can use it for all materializeForSet emission, which
I don't think will take much.  However, that's not really
the sort of instability we want to embrace for the current
release.

WIP towards rdar://21836671; currently disabled, so NFC.

Swift SVN r31072
2015-08-07 09:22:27 +00:00
Slava Pestov
48fe3e1c9b SILGen: Fix static computed properties in protocol extensions
We need to keep the AST formal type of the base around when building up
lvalues.

When the getter or setter involves an accessor call, we would use the
lowered type of the self argument to form the call. However, it might be
at the wrong level of abstraction, causing a @thin -vs- @thick metatype
mismatch. Using the formal type instead allows SILGenApply logic to emit
a thin to thick metatype conversion if necessary.

Fixes <rdar://problem/21358641>.

Swift SVN r30913
2015-08-01 07:21:25 +00:00
Chris Lattner
0001dc27bb remove support for the experiemental "character literals" feature.
Swift SVN r30509
2015-07-22 22:35:19 +00:00
Joe Groff
ea197736db SILGen: Reabstract result of 'get' when materializing lvalue to temporary.
This is a bit unfortunate since the natural result of 'get' was probably already at the right abstraction level and already got abstracted in the wrong direction, but we don't have the infrastructure to peephole away the redundancy yet. Fixes rdar://problem/20341012.

Swift SVN r30483
2015-07-22 01:03:10 +00:00
Nadav Rotem
aaba211ad0 [SILGen] fix rdar://21883752. Make sure that dealloc_stack instructions are inserted in the right place.
Before the fix we were inserting the dealloc_stack in the wrong basic block. Adding a scope to
performWriteback ensures that the different writeback methods don't leak cleanups into the their
caller cleanup scope.

Swift SVN r30428
2015-07-21 01:06:43 +00:00
Andrew Trick
bd1c3ba0fc Revert "ManagedValue forwardInto and assignInto should not always "take" their value."
This reverts commit r30272.

There's a way to fix Builtin.reinterpretCast that preserves SILGen
RValue invariants better according to JohnM. So although these changes
are valid, there will be no way for me to test them.

After reverting this, I will roll back in the change to
emitImplicitValueConstructor because I think the old code was
violating SILGen invariants.

Swift SVN r30306
2015-07-17 06:52:04 +00:00
Andrew Trick
fda0971390 ManagedValue forwardInto and assignInto should not always "take" their value.
This is required in order to fix Builtin.reinterpretCast for
address-only types. That upcoming fix will include a test case that
exposes this SILGen path.

Swift SVN r30272
2015-07-16 21:24:04 +00:00
John McCall
29b49480f1 Emit writebacks during error-handling cleanup.
This requires some really ugly copies at -O0 in order to
avoid changing whether enclosing cleanups are active during
the emission of those cleanups.  (There may also be complex
situations where values are forwarded to the writeback but
the writeback cleanup can't take advantage of that --- not
sure yet.)  These should generally be trivial to clean up,
but I'm still thinking about how to avoid emitting them in
the first place.

Swift SVN r30180
2015-07-14 00:32:32 +00:00
John McCall
ed0681004c Remove the almost-pointless Materialize type from SILGen,
and stop forcing optionals to memory in a bunch of places
where the callee is perfectly capable of handling a
non-address value.

Swift SVN r30107
2015-07-11 02:58:49 +00:00
Joe Groff
d84993108b SILGen: Emit Clang-imported witness tables by need too.
The other part of rdar://problem/21444126. This is a little trickier since SIL doesn't track uses of witness tables in a principled way. Track uses in SILGen by putting a "SILGenBuilder" wrapper in front of SILBuilder, which marks conformances from apply, existential erasure, and metatype lookup instructions as used, so we can avoid emitting shared Clang importer witnesses when they aren't needed.

Swift SVN r29544
2015-06-22 03:08:41 +00:00
Joe Groff
d7b2bbaadb Remove stale FIXME.
Swift SVN r29068
2015-05-27 17:27:10 +00:00
Joe Groff
ec3dfc230c SILGen: Mark the stack slot for '_' assignments uninitialized.
It will be assigned into, so we need DI to lower the assignment to an initialization for us. Fixes rdar://problem/21090194.

Swift SVN r29067
2015-05-27 16:59:19 +00:00
Chris Lattner
5e7a45ff70 revert r28318, it is causing a problem on perftests. I'll investigate after lunch.
Swift SVN r28321
2015-05-08 18:02:24 +00:00
Chris Lattner
f379b1e15b Revise SILGen of foreach loops to only drop the optional generator result value
in memory when it is address-only.  This leads to better -O0 performance and 
easier to read silgen output.  This is ongoing progress towards rdar://20642198.


Swift SVN r28318
2015-05-08 17:46:20 +00:00
Michael Gottesman
8361ba44a9 Revert "Revert "[+0 self] Teach SILGen how to avoid emitting extra rr pairs when emitting RValues with Nominal Types and Tuples.""
This reapplies commit r27632 with additional fixes, tests.

I turned off the guaranteed struct optimization since we really don't have the
infrastructure to do it right and more importantly I don't have the time to do
so (and was not asked to do so).

We still have the class optimization though!

This means that there is one retain in ClassIntTreeMethod.find.

class ClassIntTreeNode {
  let value : Int
  let left, right : ClassIntTreeNode

  init() {}

  func find(v : Int) -> ClassIntTreeNode {
    if v == value { return self }
    if v < value { return left.find(v) }
    return right.find(v)
  }
}

Swift SVN r28264
2015-05-07 15:47:34 +00:00
Chris Lattner
b6ad8d5efc Teach emitBindOptional() to disable the cleanup for the optional it is testing on the
nil path.  This avoids emitting a "release" operation on an optional temporary that is
always guaranteed to be dynamically nil.  This cleans up the generated code for x?.foo().



Swift SVN r28103
2015-05-04 00:13:18 +00:00
Michael Gottesman
a3aa89d4c4 Remove Callback from SILBuilder and instead rename
emit{StrongRelease,ReleaseValue} => emit{StrongRelease,ReleaseValue}AndFold.
Then introduce a new method emit{StrongRelease,ReleaseValue} that returns a
PointerUnion containing the increment to be deleted if it exists. This obviates
the need for the callback.

Swift SVN r27804
2015-04-27 07:29:13 +00:00
Chris Lattner
2d227db594 remove the dead CallerDefaultInitialize case from visitTupleShuffleExpr.
Swift SVN r27801
2015-04-27 04:57:31 +00:00
Michael Gottesman
9c35c5eafd Revert "[+0 self] Teach SILGen how to avoid emitting extra rr pairs when emitting RValues with Nominal Types and Tuples."
This reverts commit r27632. I broke a test. I am going to look at it later.

Swift SVN r27634
2015-04-23 10:42:46 +00:00